]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/test/test-process-util.c
Merge pull request #3520 from keszybz/add-release.md
[thirdparty/systemd.git] / src / test / test-process-util.c
1 /***
2 This file is part of systemd.
3
4 Copyright 2010 Lennart Poettering
5 Copyright 2013 Thomas H.P. Andersen
6
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
11
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
19 ***/
20
21 #include <sys/personality.h>
22 #include <sys/stat.h>
23 #include <sys/types.h>
24 #include <sys/wait.h>
25 #include <unistd.h>
26
27 #include "alloc-util.h"
28 #include "architecture.h"
29 #include "log.h"
30 #include "macro.h"
31 #include "parse-util.h"
32 #include "process-util.h"
33 #include "stdio-util.h"
34 #include "string-util.h"
35 #include "terminal-util.h"
36 #include "util.h"
37 #include "virt.h"
38
39 static void test_get_process_comm(pid_t pid) {
40 struct stat st;
41 _cleanup_free_ char *a = NULL, *c = NULL, *d = NULL, *f = NULL, *i = NULL, *cwd = NULL, *root = NULL;
42 _cleanup_free_ char *env = NULL;
43 char path[strlen("/proc//comm") + DECIMAL_STR_MAX(pid_t)];
44 pid_t e;
45 uid_t u;
46 gid_t g;
47 dev_t h;
48 int r;
49
50 xsprintf(path, "/proc/"PID_FMT"/comm", pid);
51
52 if (stat(path, &st) == 0) {
53 assert_se(get_process_comm(pid, &a) >= 0);
54 log_info("PID"PID_FMT" comm: '%s'", pid, a);
55 } else
56 log_warning("%s not exist.", path);
57
58 assert_se(get_process_cmdline(pid, 0, true, &c) >= 0);
59 log_info("PID"PID_FMT" cmdline: '%s'", pid, c);
60
61 assert_se(get_process_cmdline(pid, 8, false, &d) >= 0);
62 log_info("PID"PID_FMT" cmdline truncated: '%s'", pid, d);
63
64 assert_se(get_process_ppid(pid, &e) >= 0);
65 log_info("PID"PID_FMT" PPID: "PID_FMT, pid, e);
66 assert_se(pid == 1 ? e == 0 : e > 0);
67
68 assert_se(is_kernel_thread(pid) == 0 || pid != 1);
69
70 r = get_process_exe(pid, &f);
71 assert_se(r >= 0 || r == -EACCES);
72 log_info("PID"PID_FMT" exe: '%s'", pid, strna(f));
73
74 assert_se(get_process_uid(pid, &u) == 0);
75 log_info("PID"PID_FMT" UID: "UID_FMT, pid, u);
76 assert_se(u == 0 || pid != 1);
77
78 assert_se(get_process_gid(pid, &g) == 0);
79 log_info("PID"PID_FMT" GID: "GID_FMT, pid, g);
80 assert_se(g == 0 || pid != 1);
81
82 r = get_process_environ(pid, &env);
83 assert_se(r >= 0 || r == -EACCES);
84 log_info("PID"PID_FMT" strlen(environ): %zi", pid, env ? (ssize_t)strlen(env) : (ssize_t)-errno);
85
86 if (!detect_container())
87 assert_se(get_ctty_devnr(pid, &h) == -ENXIO || pid != 1);
88
89 getenv_for_pid(pid, "PATH", &i);
90 log_info("PID"PID_FMT" $PATH: '%s'", pid, strna(i));
91 }
92
93 static void test_pid_is_unwaited(void) {
94 pid_t pid;
95
96 pid = fork();
97 assert_se(pid >= 0);
98 if (pid == 0) {
99 _exit(EXIT_SUCCESS);
100 } else {
101 int status;
102
103 waitpid(pid, &status, 0);
104 assert_se(!pid_is_unwaited(pid));
105 }
106 assert_se(pid_is_unwaited(getpid()));
107 assert_se(!pid_is_unwaited(-1));
108 }
109
110 static void test_pid_is_alive(void) {
111 pid_t pid;
112
113 pid = fork();
114 assert_se(pid >= 0);
115 if (pid == 0) {
116 _exit(EXIT_SUCCESS);
117 } else {
118 int status;
119
120 waitpid(pid, &status, 0);
121 assert_se(!pid_is_alive(pid));
122 }
123 assert_se(pid_is_alive(getpid()));
124 assert_se(!pid_is_alive(-1));
125 }
126
127 static void test_personality(void) {
128
129 assert_se(personality_to_string(PER_LINUX));
130 assert_se(!personality_to_string(PERSONALITY_INVALID));
131
132 assert_se(streq(personality_to_string(PER_LINUX), architecture_to_string(native_architecture())));
133
134 assert_se(personality_from_string(personality_to_string(PER_LINUX)) == PER_LINUX);
135 assert_se(personality_from_string(architecture_to_string(native_architecture())) == PER_LINUX);
136
137 #ifdef __x86_64__
138 assert_se(streq_ptr(personality_to_string(PER_LINUX), "x86-64"));
139 assert_se(streq_ptr(personality_to_string(PER_LINUX32), "x86"));
140
141 assert_se(personality_from_string("x86-64") == PER_LINUX);
142 assert_se(personality_from_string("x86") == PER_LINUX32);
143 assert_se(personality_from_string("ia64") == PERSONALITY_INVALID);
144 assert_se(personality_from_string(NULL) == PERSONALITY_INVALID);
145
146 assert_se(personality_from_string(personality_to_string(PER_LINUX32)) == PER_LINUX32);
147 #endif
148 }
149
150 int main(int argc, char *argv[]) {
151 log_parse_environment();
152 log_open();
153
154 if (argc > 1) {
155 pid_t pid = 0;
156
157 (void) parse_pid(argv[1], &pid);
158 test_get_process_comm(pid);
159 } else {
160 test_get_process_comm(1);
161 test_get_process_comm(getpid());
162 }
163
164 test_pid_is_unwaited();
165 test_pid_is_alive();
166 test_personality();
167
168 return 0;
169 }