1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
7 Copyright 2013 Thomas H.P. Andersen
9 systemd is free software; you can redistribute it and/or modify it
10 under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 2.1 of the License, or
12 (at your option) any later version.
14 systemd is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
19 You should have received a copy of the GNU Lesser General Public License
20 along with systemd; If not, see <http://www.gnu.org/licenses/>.
30 static void test_streq_ptr(void) {
31 assert_se(streq_ptr(NULL, NULL));
32 assert_se(!streq_ptr("abc", "cdef"));
35 static void test_first_word(void) {
36 assert_se(first_word("Hello", ""));
37 assert_se(first_word("Hello", "Hello"));
38 assert_se(first_word("Hello world", "Hello"));
39 assert_se(first_word("Hello\tworld", "Hello"));
40 assert_se(first_word("Hello\nworld", "Hello"));
41 assert_se(first_word("Hello\rworld", "Hello"));
42 assert_se(first_word("Hello ", "Hello"));
44 assert_se(!first_word("Hello", "Hellooo"));
45 assert_se(!first_word("Hello", "xxxxx"));
46 assert_se(!first_word("Hellooo", "Hello"));
49 static void test_close_many(void) {
51 char name0[] = "/tmp/test-close-many.XXXXXX";
52 char name1[] = "/tmp/test-close-many.XXXXXX";
53 char name2[] = "/tmp/test-close-many.XXXXXX";
55 fds[0] = mkstemp(name0);
56 fds[1] = mkstemp(name1);
57 fds[2] = mkstemp(name2);
61 assert_se(fcntl(fds[0], F_GETFD) == -1);
62 assert_se(fcntl(fds[1], F_GETFD) == -1);
63 assert_se(fcntl(fds[2], F_GETFD) >= 0);
65 close_nointr_nofail(fds[2]);
72 static void test_parse_boolean(void) {
73 assert_se(parse_boolean("1") == 1);
74 assert_se(parse_boolean("y") == 1);
75 assert_se(parse_boolean("Y") == 1);
76 assert_se(parse_boolean("yes") == 1);
77 assert_se(parse_boolean("YES") == 1);
78 assert_se(parse_boolean("true") == 1);
79 assert_se(parse_boolean("TRUE") == 1);
80 assert_se(parse_boolean("on") == 1);
81 assert_se(parse_boolean("ON") == 1);
83 assert_se(parse_boolean("0") == 0);
84 assert_se(parse_boolean("n") == 0);
85 assert_se(parse_boolean("N") == 0);
86 assert_se(parse_boolean("no") == 0);
87 assert_se(parse_boolean("NO") == 0);
88 assert_se(parse_boolean("false") == 0);
89 assert_se(parse_boolean("FALSE") == 0);
90 assert_se(parse_boolean("off") == 0);
91 assert_se(parse_boolean("OFF") == 0);
93 assert_se(parse_boolean("garbage") < 0);
94 assert_se(parse_boolean("") < 0);
97 static void test_parse_pid(void) {
101 r = parse_pid("100", &pid);
103 assert_se(pid == 100);
105 r = parse_pid("0x7FFFFFFF", &pid);
107 assert_se(pid == 2147483647);
109 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
110 r = parse_pid("0", &pid);
111 assert_se(r == -ERANGE);
112 assert_se(pid == 65);
114 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
115 r = parse_pid("-100", &pid);
116 assert_se(r == -ERANGE);
117 assert_se(pid == 65);
119 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
120 r = parse_pid("0xFFFFFFFFFFFFFFFFF", &pid);
121 assert(r == -ERANGE);
122 assert_se(pid == 65);
125 static void test_parse_uid(void) {
129 r = parse_uid("100", &uid);
131 assert_se(uid == 100);
134 static void test_safe_atolli(void) {
138 r = safe_atolli("12345", &l);
140 assert_se(l == 12345);
142 r = safe_atolli("junk", &l);
143 assert_se(r == -EINVAL);
146 static void test_safe_atod(void) {
151 r = safe_atod("junk", &d);
152 assert_se(r == -EINVAL);
154 r = safe_atod("0.2244", &d);
156 assert_se(abs(d - 0.2244) < 0.000001);
158 r = safe_atod("0,5", &d);
159 assert_se(r == -EINVAL);
163 assert_se(*e == ',');
165 /* Check if this really is locale independent */
166 setlocale(LC_NUMERIC, "de_DE.utf8");
168 r = safe_atod("0.2244", &d);
170 assert_se(abs(d - 0.2244) < 0.000001);
172 r = safe_atod("0,5", &d);
173 assert_se(r == -EINVAL);
176 assert_se(abs(strtod("0,5", &e) - 0.5) < 0.00001);
178 /* And check again, reset */
179 setlocale(LC_NUMERIC, "C");
181 r = safe_atod("0.2244", &d);
183 assert_se(abs(d - 0.2244) < 0.000001);
185 r = safe_atod("0,5", &d);
186 assert_se(r == -EINVAL);
190 assert_se(*e == ',');
193 static void test_strappend(void) {
194 _cleanup_free_ char *t1, *t2, *t3, *t4;
196 t1 = strappend(NULL, NULL);
197 assert_se(streq(t1, ""));
199 t2 = strappend(NULL, "suf");
200 assert_se(streq(t2, "suf"));
202 t3 = strappend("pre", NULL);
203 assert_se(streq(t3, "pre"));
205 t4 = strappend("pre", "suf");
206 assert_se(streq(t4, "presuf"));
209 static void test_strstrip(void) {
211 char input[] = " hello, waldo. ";
214 assert_se(streq(r, "hello, waldo."));
218 static void test_delete_chars(void) {
220 char input[] = " hello, waldo. abc";
222 r = delete_chars(input, WHITESPACE);
223 assert_se(streq(r, "hello,waldo.abc"));
226 static void test_in_charset(void) {
227 assert_se(in_charset("dddaaabbbcccc", "abcd"));
228 assert_se(!in_charset("dddaaabbbcccc", "abc f"));
231 static void test_hexchar(void) {
232 assert_se(hexchar(0xa) == 'a');
233 assert_se(hexchar(0x0) == '0');
236 static void test_unhexchar(void) {
237 assert_se(unhexchar('a') == 0xA);
238 assert_se(unhexchar('A') == 0xA);
239 assert_se(unhexchar('0') == 0x0);
242 static void test_octchar(void) {
243 assert_se(octchar(00) == '0');
244 assert_se(octchar(07) == '7');
247 static void test_unoctchar(void) {
248 assert_se(unoctchar('0') == 00);
249 assert_se(unoctchar('7') == 07);
252 static void test_decchar(void) {
253 assert_se(decchar(0) == '0');
254 assert_se(decchar(9) == '9');
257 static void test_undecchar(void) {
258 assert_se(undecchar('0') == 0);
259 assert_se(undecchar('9') == 9);
262 static void test_foreach_word(void) {
266 const char test[] = "test abc d\te f ";
267 const char * const expected[] = {
277 FOREACH_WORD(w, l, test, state) {
278 assert_se(strneq(expected[i++], w, l));
282 static void test_foreach_word_quoted(void) {
286 const char test[] = "test a b c 'd' e '' '' hhh '' '' \"a b c\"";
287 const char * const expected[] = {
303 printf("<%s>\n", test);
304 FOREACH_WORD_QUOTED(w, l, test, state) {
305 _cleanup_free_ char *t = NULL;
307 assert_se(t = strndup(w, l));
308 assert_se(strneq(expected[i++], w, l));
313 static void test_default_term_for_tty(void) {
314 puts(default_term_for_tty("/dev/tty23"));
315 puts(default_term_for_tty("/dev/ttyS23"));
316 puts(default_term_for_tty("/dev/tty0"));
317 puts(default_term_for_tty("/dev/pty0"));
318 puts(default_term_for_tty("/dev/pts/0"));
319 puts(default_term_for_tty("/dev/console"));
320 puts(default_term_for_tty("tty23"));
321 puts(default_term_for_tty("ttyS23"));
322 puts(default_term_for_tty("tty0"));
323 puts(default_term_for_tty("pty0"));
324 puts(default_term_for_tty("pts/0"));
325 puts(default_term_for_tty("console"));
328 static void test_memdup_multiply(void) {
329 int org[] = {1, 2, 3};
332 dup = (int*)memdup_multiply(org, sizeof(int), 3);
335 assert_se(dup[0] == 1);
336 assert_se(dup[1] == 2);
337 assert_se(dup[2] == 3);
341 static void test_bus_path_escape_one(const char *a, const char *b) {
342 _cleanup_free_ char *t = NULL, *x = NULL, *y = NULL;
344 assert_se(t = bus_path_escape(a));
345 assert_se(streq(t, b));
347 assert_se(x = bus_path_unescape(t));
348 assert_se(streq(a, x));
350 assert_se(y = bus_path_unescape(b));
351 assert_se(streq(a, y));
354 static void test_bus_path_escape(void) {
355 test_bus_path_escape_one("foo123bar", "foo123bar");
356 test_bus_path_escape_one("foo.bar", "foo_2ebar");
357 test_bus_path_escape_one("foo_2ebar", "foo_5f2ebar");
358 test_bus_path_escape_one("", "_");
359 test_bus_path_escape_one("_", "_5f");
360 test_bus_path_escape_one("1", "_31");
361 test_bus_path_escape_one(":1", "_3a1");
364 static void test_hostname_is_valid(void) {
365 assert(hostname_is_valid("foobar"));
366 assert(hostname_is_valid("foobar.com"));
367 assert(!hostname_is_valid("fööbar"));
368 assert(!hostname_is_valid(""));
369 assert(!hostname_is_valid("."));
370 assert(!hostname_is_valid(".."));
371 assert(!hostname_is_valid("foobar."));
372 assert(!hostname_is_valid(".foobar"));
373 assert(!hostname_is_valid("foo..bar"));
374 assert(!hostname_is_valid("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"));
377 static void test_u64log2(void) {
378 assert(u64log2(0) == 0);
379 assert(u64log2(8) == 3);
380 assert(u64log2(9) == 3);
381 assert(u64log2(15) == 3);
382 assert(u64log2(16) == 4);
383 assert(u64log2(1024*1024) == 20);
384 assert(u64log2(1024*1024+5) == 20);
387 static void test_get_process_comm(void) {
388 _cleanup_free_ char *a = NULL, *c = NULL, *d = NULL, *f = NULL, *i = NULL;
389 unsigned long long b;
396 assert_se(get_process_comm(1, &a) >= 0);
397 log_info("pid1 comm: '%s'", a);
399 assert_se(get_starttime_of_pid(1, &b) >= 0);
400 log_info("pid1 starttime: '%llu'", b);
402 assert_se(get_process_cmdline(1, 0, true, &c) >= 0);
403 log_info("pid1 cmdline: '%s'", c);
405 assert_se(get_process_cmdline(1, 8, false, &d) >= 0);
406 log_info("pid1 cmdline truncated: '%s'", d);
408 assert_se(get_parent_of_pid(1, &e) >= 0);
409 log_info("pid1 ppid: '%llu'", (unsigned long long) e);
412 assert_se(is_kernel_thread(1) == 0);
414 r = get_process_exe(1, &f);
415 assert_se(r >= 0 || r == -EACCES);
416 log_info("pid1 exe: '%s'", strna(f));
418 assert_se(get_process_uid(1, &u) == 0);
419 log_info("pid1 uid: '%llu'", (unsigned long long) u);
422 assert_se(get_process_gid(1, &g) == 0);
423 log_info("pid1 gid: '%llu'", (unsigned long long) g);
426 assert(get_ctty_devnr(1, &h) == -ENOENT);
428 getenv_for_pid(1, "PATH", &i);
429 log_info("pid1 $PATH: '%s'", strna(i));
432 int main(int argc, char *argv[]) {
436 test_parse_boolean();
452 test_foreach_word_quoted();
453 test_default_term_for_tty();
454 test_memdup_multiply();
455 test_bus_path_escape();
456 test_hostname_is_valid();
458 test_get_process_comm();