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/>.
31 static void test_streq_ptr(void) {
32 assert_se(streq_ptr(NULL, NULL));
33 assert_se(!streq_ptr("abc", "cdef"));
36 static void test_first_word(void) {
37 assert_se(first_word("Hello", ""));
38 assert_se(first_word("Hello", "Hello"));
39 assert_se(first_word("Hello world", "Hello"));
40 assert_se(first_word("Hello\tworld", "Hello"));
41 assert_se(first_word("Hello\nworld", "Hello"));
42 assert_se(first_word("Hello\rworld", "Hello"));
43 assert_se(first_word("Hello ", "Hello"));
45 assert_se(!first_word("Hello", "Hellooo"));
46 assert_se(!first_word("Hello", "xxxxx"));
47 assert_se(!first_word("Hellooo", "Hello"));
50 static void test_close_many(void) {
52 char name0[] = "/tmp/test-close-many.XXXXXX";
53 char name1[] = "/tmp/test-close-many.XXXXXX";
54 char name2[] = "/tmp/test-close-many.XXXXXX";
56 fds[0] = mkstemp(name0);
57 fds[1] = mkstemp(name1);
58 fds[2] = mkstemp(name2);
62 assert_se(fcntl(fds[0], F_GETFD) == -1);
63 assert_se(fcntl(fds[1], F_GETFD) == -1);
64 assert_se(fcntl(fds[2], F_GETFD) >= 0);
66 close_nointr_nofail(fds[2]);
73 static void test_parse_boolean(void) {
74 assert_se(parse_boolean("1") == 1);
75 assert_se(parse_boolean("y") == 1);
76 assert_se(parse_boolean("Y") == 1);
77 assert_se(parse_boolean("yes") == 1);
78 assert_se(parse_boolean("YES") == 1);
79 assert_se(parse_boolean("true") == 1);
80 assert_se(parse_boolean("TRUE") == 1);
81 assert_se(parse_boolean("on") == 1);
82 assert_se(parse_boolean("ON") == 1);
84 assert_se(parse_boolean("0") == 0);
85 assert_se(parse_boolean("n") == 0);
86 assert_se(parse_boolean("N") == 0);
87 assert_se(parse_boolean("no") == 0);
88 assert_se(parse_boolean("NO") == 0);
89 assert_se(parse_boolean("false") == 0);
90 assert_se(parse_boolean("FALSE") == 0);
91 assert_se(parse_boolean("off") == 0);
92 assert_se(parse_boolean("OFF") == 0);
94 assert_se(parse_boolean("garbage") < 0);
95 assert_se(parse_boolean("") < 0);
98 static void test_parse_pid(void) {
102 r = parse_pid("100", &pid);
104 assert_se(pid == 100);
106 r = parse_pid("0x7FFFFFFF", &pid);
108 assert_se(pid == 2147483647);
110 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
111 r = parse_pid("0", &pid);
112 assert_se(r == -ERANGE);
113 assert_se(pid == 65);
115 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
116 r = parse_pid("-100", &pid);
117 assert_se(r == -ERANGE);
118 assert_se(pid == 65);
120 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
121 r = parse_pid("0xFFFFFFFFFFFFFFFFF", &pid);
122 assert(r == -ERANGE);
123 assert_se(pid == 65);
126 static void test_parse_uid(void) {
130 r = parse_uid("100", &uid);
132 assert_se(uid == 100);
135 static void test_safe_atolli(void) {
139 r = safe_atolli("12345", &l);
141 assert_se(l == 12345);
143 r = safe_atolli("junk", &l);
144 assert_se(r == -EINVAL);
147 static void test_safe_atod(void) {
152 r = safe_atod("junk", &d);
153 assert_se(r == -EINVAL);
155 r = safe_atod("0.2244", &d);
157 assert_se(abs(d - 0.2244) < 0.000001);
159 r = safe_atod("0,5", &d);
160 assert_se(r == -EINVAL);
164 assert_se(*e == ',');
166 /* Check if this really is locale independent */
167 setlocale(LC_NUMERIC, "de_DE.utf8");
169 r = safe_atod("0.2244", &d);
171 assert_se(abs(d - 0.2244) < 0.000001);
173 r = safe_atod("0,5", &d);
174 assert_se(r == -EINVAL);
177 assert_se(abs(strtod("0,5", &e) - 0.5) < 0.00001);
179 /* And check again, reset */
180 setlocale(LC_NUMERIC, "C");
182 r = safe_atod("0.2244", &d);
184 assert_se(abs(d - 0.2244) < 0.000001);
186 r = safe_atod("0,5", &d);
187 assert_se(r == -EINVAL);
191 assert_se(*e == ',');
194 static void test_strappend(void) {
195 _cleanup_free_ char *t1, *t2, *t3, *t4;
197 t1 = strappend(NULL, NULL);
198 assert_se(streq(t1, ""));
200 t2 = strappend(NULL, "suf");
201 assert_se(streq(t2, "suf"));
203 t3 = strappend("pre", NULL);
204 assert_se(streq(t3, "pre"));
206 t4 = strappend("pre", "suf");
207 assert_se(streq(t4, "presuf"));
210 static void test_strstrip(void) {
212 char input[] = " hello, waldo. ";
215 assert_se(streq(r, "hello, waldo."));
219 static void test_delete_chars(void) {
221 char input[] = " hello, waldo. abc";
223 r = delete_chars(input, WHITESPACE);
224 assert_se(streq(r, "hello,waldo.abc"));
227 static void test_in_charset(void) {
228 assert_se(in_charset("dddaaabbbcccc", "abcd"));
229 assert_se(!in_charset("dddaaabbbcccc", "abc f"));
232 static void test_hexchar(void) {
233 assert_se(hexchar(0xa) == 'a');
234 assert_se(hexchar(0x0) == '0');
237 static void test_unhexchar(void) {
238 assert_se(unhexchar('a') == 0xA);
239 assert_se(unhexchar('A') == 0xA);
240 assert_se(unhexchar('0') == 0x0);
243 static void test_octchar(void) {
244 assert_se(octchar(00) == '0');
245 assert_se(octchar(07) == '7');
248 static void test_unoctchar(void) {
249 assert_se(unoctchar('0') == 00);
250 assert_se(unoctchar('7') == 07);
253 static void test_decchar(void) {
254 assert_se(decchar(0) == '0');
255 assert_se(decchar(9) == '9');
258 static void test_undecchar(void) {
259 assert_se(undecchar('0') == 0);
260 assert_se(undecchar('9') == 9);
263 static void test_cescape(void) {
264 _cleanup_free_ char *escaped;
265 escaped = cescape("abc\\\"\b\f\n\r\t\v\003\177\234\313");
266 assert_se(streq(escaped, "abc\\\\\\\"\\b\\f\\n\\r\\t\\v\\003\\177\\234\\313"));
269 static void test_cunescape(void) {
270 _cleanup_free_ char *unescaped;
271 unescaped = cunescape("abc\\\\\\\"\\b\\f\\n\\r\\t\\v\\003\\177\\234\\313");
272 assert_se(streq(unescaped, "abc\\\"\b\f\n\r\t\v\003\177\234\313"));
275 static void test_foreach_word(void) {
279 const char test[] = "test abc d\te f ";
280 const char * const expected[] = {
290 FOREACH_WORD(w, l, test, state) {
291 assert_se(strneq(expected[i++], w, l));
295 static void test_foreach_word_quoted(void) {
299 const char test[] = "test a b c 'd' e '' '' hhh '' '' \"a b c\"";
300 const char * const expected[] = {
316 printf("<%s>\n", test);
317 FOREACH_WORD_QUOTED(w, l, test, state) {
318 _cleanup_free_ char *t = NULL;
320 assert_se(t = strndup(w, l));
321 assert_se(strneq(expected[i++], w, l));
326 static void test_default_term_for_tty(void) {
327 puts(default_term_for_tty("/dev/tty23"));
328 puts(default_term_for_tty("/dev/ttyS23"));
329 puts(default_term_for_tty("/dev/tty0"));
330 puts(default_term_for_tty("/dev/pty0"));
331 puts(default_term_for_tty("/dev/pts/0"));
332 puts(default_term_for_tty("/dev/console"));
333 puts(default_term_for_tty("tty23"));
334 puts(default_term_for_tty("ttyS23"));
335 puts(default_term_for_tty("tty0"));
336 puts(default_term_for_tty("pty0"));
337 puts(default_term_for_tty("pts/0"));
338 puts(default_term_for_tty("console"));
341 static void test_memdup_multiply(void) {
342 int org[] = {1, 2, 3};
345 dup = (int*)memdup_multiply(org, sizeof(int), 3);
348 assert_se(dup[0] == 1);
349 assert_se(dup[1] == 2);
350 assert_se(dup[2] == 3);
354 static void test_bus_path_escape_one(const char *a, const char *b) {
355 _cleanup_free_ char *t = NULL, *x = NULL, *y = NULL;
357 assert_se(t = bus_path_escape(a));
358 assert_se(streq(t, b));
360 assert_se(x = bus_path_unescape(t));
361 assert_se(streq(a, x));
363 assert_se(y = bus_path_unescape(b));
364 assert_se(streq(a, y));
367 static void test_bus_path_escape(void) {
368 test_bus_path_escape_one("foo123bar", "foo123bar");
369 test_bus_path_escape_one("foo.bar", "foo_2ebar");
370 test_bus_path_escape_one("foo_2ebar", "foo_5f2ebar");
371 test_bus_path_escape_one("", "_");
372 test_bus_path_escape_one("_", "_5f");
373 test_bus_path_escape_one("1", "_31");
374 test_bus_path_escape_one(":1", "_3a1");
377 static void test_hostname_is_valid(void) {
378 assert(hostname_is_valid("foobar"));
379 assert(hostname_is_valid("foobar.com"));
380 assert(!hostname_is_valid("fööbar"));
381 assert(!hostname_is_valid(""));
382 assert(!hostname_is_valid("."));
383 assert(!hostname_is_valid(".."));
384 assert(!hostname_is_valid("foobar."));
385 assert(!hostname_is_valid(".foobar"));
386 assert(!hostname_is_valid("foo..bar"));
387 assert(!hostname_is_valid("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"));
390 static void test_u64log2(void) {
391 assert(u64log2(0) == 0);
392 assert(u64log2(8) == 3);
393 assert(u64log2(9) == 3);
394 assert(u64log2(15) == 3);
395 assert(u64log2(16) == 4);
396 assert(u64log2(1024*1024) == 20);
397 assert(u64log2(1024*1024+5) == 20);
400 static void test_get_process_comm(void) {
401 _cleanup_free_ char *a = NULL, *c = NULL, *d = NULL, *f = NULL, *i = NULL;
402 unsigned long long b;
409 assert_se(get_process_comm(1, &a) >= 0);
410 log_info("pid1 comm: '%s'", a);
412 assert_se(get_starttime_of_pid(1, &b) >= 0);
413 log_info("pid1 starttime: '%llu'", b);
415 assert_se(get_process_cmdline(1, 0, true, &c) >= 0);
416 log_info("pid1 cmdline: '%s'", c);
418 assert_se(get_process_cmdline(1, 8, false, &d) >= 0);
419 log_info("pid1 cmdline truncated: '%s'", d);
421 assert_se(get_parent_of_pid(1, &e) >= 0);
422 log_info("pid1 ppid: '%llu'", (unsigned long long) e);
425 assert_se(is_kernel_thread(1) == 0);
427 r = get_process_exe(1, &f);
428 assert_se(r >= 0 || r == -EACCES);
429 log_info("pid1 exe: '%s'", strna(f));
431 assert_se(get_process_uid(1, &u) == 0);
432 log_info("pid1 uid: '%llu'", (unsigned long long) u);
435 assert_se(get_process_gid(1, &g) == 0);
436 log_info("pid1 gid: '%llu'", (unsigned long long) g);
439 assert(get_ctty_devnr(1, &h) == -ENOENT);
441 getenv_for_pid(1, "PATH", &i);
442 log_info("pid1 $PATH: '%s'", strna(i));
445 static void test_protect_errno(void) {
454 static void test_parse_bytes(void) {
457 assert_se(parse_bytes("111", &bytes) == 0);
458 assert_se(bytes == 111);
460 assert_se(parse_bytes(" 112 B", &bytes) == 0);
461 assert_se(bytes == 112);
463 assert_se(parse_bytes("3 K", &bytes) == 0);
464 assert_se(bytes == 3*1024);
466 assert_se(parse_bytes(" 4 M 11K", &bytes) == 0);
467 assert_se(bytes == 4*1024*1024 + 11 * 1024);
469 assert_se(parse_bytes("3B3G", &bytes) == 0);
470 assert_se(bytes == 3ULL*1024*1024*1024 + 3);
472 assert_se(parse_bytes("3B3G4T", &bytes) == 0);
473 assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
475 assert_se(parse_bytes("12P", &bytes) == 0);
476 assert_se(bytes == 12ULL * 1024*1024*1024*1024*1024);
478 assert_se(parse_bytes("3E 2P", &bytes) == 0);
479 assert_se(bytes == (3 * 1024 + 2ULL) * 1024*1024*1024*1024*1024);
481 assert_se(parse_bytes("12X", &bytes) == -EINVAL);
483 assert_se(parse_bytes("1024E", &bytes) == -ERANGE);
484 assert_se(parse_bytes("-1", &bytes) == -ERANGE);
485 assert_se(parse_bytes("-1024E", &bytes) == -ERANGE);
487 assert_se(parse_bytes("-1024P", &bytes) == -ERANGE);
489 assert_se(parse_bytes("-10B 20K", &bytes) == -ERANGE);
492 static void test_strextend(void) {
493 _cleanup_free_ char *str = strdup("0123");
494 strextend(&str, "456", "78", "9", NULL);
495 assert_se(streq(str, "0123456789"));
498 static void test_strrep(void) {
499 _cleanup_free_ char *one, *three, *zero;
500 one = strrep("waldo", 1);
501 three = strrep("waldo", 3);
502 zero = strrep("waldo", 0);
504 assert_se(streq(one, "waldo"));
505 assert_se(streq(three, "waldowaldowaldo"));
506 assert_se(streq(zero, ""));
509 static void test_parse_user_at_host(void) {
510 _cleanup_free_ char *both = strdup("waldo@waldoscomputer");
511 _cleanup_free_ char *onlyhost = strdup("mikescomputer");
512 char *user = NULL, *host = NULL;
514 parse_user_at_host(both, &user, &host);
515 assert_se(streq(user, "waldo"));
516 assert_se(streq(host, "waldoscomputer"));
519 parse_user_at_host(onlyhost, &user, &host);
520 assert_se(user == NULL);
521 assert_se(streq(host, "mikescomputer"));
524 static void test_split_pair(void) {
525 _cleanup_free_ char *a = NULL, *b = NULL;
527 assert_se(split_pair("", "", &a, &b) == -EINVAL);
528 assert_se(split_pair("foo=bar", "", &a, &b) == -EINVAL);
529 assert_se(split_pair("", "=", &a, &b) == -EINVAL);
530 assert_se(split_pair("foo=bar", "=", &a, &b) >= 0);
531 assert_se(streq(a, "foo"));
532 assert_se(streq(b, "bar"));
535 assert_se(split_pair("==", "==", &a, &b) >= 0);
536 assert_se(streq(a, ""));
537 assert_se(streq(b, ""));
541 assert_se(split_pair("===", "==", &a, &b) >= 0);
542 assert_se(streq(a, ""));
543 assert_se(streq(b, "="));
546 int main(int argc, char *argv[]) {
550 test_parse_boolean();
568 test_foreach_word_quoted();
569 test_default_term_for_tty();
570 test_memdup_multiply();
571 test_bus_path_escape();
572 test_hostname_is_valid();
574 test_get_process_comm();
575 test_protect_errno();
579 test_parse_user_at_host();