chiark / gitweb /
tree-wide: remove Emacs lines from all files
[elogind.git] / src / basic / process-util.c
1 /***
2   This file is part of systemd.
3
4   Copyright 2010 Lennart Poettering
5
6   systemd is free software; you can redistribute it and/or modify it
7   under the terms of the GNU Lesser General Public License as published by
8   the Free Software Foundation; either version 2.1 of the License, or
9   (at your option) any later version.
10
11   systemd is distributed in the hope that it will be useful, but
12   WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14   Lesser General Public License for more details.
15
16   You should have received a copy of the GNU Lesser General Public License
17   along with systemd; If not, see <http://www.gnu.org/licenses/>.
18 ***/
19
20 #include <assert.h>
21 #include <ctype.h>
22 #include <errno.h>
23 #include <sched.h>
24 #include <signal.h>
25 #include <stdbool.h>
26 #include <stdio.h>
27 #include <string.h>
28 #include <sys/personality.h>
29 #include <sys/prctl.h>
30 #include <sys/types.h>
31 #include <sys/wait.h>
32 #include <unistd.h>
33
34 #include "alloc-util.h"
35 #include "escape.h"
36 #include "fd-util.h"
37 #include "fileio.h"
38 #include "fs-util.h"
39 //#include "ioprio.h"
40 #include "log.h"
41 #include "process-util.h"
42 #include "signal-util.h"
43 #include "string-table.h"
44 #include "string-util.h"
45 #include "user-util.h"
46 #include "util.h"
47
48 int get_process_state(pid_t pid) {
49         const char *p;
50         char state;
51         int r;
52         _cleanup_free_ char *line = NULL;
53
54         assert(pid >= 0);
55
56         p = procfs_file_alloca(pid, "stat");
57
58         r = read_one_line_file(p, &line);
59         if (r == -ENOENT)
60                 return -ESRCH;
61         if (r < 0)
62                 return r;
63
64         p = strrchr(line, ')');
65         if (!p)
66                 return -EIO;
67
68         p++;
69
70         if (sscanf(p, " %c", &state) != 1)
71                 return -EIO;
72
73         return (unsigned char) state;
74 }
75
76 int get_process_comm(pid_t pid, char **name) {
77         const char *p;
78         int r;
79
80         assert(name);
81         assert(pid >= 0);
82
83         p = procfs_file_alloca(pid, "comm");
84
85         r = read_one_line_file(p, name);
86         if (r == -ENOENT)
87                 return -ESRCH;
88
89         return r;
90 }
91
92 int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char **line) {
93         _cleanup_fclose_ FILE *f = NULL;
94         char *r = NULL, *k;
95         const char *p;
96         int c;
97
98         assert(line);
99         assert(pid >= 0);
100
101         p = procfs_file_alloca(pid, "cmdline");
102
103         f = fopen(p, "re");
104         if (!f) {
105                 if (errno == ENOENT)
106                         return -ESRCH;
107                 return -errno;
108         }
109
110         if (max_length == 0) {
111                 size_t len = 0, allocated = 0;
112
113                 while ((c = getc(f)) != EOF) {
114
115                         if (!GREEDY_REALLOC(r, allocated, len+2)) {
116                                 free(r);
117                                 return -ENOMEM;
118                         }
119
120                         r[len++] = isprint(c) ? c : ' ';
121                 }
122
123                 if (len > 0)
124                         r[len-1] = 0;
125
126         } else {
127                 bool space = false;
128                 size_t left;
129
130                 r = new(char, max_length);
131                 if (!r)
132                         return -ENOMEM;
133
134                 k = r;
135                 left = max_length;
136                 while ((c = getc(f)) != EOF) {
137
138                         if (isprint(c)) {
139                                 if (space) {
140                                         if (left <= 4)
141                                                 break;
142
143                                         *(k++) = ' ';
144                                         left--;
145                                         space = false;
146                                 }
147
148                                 if (left <= 4)
149                                         break;
150
151                                 *(k++) = (char) c;
152                                 left--;
153                         }  else
154                                 space = true;
155                 }
156
157                 if (left <= 4) {
158                         size_t n = MIN(left-1, 3U);
159                         memcpy(k, "...", n);
160                         k[n] = 0;
161                 } else
162                         *k = 0;
163         }
164
165         /* Kernel threads have no argv[] */
166         if (isempty(r)) {
167                 _cleanup_free_ char *t = NULL;
168                 int h;
169
170                 free(r);
171
172                 if (!comm_fallback)
173                         return -ENOENT;
174
175                 h = get_process_comm(pid, &t);
176                 if (h < 0)
177                         return h;
178
179                 r = strjoin("[", t, "]", NULL);
180                 if (!r)
181                         return -ENOMEM;
182         }
183
184         *line = r;
185         return 0;
186 }
187
188 #if 0 /// UNNEEDED by elogind
189 void rename_process(const char name[8]) {
190         assert(name);
191
192         /* This is a like a poor man's setproctitle(). It changes the
193          * comm field, argv[0], and also the glibc's internally used
194          * name of the process. For the first one a limit of 16 chars
195          * applies, to the second one usually one of 10 (i.e. length
196          * of "/sbin/init"), to the third one one of 7 (i.e. length of
197          * "systemd"). If you pass a longer string it will be
198          * truncated */
199
200         prctl(PR_SET_NAME, name);
201
202         if (program_invocation_name)
203                 strncpy(program_invocation_name, name, strlen(program_invocation_name));
204
205         if (saved_argc > 0) {
206                 int i;
207
208                 if (saved_argv[0])
209                         strncpy(saved_argv[0], name, strlen(saved_argv[0]));
210
211                 for (i = 1; i < saved_argc; i++) {
212                         if (!saved_argv[i])
213                                 break;
214
215                         memzero(saved_argv[i], strlen(saved_argv[i]));
216                 }
217         }
218 }
219 #endif // 0
220
221 int is_kernel_thread(pid_t pid) {
222         const char *p;
223         size_t count;
224         char c;
225         bool eof;
226         FILE *f;
227
228         if (pid == 0 || pid == 1) /* pid 1, and we ourselves certainly aren't a kernel thread */
229                 return 0;
230
231         assert(pid > 1);
232
233         p = procfs_file_alloca(pid, "cmdline");
234         f = fopen(p, "re");
235         if (!f) {
236                 if (errno == ENOENT)
237                         return -ESRCH;
238                 return -errno;
239         }
240
241         count = fread(&c, 1, 1, f);
242         eof = feof(f);
243         fclose(f);
244
245         /* Kernel threads have an empty cmdline */
246
247         if (count <= 0)
248                 return eof ? 1 : -errno;
249
250         return 0;
251 }
252
253 #if 0 /// UNNEEDED by elogind
254 int get_process_capeff(pid_t pid, char **capeff) {
255         const char *p;
256         int r;
257
258         assert(capeff);
259         assert(pid >= 0);
260
261         p = procfs_file_alloca(pid, "status");
262
263         r = get_proc_field(p, "CapEff", WHITESPACE, capeff);
264         if (r == -ENOENT)
265                 return -ESRCH;
266
267         return r;
268 }
269 #endif // 0
270
271 static int get_process_link_contents(const char *proc_file, char **name) {
272         int r;
273
274         assert(proc_file);
275         assert(name);
276
277         r = readlink_malloc(proc_file, name);
278         if (r == -ENOENT)
279                 return -ESRCH;
280         if (r < 0)
281                 return r;
282
283         return 0;
284 }
285
286 int get_process_exe(pid_t pid, char **name) {
287         const char *p;
288         char *d;
289         int r;
290
291         assert(pid >= 0);
292
293         p = procfs_file_alloca(pid, "exe");
294         r = get_process_link_contents(p, name);
295         if (r < 0)
296                 return r;
297
298         d = endswith(*name, " (deleted)");
299         if (d)
300                 *d = '\0';
301
302         return 0;
303 }
304
305 #if 0 /// UNNEEDED by elogind
306 static int get_process_id(pid_t pid, const char *field, uid_t *uid) {
307         _cleanup_fclose_ FILE *f = NULL;
308         char line[LINE_MAX];
309         const char *p;
310
311         assert(field);
312         assert(uid);
313
314         if (pid == 0)
315                 return getuid();
316
317         p = procfs_file_alloca(pid, "status");
318         f = fopen(p, "re");
319         if (!f) {
320                 if (errno == ENOENT)
321                         return -ESRCH;
322                 return -errno;
323         }
324
325         FOREACH_LINE(line, f, return -errno) {
326                 char *l;
327
328                 l = strstrip(line);
329
330                 if (startswith(l, field)) {
331                         l += strlen(field);
332                         l += strspn(l, WHITESPACE);
333
334                         l[strcspn(l, WHITESPACE)] = 0;
335
336                         return parse_uid(l, uid);
337                 }
338         }
339
340         return -EIO;
341 }
342
343 int get_process_uid(pid_t pid, uid_t *uid) {
344         return get_process_id(pid, "Uid:", uid);
345 }
346
347 int get_process_gid(pid_t pid, gid_t *gid) {
348         assert_cc(sizeof(uid_t) == sizeof(gid_t));
349         return get_process_id(pid, "Gid:", gid);
350 }
351
352 int get_process_cwd(pid_t pid, char **cwd) {
353         const char *p;
354
355         assert(pid >= 0);
356
357         p = procfs_file_alloca(pid, "cwd");
358
359         return get_process_link_contents(p, cwd);
360 }
361
362 int get_process_root(pid_t pid, char **root) {
363         const char *p;
364
365         assert(pid >= 0);
366
367         p = procfs_file_alloca(pid, "root");
368
369         return get_process_link_contents(p, root);
370 }
371
372 int get_process_environ(pid_t pid, char **env) {
373         _cleanup_fclose_ FILE *f = NULL;
374         _cleanup_free_ char *outcome = NULL;
375         int c;
376         const char *p;
377         size_t allocated = 0, sz = 0;
378
379         assert(pid >= 0);
380         assert(env);
381
382         p = procfs_file_alloca(pid, "environ");
383
384         f = fopen(p, "re");
385         if (!f) {
386                 if (errno == ENOENT)
387                         return -ESRCH;
388                 return -errno;
389         }
390
391         while ((c = fgetc(f)) != EOF) {
392                 if (!GREEDY_REALLOC(outcome, allocated, sz + 5))
393                         return -ENOMEM;
394
395                 if (c == '\0')
396                         outcome[sz++] = '\n';
397                 else
398                         sz += cescape_char(c, outcome + sz);
399         }
400
401         if (!outcome) {
402                 outcome = strdup("");
403                 if (!outcome)
404                         return -ENOMEM;
405         } else
406         outcome[sz] = '\0';
407
408         *env = outcome;
409         outcome = NULL;
410
411         return 0;
412 }
413
414 int get_process_ppid(pid_t pid, pid_t *_ppid) {
415         int r;
416         _cleanup_free_ char *line = NULL;
417         long unsigned ppid;
418         const char *p;
419
420         assert(pid >= 0);
421         assert(_ppid);
422
423         if (pid == 0) {
424                 *_ppid = getppid();
425                 return 0;
426         }
427
428         p = procfs_file_alloca(pid, "stat");
429         r = read_one_line_file(p, &line);
430         if (r == -ENOENT)
431                 return -ESRCH;
432         if (r < 0)
433                 return r;
434
435         /* Let's skip the pid and comm fields. The latter is enclosed
436          * in () but does not escape any () in its value, so let's
437          * skip over it manually */
438
439         p = strrchr(line, ')');
440         if (!p)
441                 return -EIO;
442
443         p++;
444
445         if (sscanf(p, " "
446                    "%*c "  /* state */
447                    "%lu ", /* ppid */
448                    &ppid) != 1)
449                 return -EIO;
450
451         if ((long unsigned) (pid_t) ppid != ppid)
452                 return -ERANGE;
453
454         *_ppid = (pid_t) ppid;
455
456         return 0;
457 }
458 #endif // 0
459
460 int wait_for_terminate(pid_t pid, siginfo_t *status) {
461         siginfo_t dummy;
462
463         assert(pid >= 1);
464
465         if (!status)
466                 status = &dummy;
467
468         for (;;) {
469                 zero(*status);
470
471                 if (waitid(P_PID, pid, status, WEXITED) < 0) {
472
473                         if (errno == EINTR)
474                                 continue;
475
476                         return -errno;
477                 }
478
479                 return 0;
480         }
481 }
482
483 /*
484  * Return values:
485  * < 0 : wait_for_terminate() failed to get the state of the
486  *       process, the process was terminated by a signal, or
487  *       failed for an unknown reason.
488  * >=0 : The process terminated normally, and its exit code is
489  *       returned.
490  *
491  * That is, success is indicated by a return value of zero, and an
492  * error is indicated by a non-zero value.
493  *
494  * A warning is emitted if the process terminates abnormally,
495  * and also if it returns non-zero unless check_exit_code is true.
496  */
497 int wait_for_terminate_and_warn(const char *name, pid_t pid, bool check_exit_code) {
498         int r;
499         siginfo_t status;
500
501         assert(name);
502         assert(pid > 1);
503
504         r = wait_for_terminate(pid, &status);
505         if (r < 0)
506                 return log_warning_errno(r, "Failed to wait for %s: %m", name);
507
508         if (status.si_code == CLD_EXITED) {
509                 if (status.si_status != 0)
510                         log_full(check_exit_code ? LOG_WARNING : LOG_DEBUG,
511                                  "%s failed with error code %i.", name, status.si_status);
512                 else
513                         log_debug("%s succeeded.", name);
514
515                 return status.si_status;
516         } else if (status.si_code == CLD_KILLED ||
517                    status.si_code == CLD_DUMPED) {
518
519                 log_warning("%s terminated by signal %s.", name, signal_to_string(status.si_status));
520                 return -EPROTO;
521         }
522
523         log_warning("%s failed due to unknown reason.", name);
524         return -EPROTO;
525 }
526
527 void sigkill_wait(pid_t *pid) {
528         if (!pid)
529                 return;
530         if (*pid <= 1)
531                 return;
532
533         if (kill(*pid, SIGKILL) > 0)
534                 (void) wait_for_terminate(*pid, NULL);
535 }
536
537 #if 0 /// UNNEEDED by elogind
538 int kill_and_sigcont(pid_t pid, int sig) {
539         int r;
540
541         r = kill(pid, sig) < 0 ? -errno : 0;
542
543         if (r >= 0)
544                 kill(pid, SIGCONT);
545
546         return r;
547 }
548 #endif // 0
549
550 int getenv_for_pid(pid_t pid, const char *field, char **_value) {
551         _cleanup_fclose_ FILE *f = NULL;
552         char *value = NULL;
553         int r;
554         bool done = false;
555         size_t l;
556         const char *path;
557
558         assert(pid >= 0);
559         assert(field);
560         assert(_value);
561
562         path = procfs_file_alloca(pid, "environ");
563
564         f = fopen(path, "re");
565         if (!f) {
566                 if (errno == ENOENT)
567                         return -ESRCH;
568                 return -errno;
569         }
570
571         l = strlen(field);
572         r = 0;
573
574         do {
575                 char line[LINE_MAX];
576                 unsigned i;
577
578                 for (i = 0; i < sizeof(line)-1; i++) {
579                         int c;
580
581                         c = getc(f);
582                         if (_unlikely_(c == EOF)) {
583                                 done = true;
584                                 break;
585                         } else if (c == 0)
586                                 break;
587
588                         line[i] = c;
589                 }
590                 line[i] = 0;
591
592                 if (memcmp(line, field, l) == 0 && line[l] == '=') {
593                         value = strdup(line + l + 1);
594                         if (!value)
595                                 return -ENOMEM;
596
597                         r = 1;
598                         break;
599                 }
600
601         } while (!done);
602
603         *_value = value;
604         return r;
605 }
606
607 bool pid_is_unwaited(pid_t pid) {
608         /* Checks whether a PID is still valid at all, including a zombie */
609
610         if (pid < 0)
611                 return false;
612
613         if (pid <= 1) /* If we or PID 1 would be dead and have been waited for, this code would not be running */
614                 return true;
615
616         if (kill(pid, 0) >= 0)
617                 return true;
618
619         return errno != ESRCH;
620 }
621
622 bool pid_is_alive(pid_t pid) {
623         int r;
624
625         /* Checks whether a PID is still valid and not a zombie */
626
627         if (pid < 0)
628                 return false;
629
630         if (pid <= 1) /* If we or PID 1 would be a zombie, this code would not be running */
631                 return true;
632
633         r = get_process_state(pid);
634         if (r == -ESRCH || r == 'Z')
635                 return false;
636
637         return true;
638 }
639
640 bool is_main_thread(void) {
641         static thread_local int cached = 0;
642
643         if (_unlikely_(cached == 0))
644                 cached = getpid() == gettid() ? 1 : -1;
645
646         return cached > 0;
647 }
648
649 #if 0 /// UNNEEDED by elogind
650 noreturn void freeze(void) {
651
652         /* Make sure nobody waits for us on a socket anymore */
653         close_all_fds(NULL, 0);
654
655         sync();
656
657         for (;;)
658                 pause();
659 }
660
661 bool oom_score_adjust_is_valid(int oa) {
662         return oa >= OOM_SCORE_ADJ_MIN && oa <= OOM_SCORE_ADJ_MAX;
663 }
664
665 unsigned long personality_from_string(const char *p) {
666
667         /* Parse a personality specifier. We introduce our own
668          * identifiers that indicate specific ABIs, rather than just
669          * hints regarding the register size, since we want to keep
670          * things open for multiple locally supported ABIs for the
671          * same register size. We try to reuse the ABI identifiers
672          * used by libseccomp. */
673
674 #if defined(__x86_64__)
675
676         if (streq(p, "x86"))
677                 return PER_LINUX32;
678
679         if (streq(p, "x86-64"))
680                 return PER_LINUX;
681
682 #elif defined(__i386__)
683
684         if (streq(p, "x86"))
685                 return PER_LINUX;
686
687 #elif defined(__s390x__)
688
689         if (streq(p, "s390"))
690                 return PER_LINUX32;
691
692         if (streq(p, "s390x"))
693                 return PER_LINUX;
694
695 #elif defined(__s390__)
696
697         if (streq(p, "s390"))
698                 return PER_LINUX;
699 #endif
700
701         return PERSONALITY_INVALID;
702 }
703
704 const char* personality_to_string(unsigned long p) {
705
706 #if defined(__x86_64__)
707
708         if (p == PER_LINUX32)
709                 return "x86";
710
711         if (p == PER_LINUX)
712                 return "x86-64";
713
714 #elif defined(__i386__)
715
716         if (p == PER_LINUX)
717                 return "x86";
718
719 #elif defined(__s390x__)
720
721         if (p == PER_LINUX)
722                 return "s390x";
723
724         if (p == PER_LINUX32)
725                 return "s390";
726
727 #elif defined(__s390__)
728
729         if (p == PER_LINUX)
730                 return "s390";
731
732 #endif
733
734         return NULL;
735 }
736
737 static const char *const ioprio_class_table[] = {
738         [IOPRIO_CLASS_NONE] = "none",
739         [IOPRIO_CLASS_RT] = "realtime",
740         [IOPRIO_CLASS_BE] = "best-effort",
741         [IOPRIO_CLASS_IDLE] = "idle"
742 };
743
744 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ioprio_class, int, INT_MAX);
745
746 static const char *const sigchld_code_table[] = {
747         [CLD_EXITED] = "exited",
748         [CLD_KILLED] = "killed",
749         [CLD_DUMPED] = "dumped",
750         [CLD_TRAPPED] = "trapped",
751         [CLD_STOPPED] = "stopped",
752         [CLD_CONTINUED] = "continued",
753 };
754
755 DEFINE_STRING_TABLE_LOOKUP(sigchld_code, int);
756
757 static const char* const sched_policy_table[] = {
758         [SCHED_OTHER] = "other",
759         [SCHED_BATCH] = "batch",
760         [SCHED_IDLE] = "idle",
761         [SCHED_FIFO] = "fifo",
762         [SCHED_RR] = "rr"
763 };
764
765 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(sched_policy, int, INT_MAX);
766 #endif // 0