chiark / gitweb /
Prep v228: Add remaining updates from upstream (2/3)
[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 /// UNNEEDED by elogind
189 #if 0
190 void rename_process(const char name[8]) {
191         assert(name);
192
193         /* This is a like a poor man's setproctitle(). It changes the
194          * comm field, argv[0], and also the glibc's internally used
195          * name of the process. For the first one a limit of 16 chars
196          * applies, to the second one usually one of 10 (i.e. length
197          * of "/sbin/init"), to the third one one of 7 (i.e. length of
198          * "systemd"). If you pass a longer string it will be
199          * truncated */
200
201         prctl(PR_SET_NAME, name);
202
203         if (program_invocation_name)
204                 strncpy(program_invocation_name, name, strlen(program_invocation_name));
205
206         if (saved_argc > 0) {
207                 int i;
208
209                 if (saved_argv[0])
210                         strncpy(saved_argv[0], name, strlen(saved_argv[0]));
211
212                 for (i = 1; i < saved_argc; i++) {
213                         if (!saved_argv[i])
214                                 break;
215
216                         memzero(saved_argv[i], strlen(saved_argv[i]));
217                 }
218         }
219 }
220 #endif // 0
221
222 int is_kernel_thread(pid_t pid) {
223         const char *p;
224         size_t count;
225         char c;
226         bool eof;
227         FILE *f;
228
229         if (pid == 0 || pid == 1) /* pid 1, and we ourselves certainly aren't a kernel thread */
230                 return 0;
231
232         assert(pid > 1);
233
234         p = procfs_file_alloca(pid, "cmdline");
235         f = fopen(p, "re");
236         if (!f) {
237                 if (errno == ENOENT)
238                         return -ESRCH;
239                 return -errno;
240         }
241
242         count = fread(&c, 1, 1, f);
243         eof = feof(f);
244         fclose(f);
245
246         /* Kernel threads have an empty cmdline */
247
248         if (count <= 0)
249                 return eof ? 1 : -errno;
250
251         return 0;
252 }
253
254 /// UNNEEDED by elogind
255 #if 0
256 int get_process_capeff(pid_t pid, char **capeff) {
257         const char *p;
258         int r;
259
260         assert(capeff);
261         assert(pid >= 0);
262
263         p = procfs_file_alloca(pid, "status");
264
265         r = get_proc_field(p, "CapEff", WHITESPACE, capeff);
266         if (r == -ENOENT)
267                 return -ESRCH;
268
269         return r;
270 }
271 #endif // 0
272
273 static int get_process_link_contents(const char *proc_file, char **name) {
274         int r;
275
276         assert(proc_file);
277         assert(name);
278
279         r = readlink_malloc(proc_file, name);
280         if (r == -ENOENT)
281                 return -ESRCH;
282         if (r < 0)
283                 return r;
284
285         return 0;
286 }
287
288 int get_process_exe(pid_t pid, char **name) {
289         const char *p;
290         char *d;
291         int r;
292
293         assert(pid >= 0);
294
295         p = procfs_file_alloca(pid, "exe");
296         r = get_process_link_contents(p, name);
297         if (r < 0)
298                 return r;
299
300         d = endswith(*name, " (deleted)");
301         if (d)
302                 *d = '\0';
303
304         return 0;
305 }
306
307 /// UNNEEDED by elogind
308 #if 0
309 static int get_process_id(pid_t pid, const char *field, uid_t *uid) {
310         _cleanup_fclose_ FILE *f = NULL;
311         char line[LINE_MAX];
312         const char *p;
313
314         assert(field);
315         assert(uid);
316
317         if (pid == 0)
318                 return getuid();
319
320         p = procfs_file_alloca(pid, "status");
321         f = fopen(p, "re");
322         if (!f) {
323                 if (errno == ENOENT)
324                         return -ESRCH;
325                 return -errno;
326         }
327
328         FOREACH_LINE(line, f, return -errno) {
329                 char *l;
330
331                 l = strstrip(line);
332
333                 if (startswith(l, field)) {
334                         l += strlen(field);
335                         l += strspn(l, WHITESPACE);
336
337                         l[strcspn(l, WHITESPACE)] = 0;
338
339                         return parse_uid(l, uid);
340                 }
341         }
342
343         return -EIO;
344 }
345
346 int get_process_uid(pid_t pid, uid_t *uid) {
347         return get_process_id(pid, "Uid:", uid);
348 }
349
350 int get_process_gid(pid_t pid, gid_t *gid) {
351         assert_cc(sizeof(uid_t) == sizeof(gid_t));
352         return get_process_id(pid, "Gid:", gid);
353 }
354
355 int get_process_cwd(pid_t pid, char **cwd) {
356         const char *p;
357
358         assert(pid >= 0);
359
360         p = procfs_file_alloca(pid, "cwd");
361
362         return get_process_link_contents(p, cwd);
363 }
364
365 int get_process_root(pid_t pid, char **root) {
366         const char *p;
367
368         assert(pid >= 0);
369
370         p = procfs_file_alloca(pid, "root");
371
372         return get_process_link_contents(p, root);
373 }
374
375 int get_process_environ(pid_t pid, char **env) {
376         _cleanup_fclose_ FILE *f = NULL;
377         _cleanup_free_ char *outcome = NULL;
378         int c;
379         const char *p;
380         size_t allocated = 0, sz = 0;
381
382         assert(pid >= 0);
383         assert(env);
384
385         p = procfs_file_alloca(pid, "environ");
386
387         f = fopen(p, "re");
388         if (!f) {
389                 if (errno == ENOENT)
390                         return -ESRCH;
391                 return -errno;
392         }
393
394         while ((c = fgetc(f)) != EOF) {
395                 if (!GREEDY_REALLOC(outcome, allocated, sz + 5))
396                         return -ENOMEM;
397
398                 if (c == '\0')
399                         outcome[sz++] = '\n';
400                 else
401                         sz += cescape_char(c, outcome + sz);
402         }
403
404         if (!outcome) {
405                 outcome = strdup("");
406                 if (!outcome)
407                         return -ENOMEM;
408         } else
409         outcome[sz] = '\0';
410
411         *env = outcome;
412         outcome = NULL;
413
414         return 0;
415 }
416
417 int get_process_ppid(pid_t pid, pid_t *_ppid) {
418         int r;
419         _cleanup_free_ char *line = NULL;
420         long unsigned ppid;
421         const char *p;
422
423         assert(pid >= 0);
424         assert(_ppid);
425
426         if (pid == 0) {
427                 *_ppid = getppid();
428                 return 0;
429         }
430
431         p = procfs_file_alloca(pid, "stat");
432         r = read_one_line_file(p, &line);
433         if (r == -ENOENT)
434                 return -ESRCH;
435         if (r < 0)
436                 return r;
437
438         /* Let's skip the pid and comm fields. The latter is enclosed
439          * in () but does not escape any () in its value, so let's
440          * skip over it manually */
441
442         p = strrchr(line, ')');
443         if (!p)
444                 return -EIO;
445
446         p++;
447
448         if (sscanf(p, " "
449                    "%*c "  /* state */
450                    "%lu ", /* ppid */
451                    &ppid) != 1)
452                 return -EIO;
453
454         if ((long unsigned) (pid_t) ppid != ppid)
455                 return -ERANGE;
456
457         *_ppid = (pid_t) ppid;
458
459         return 0;
460 }
461 #endif // 0
462
463 int wait_for_terminate(pid_t pid, siginfo_t *status) {
464         siginfo_t dummy;
465
466         assert(pid >= 1);
467
468         if (!status)
469                 status = &dummy;
470
471         for (;;) {
472                 zero(*status);
473
474                 if (waitid(P_PID, pid, status, WEXITED) < 0) {
475
476                         if (errno == EINTR)
477                                 continue;
478
479                         return -errno;
480                 }
481
482                 return 0;
483         }
484 }
485
486 /*
487  * Return values:
488  * < 0 : wait_for_terminate() failed to get the state of the
489  *       process, the process was terminated by a signal, or
490  *       failed for an unknown reason.
491  * >=0 : The process terminated normally, and its exit code is
492  *       returned.
493  *
494  * That is, success is indicated by a return value of zero, and an
495  * error is indicated by a non-zero value.
496  *
497  * A warning is emitted if the process terminates abnormally,
498  * and also if it returns non-zero unless check_exit_code is true.
499  */
500 int wait_for_terminate_and_warn(const char *name, pid_t pid, bool check_exit_code) {
501         int r;
502         siginfo_t status;
503
504         assert(name);
505         assert(pid > 1);
506
507         r = wait_for_terminate(pid, &status);
508         if (r < 0)
509                 return log_warning_errno(r, "Failed to wait for %s: %m", name);
510
511         if (status.si_code == CLD_EXITED) {
512                 if (status.si_status != 0)
513                         log_full(check_exit_code ? LOG_WARNING : LOG_DEBUG,
514                                  "%s failed with error code %i.", name, status.si_status);
515                 else
516                         log_debug("%s succeeded.", name);
517
518                 return status.si_status;
519         } else if (status.si_code == CLD_KILLED ||
520                    status.si_code == CLD_DUMPED) {
521
522                 log_warning("%s terminated by signal %s.", name, signal_to_string(status.si_status));
523                 return -EPROTO;
524         }
525
526         log_warning("%s failed due to unknown reason.", name);
527         return -EPROTO;
528 }
529
530 void sigkill_wait(pid_t *pid) {
531         if (!pid)
532                 return;
533         if (*pid <= 1)
534                 return;
535
536         if (kill(*pid, SIGKILL) > 0)
537                 (void) wait_for_terminate(*pid, NULL);
538 }
539
540 /// UNNEEDED by elogind
541 #if 0
542 int kill_and_sigcont(pid_t pid, int sig) {
543         int r;
544
545         r = kill(pid, sig) < 0 ? -errno : 0;
546
547         if (r >= 0)
548                 kill(pid, SIGCONT);
549
550         return r;
551 }
552 #endif // 0
553
554 int getenv_for_pid(pid_t pid, const char *field, char **_value) {
555         _cleanup_fclose_ FILE *f = NULL;
556         char *value = NULL;
557         int r;
558         bool done = false;
559         size_t l;
560         const char *path;
561
562         assert(pid >= 0);
563         assert(field);
564         assert(_value);
565
566         path = procfs_file_alloca(pid, "environ");
567
568         f = fopen(path, "re");
569         if (!f) {
570                 if (errno == ENOENT)
571                         return -ESRCH;
572                 return -errno;
573         }
574
575         l = strlen(field);
576         r = 0;
577
578         do {
579                 char line[LINE_MAX];
580                 unsigned i;
581
582                 for (i = 0; i < sizeof(line)-1; i++) {
583                         int c;
584
585                         c = getc(f);
586                         if (_unlikely_(c == EOF)) {
587                                 done = true;
588                                 break;
589                         } else if (c == 0)
590                                 break;
591
592                         line[i] = c;
593                 }
594                 line[i] = 0;
595
596                 if (memcmp(line, field, l) == 0 && line[l] == '=') {
597                         value = strdup(line + l + 1);
598                         if (!value)
599                                 return -ENOMEM;
600
601                         r = 1;
602                         break;
603                 }
604
605         } while (!done);
606
607         *_value = value;
608         return r;
609 }
610
611 bool pid_is_unwaited(pid_t pid) {
612         /* Checks whether a PID is still valid at all, including a zombie */
613
614         if (pid < 0)
615                 return false;
616
617         if (pid <= 1) /* If we or PID 1 would be dead and have been waited for, this code would not be running */
618                 return true;
619
620         if (kill(pid, 0) >= 0)
621                 return true;
622
623         return errno != ESRCH;
624 }
625
626 bool pid_is_alive(pid_t pid) {
627         int r;
628
629         /* Checks whether a PID is still valid and not a zombie */
630
631         if (pid < 0)
632                 return false;
633
634         if (pid <= 1) /* If we or PID 1 would be a zombie, this code would not be running */
635                 return true;
636
637         r = get_process_state(pid);
638         if (r == -ESRCH || r == 'Z')
639                 return false;
640
641         return true;
642 }
643
644 bool is_main_thread(void) {
645         static thread_local int cached = 0;
646
647         if (_unlikely_(cached == 0))
648                 cached = getpid() == gettid() ? 1 : -1;
649
650         return cached > 0;
651 }
652
653 /// UNNEEDED by elogind
654 #if 0
655 noreturn void freeze(void) {
656
657         /* Make sure nobody waits for us on a socket anymore */
658         close_all_fds(NULL, 0);
659
660         sync();
661
662         for (;;)
663                 pause();
664 }
665
666 bool oom_score_adjust_is_valid(int oa) {
667         return oa >= OOM_SCORE_ADJ_MIN && oa <= OOM_SCORE_ADJ_MAX;
668 }
669
670 unsigned long personality_from_string(const char *p) {
671
672         /* Parse a personality specifier. We introduce our own
673          * identifiers that indicate specific ABIs, rather than just
674          * hints regarding the register size, since we want to keep
675          * things open for multiple locally supported ABIs for the
676          * same register size. We try to reuse the ABI identifiers
677          * used by libseccomp. */
678
679 #if defined(__x86_64__)
680
681         if (streq(p, "x86"))
682                 return PER_LINUX32;
683
684         if (streq(p, "x86-64"))
685                 return PER_LINUX;
686
687 #elif defined(__i386__)
688
689         if (streq(p, "x86"))
690                 return PER_LINUX;
691
692 #elif defined(__s390x__)
693
694         if (streq(p, "s390"))
695                 return PER_LINUX32;
696
697         if (streq(p, "s390x"))
698                 return PER_LINUX;
699
700 #elif defined(__s390__)
701
702         if (streq(p, "s390"))
703                 return PER_LINUX;
704 #endif
705
706         return PERSONALITY_INVALID;
707 }
708
709 const char* personality_to_string(unsigned long p) {
710
711 #if defined(__x86_64__)
712
713         if (p == PER_LINUX32)
714                 return "x86";
715
716         if (p == PER_LINUX)
717                 return "x86-64";
718
719 #elif defined(__i386__)
720
721         if (p == PER_LINUX)
722                 return "x86";
723
724 #elif defined(__s390x__)
725
726         if (p == PER_LINUX)
727                 return "s390x";
728
729         if (p == PER_LINUX32)
730                 return "s390";
731
732 #elif defined(__s390__)
733
734         if (p == PER_LINUX)
735                 return "s390";
736
737 #endif
738
739         return NULL;
740 }
741
742 static const char *const ioprio_class_table[] = {
743         [IOPRIO_CLASS_NONE] = "none",
744         [IOPRIO_CLASS_RT] = "realtime",
745         [IOPRIO_CLASS_BE] = "best-effort",
746         [IOPRIO_CLASS_IDLE] = "idle"
747 };
748
749 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ioprio_class, int, INT_MAX);
750
751 static const char *const sigchld_code_table[] = {
752         [CLD_EXITED] = "exited",
753         [CLD_KILLED] = "killed",
754         [CLD_DUMPED] = "dumped",
755         [CLD_TRAPPED] = "trapped",
756         [CLD_STOPPED] = "stopped",
757         [CLD_CONTINUED] = "continued",
758 };
759
760 DEFINE_STRING_TABLE_LOOKUP(sigchld_code, int);
761
762 static const char* const sched_policy_table[] = {
763         [SCHED_OTHER] = "other",
764         [SCHED_BATCH] = "batch",
765         [SCHED_IDLE] = "idle",
766         [SCHED_FIFO] = "fifo",
767         [SCHED_RR] = "rr"
768 };
769
770 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(sched_policy, int, INT_MAX);
771 #endif // 0