]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/basic/process-util.h
process-util: add helper get_process_threads()
[thirdparty/systemd.git] / src / basic / process-util.h
CommitLineData
db9ecf05 1/* SPDX-License-Identifier: LGPL-2.1-or-later */
0b452006
RC
2#pragma once
3
dccca82b 4#include <errno.h>
29ea9f0f 5#include <sched.h>
71d35b6b
TA
6#include <signal.h>
7#include <stdbool.h>
11c3a366 8#include <stddef.h>
0b452006
RC
9#include <stdio.h>
10#include <string.h>
41bf0590 11#include <sys/resource.h>
7f452159 12#include <sys/types.h>
0b452006 13
0cb8e3d1 14#include "alloc-util.h"
f97b34a6 15#include "format-util.h"
7b3e062c 16#include "macro.h"
d5641e0d 17#include "time-util.h"
0b452006
RC
18
19#define procfs_file_alloca(pid, field) \
20 ({ \
21 pid_t _pid_ = (pid); \
a07f18cd
LP
22 const char *_field_ = (field); \
23 char *_r_; \
0b452006 24 if (_pid_ == 0) { \
a07f18cd
LP
25 _r_ = newa(char, STRLEN("/proc/self/") + strlen(_field_) + 1); \
26 strcpy(stpcpy(_r_, "/proc/self/"), _field_); \
0b452006 27 } else { \
a07f18cd
LP
28 _r_ = newa(char, STRLEN("/proc/") + DECIMAL_STR_MAX(pid_t) + 1 + strlen(_field_) + 1); \
29 sprintf(_r_, "/proc/" PID_FMT "/%s", _pid_, _field_); \
0b452006 30 } \
a07f18cd 31 (const char*) _r_; \
0b452006
RC
32 })
33
09c1dcee
ZJS
34typedef enum ProcessCmdlineFlags {
35 PROCESS_CMDLINE_COMM_FALLBACK = 1 << 0,
e3b4efd2 36 PROCESS_CMDLINE_USE_LOCALE = 1 << 1,
61977664 37 PROCESS_CMDLINE_QUOTE = 1 << 2,
99009ed0 38 PROCESS_CMDLINE_QUOTE_POSIX = 1 << 3,
09c1dcee
ZJS
39} ProcessCmdlineFlags;
40
95a511b7
YW
41int get_process_comm(pid_t pid, char **ret);
42int get_process_cmdline(pid_t pid, size_t max_columns, ProcessCmdlineFlags flags, char **ret);
43int get_process_exe(pid_t pid, char **ret);
44int get_process_uid(pid_t pid, uid_t *ret);
45int get_process_gid(pid_t pid, gid_t *ret);
46int get_process_capeff(pid_t pid, char **ret);
47int get_process_cwd(pid_t pid, char **ret);
48int get_process_root(pid_t pid, char **ret);
49int get_process_environ(pid_t pid, char **ret);
50int get_process_ppid(pid_t pid, pid_t *ret);
51int get_process_umask(pid_t pid, mode_t *ret);
0b452006 52
3ec2ad35
ZJS
53int container_get_leader(const char *machine, pid_t *pid);
54
0b452006 55int wait_for_terminate(pid_t pid, siginfo_t *status);
7d4904fe
LP
56
57typedef enum WaitFlags {
ef31828d
LP
58 WAIT_LOG_ABNORMAL = 1 << 0,
59 WAIT_LOG_NON_ZERO_EXIT_STATUS = 1 << 1,
7d4904fe
LP
60
61 /* A shortcut for requesting the most complete logging */
62 WAIT_LOG = WAIT_LOG_ABNORMAL|WAIT_LOG_NON_ZERO_EXIT_STATUS,
63} WaitFlags;
64
65int wait_for_terminate_and_check(const char *name, pid_t pid, WaitFlags flags);
d5641e0d 66int wait_for_terminate_with_timeout(pid_t pid, usec_t timeout);
0b452006 67
89c9030d
LP
68void sigkill_wait(pid_t pid);
69void sigkill_waitp(pid_t *pid);
392cf1d0 70void sigterm_wait(pid_t pid);
b293bb23
LP
71void sigkill_nowait(pid_t pid);
72void sigkill_nowaitp(pid_t *pid);
4d0d3d41 73
0b452006 74int kill_and_sigcont(pid_t pid, int sig);
405f8907 75
0b452006 76int is_kernel_thread(pid_t pid);
405f8907 77
0b452006
RC
78int getenv_for_pid(pid_t pid, const char *field, char **_value);
79
80bool pid_is_alive(pid_t pid);
81bool pid_is_unwaited(pid_t pid);
4d051546 82int pid_is_my_child(pid_t pid);
1359fffa 83int pid_from_same_root_fs(pid_t pid);
d4510856
LP
84
85bool is_main_thread(void);
ceee6d3a 86
c4412d4d
LP
87bool oom_score_adjust_is_valid(int oa);
88
7b3e062c
LP
89#ifndef PERSONALITY_INVALID
90/* personality(7) documents that 0xffffffffUL is used for querying the
91 * current personality, hence let's use that here as error
92 * indicator. */
93#define PERSONALITY_INVALID 0xffffffffLU
94#endif
95
96unsigned long personality_from_string(const char *p);
97const char *personality_to_string(unsigned long);
98
21022b9d 99int safe_personality(unsigned long p);
e8132d63
LP
100int opinionated_personality(unsigned long *ret);
101
7b3e062c
LP
102const char *sigchld_code_to_string(int i) _const_;
103int sigchld_code_from_string(const char *s) _pure_;
104
105int sched_policy_to_string_alloc(int i, char **s);
106int sched_policy_from_string(const char *s);
107
bc2fcf7f
LP
108static inline pid_t PTR_TO_PID(const void *p) {
109 return (pid_t) ((uintptr_t) p);
110}
111
112static inline void* PID_TO_PTR(pid_t pid) {
113 return (void*) ((uintptr_t) pid);
114}
dcadc967
EV
115
116void valgrind_summary_hack(void);
291d565a 117
93bab288 118int pid_compare_func(const pid_t *a, const pid_t *b);
41bf0590
LP
119
120static inline bool nice_is_valid(int n) {
121 return n >= PRIO_MIN && n < PRIO_MAX;
122}
7f452159 123
29ea9f0f
YW
124static inline bool sched_policy_is_valid(int i) {
125 return IN_SET(i, SCHED_OTHER, SCHED_BATCH, SCHED_IDLE, SCHED_FIFO, SCHED_RR);
126}
127
128static inline bool sched_priority_is_valid(int i) {
129 return i >= 0 && i <= sched_get_priority_max(SCHED_RR);
130}
131
54191eb3
LP
132static inline bool pid_is_valid(pid_t p) {
133 return p > 0;
134}
135
5c30a6d2 136pid_t getpid_cached(void);
799a960d 137void reset_cached_pid(void);
fba868fa
LP
138
139int must_be_root(void);
4c253ed1
LP
140
141typedef enum ForkFlags {
8987afc4
LP
142 FORK_RESET_SIGNALS = 1 << 0, /* Reset all signal handlers and signal mask */
143 FORK_CLOSE_ALL_FDS = 1 << 1, /* Close all open file descriptors in the child, except for 0,1,2 */
97033ba4
LP
144 FORK_DEATHSIG = 1 << 2, /* Set PR_DEATHSIG in the child to SIGTERM */
145 FORK_DEATHSIG_SIGINT = 1 << 3, /* Set PR_DEATHSIG in the child to SIGINT */
146 FORK_NULL_STDIO = 1 << 4, /* Connect 0,1,2 to /dev/null */
147 FORK_REOPEN_LOG = 1 << 5, /* Reopen log connection */
148 FORK_LOG = 1 << 6, /* Log above LOG_DEBUG log level about failures */
149 FORK_WAIT = 1 << 7, /* Wait until child exited */
150 FORK_NEW_MOUNTNS = 1 << 8, /* Run child in its own mount namespace */
151 FORK_MOUNTNS_SLAVE = 1 << 9, /* Make child's mount namespace MS_SLAVE */
61ef3051
ZJS
152 FORK_PRIVATE_TMP = 1 << 10, /* Mount new /tmp/ in the child (combine with FORK_NEW_MOUNTNS!) */
153 FORK_RLIMIT_NOFILE_SAFE = 1 << 11, /* Set RLIMIT_NOFILE soft limit to 1K for select() compat */
154 FORK_STDOUT_TO_STDERR = 1 << 12, /* Make stdout a copy of stderr */
155 FORK_FLUSH_STDIO = 1 << 13, /* fflush() stdout (and stderr) before forking */
156 FORK_NEW_USERNS = 1 << 14, /* Run child in its own user namespace */
157 FORK_CLOEXEC_OFF = 1 << 15, /* In the child: turn off O_CLOEXEC on all fds in except_fds[] */
4c253ed1
LP
158} ForkFlags;
159
c85cb3bc 160int safe_fork_full(const char *name, const int except_fds[], size_t n_except_fds, ForkFlags flags, pid_t *ret_pid);
4c253ed1
LP
161
162static inline int safe_fork(const char *name, ForkFlags flags, pid_t *ret_pid) {
163 return safe_fork_full(name, NULL, 0, flags, ret_pid);
164}
78752f2e 165
c85cb3bc 166int namespace_fork(const char *outer_name, const char *inner_name, const int except_fds[], size_t n_except_fds, ForkFlags flags, int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int root_fd, pid_t *ret_pid);
27096982 167
9f8168eb 168int set_oom_score_adjust(int value);
2c37c613 169int get_oom_score_adjust(int *ret);
9f8168eb 170
f3a367d6
LP
171/* The highest possibly (theoretic) pid_t value on this architecture. */
172#define PID_T_MAX ((pid_t) INT32_MAX)
173/* The maximum number of concurrent processes Linux allows on this architecture, as well as the highest valid PID value
174 * the kernel will potentially assign. This reflects a value compiled into the kernel (PID_MAX_LIMIT), and sets the
175 * upper boundary on what may be written to the /proc/sys/kernel/pid_max sysctl (but do note that the sysctl is off by
176 * 1, since PID 0 can never exist and there can hence only be one process less than the limit would suggest). Since
177 * these values are documented in proc(5) we feel quite confident that they are stable enough for the near future at
178 * least to define them here too. */
179#define TASKS_MAX 4194303U
f3a367d6 180
ab1a1ba5 181assert_cc(TASKS_MAX <= (unsigned long) PID_T_MAX);
342f6f80 182
40c5cc2b
DS
183/* Like TAKE_PTR() but for pid_t, resetting them to 0 */
184#define TAKE_PID(pid) TAKE_GENERIC(pid, pid_t, 0)
298f466f
LP
185
186int pidfd_get_pid(int fd, pid_t *ret);
f840c7d5 187int pidfd_verify_pid(int pidfd, pid_t pid);
39090201
DJL
188
189int setpriority_closest(int priority);
2306d177 190
8ddefb8e 191_noreturn_ void freeze(void);
6aa90884
LP
192
193int get_process_threads(pid_t pid);