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