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/>.
32 static void test_streq_ptr(void) {
33 assert_se(streq_ptr(NULL, NULL));
34 assert_se(!streq_ptr("abc", "cdef"));
37 static void test_first_word(void) {
38 assert_se(first_word("Hello", ""));
39 assert_se(first_word("Hello", "Hello"));
40 assert_se(first_word("Hello world", "Hello"));
41 assert_se(first_word("Hello\tworld", "Hello"));
42 assert_se(first_word("Hello\nworld", "Hello"));
43 assert_se(first_word("Hello\rworld", "Hello"));
44 assert_se(first_word("Hello ", "Hello"));
46 assert_se(!first_word("Hello", "Hellooo"));
47 assert_se(!first_word("Hello", "xxxxx"));
48 assert_se(!first_word("Hellooo", "Hello"));
51 static void test_close_many(void) {
53 char name0[] = "/tmp/test-close-many.XXXXXX";
54 char name1[] = "/tmp/test-close-many.XXXXXX";
55 char name2[] = "/tmp/test-close-many.XXXXXX";
57 fds[0] = mkstemp(name0);
58 fds[1] = mkstemp(name1);
59 fds[2] = mkstemp(name2);
63 assert_se(fcntl(fds[0], F_GETFD) == -1);
64 assert_se(fcntl(fds[1], F_GETFD) == -1);
65 assert_se(fcntl(fds[2], F_GETFD) >= 0);
67 close_nointr_nofail(fds[2]);
74 static void test_parse_boolean(void) {
75 assert_se(parse_boolean("1") == 1);
76 assert_se(parse_boolean("y") == 1);
77 assert_se(parse_boolean("Y") == 1);
78 assert_se(parse_boolean("yes") == 1);
79 assert_se(parse_boolean("YES") == 1);
80 assert_se(parse_boolean("true") == 1);
81 assert_se(parse_boolean("TRUE") == 1);
82 assert_se(parse_boolean("on") == 1);
83 assert_se(parse_boolean("ON") == 1);
85 assert_se(parse_boolean("0") == 0);
86 assert_se(parse_boolean("n") == 0);
87 assert_se(parse_boolean("N") == 0);
88 assert_se(parse_boolean("no") == 0);
89 assert_se(parse_boolean("NO") == 0);
90 assert_se(parse_boolean("false") == 0);
91 assert_se(parse_boolean("FALSE") == 0);
92 assert_se(parse_boolean("off") == 0);
93 assert_se(parse_boolean("OFF") == 0);
95 assert_se(parse_boolean("garbage") < 0);
96 assert_se(parse_boolean("") < 0);
99 static void test_parse_pid(void) {
103 r = parse_pid("100", &pid);
105 assert_se(pid == 100);
107 r = parse_pid("0x7FFFFFFF", &pid);
109 assert_se(pid == 2147483647);
111 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
112 r = parse_pid("0", &pid);
113 assert_se(r == -ERANGE);
114 assert_se(pid == 65);
116 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
117 r = parse_pid("-100", &pid);
118 assert_se(r == -ERANGE);
119 assert_se(pid == 65);
121 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
122 r = parse_pid("0xFFFFFFFFFFFFFFFFF", &pid);
123 assert(r == -ERANGE);
124 assert_se(pid == 65);
127 static void test_parse_uid(void) {
131 r = parse_uid("100", &uid);
133 assert_se(uid == 100);
136 static void test_safe_atolli(void) {
140 r = safe_atolli("12345", &l);
142 assert_se(l == 12345);
144 r = safe_atolli("junk", &l);
145 assert_se(r == -EINVAL);
148 static void test_safe_atod(void) {
153 r = safe_atod("junk", &d);
154 assert_se(r == -EINVAL);
156 r = safe_atod("0.2244", &d);
158 assert_se(abs(d - 0.2244) < 0.000001);
160 r = safe_atod("0,5", &d);
161 assert_se(r == -EINVAL);
165 assert_se(*e == ',');
167 /* Check if this really is locale independent */
168 setlocale(LC_NUMERIC, "de_DE.utf8");
170 r = safe_atod("0.2244", &d);
172 assert_se(abs(d - 0.2244) < 0.000001);
174 r = safe_atod("0,5", &d);
175 assert_se(r == -EINVAL);
178 assert_se(abs(strtod("0,5", &e) - 0.5) < 0.00001);
180 /* And check again, reset */
181 setlocale(LC_NUMERIC, "C");
183 r = safe_atod("0.2244", &d);
185 assert_se(abs(d - 0.2244) < 0.000001);
187 r = safe_atod("0,5", &d);
188 assert_se(r == -EINVAL);
192 assert_se(*e == ',');
195 static void test_strappend(void) {
196 _cleanup_free_ char *t1, *t2, *t3, *t4;
198 t1 = strappend(NULL, NULL);
199 assert_se(streq(t1, ""));
201 t2 = strappend(NULL, "suf");
202 assert_se(streq(t2, "suf"));
204 t3 = strappend("pre", NULL);
205 assert_se(streq(t3, "pre"));
207 t4 = strappend("pre", "suf");
208 assert_se(streq(t4, "presuf"));
211 static void test_strstrip(void) {
213 char input[] = " hello, waldo. ";
216 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) {
402 _cleanup_free_ char *a = NULL, *c = NULL, *d = NULL, *f = NULL, *i = NULL;
403 unsigned long long b;
410 if (stat("/proc/1/comm", &st) == 0) {
411 assert_se(get_process_comm(1, &a) >= 0);
412 log_info("pid1 comm: '%s'", a);
414 log_warning("/proc/1/comm does not exist.");
417 assert_se(get_starttime_of_pid(1, &b) >= 0);
418 log_info("pid1 starttime: '%llu'", b);
420 assert_se(get_process_cmdline(1, 0, true, &c) >= 0);
421 log_info("pid1 cmdline: '%s'", c);
423 assert_se(get_process_cmdline(1, 8, false, &d) >= 0);
424 log_info("pid1 cmdline truncated: '%s'", d);
426 assert_se(get_parent_of_pid(1, &e) >= 0);
427 log_info("pid1 ppid: '%llu'", (unsigned long long) e);
430 assert_se(is_kernel_thread(1) == 0);
432 r = get_process_exe(1, &f);
433 assert_se(r >= 0 || r == -EACCES);
434 log_info("pid1 exe: '%s'", strna(f));
436 assert_se(get_process_uid(1, &u) == 0);
437 log_info("pid1 uid: '%llu'", (unsigned long long) u);
440 assert_se(get_process_gid(1, &g) == 0);
441 log_info("pid1 gid: '%llu'", (unsigned long long) g);
444 assert(get_ctty_devnr(1, &h) == -ENOENT);
446 getenv_for_pid(1, "PATH", &i);
447 log_info("pid1 $PATH: '%s'", strna(i));
450 static void test_protect_errno(void) {
459 static void test_parse_bytes(void) {
462 assert_se(parse_bytes("111", &bytes) == 0);
463 assert_se(bytes == 111);
465 assert_se(parse_bytes(" 112 B", &bytes) == 0);
466 assert_se(bytes == 112);
468 assert_se(parse_bytes("3 K", &bytes) == 0);
469 assert_se(bytes == 3*1024);
471 assert_se(parse_bytes(" 4 M 11K", &bytes) == 0);
472 assert_se(bytes == 4*1024*1024 + 11 * 1024);
474 assert_se(parse_bytes("3B3G", &bytes) == 0);
475 assert_se(bytes == 3ULL*1024*1024*1024 + 3);
477 assert_se(parse_bytes("3B3G4T", &bytes) == 0);
478 assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
480 assert_se(parse_bytes("12P", &bytes) == 0);
481 assert_se(bytes == 12ULL * 1024*1024*1024*1024*1024);
483 assert_se(parse_bytes("3E 2P", &bytes) == 0);
484 assert_se(bytes == (3 * 1024 + 2ULL) * 1024*1024*1024*1024*1024);
486 assert_se(parse_bytes("12X", &bytes) == -EINVAL);
488 assert_se(parse_bytes("1024E", &bytes) == -ERANGE);
489 assert_se(parse_bytes("-1", &bytes) == -ERANGE);
490 assert_se(parse_bytes("-1024E", &bytes) == -ERANGE);
492 assert_se(parse_bytes("-1024P", &bytes) == -ERANGE);
494 assert_se(parse_bytes("-10B 20K", &bytes) == -ERANGE);
497 static void test_strextend(void) {
498 _cleanup_free_ char *str = strdup("0123");
499 strextend(&str, "456", "78", "9", NULL);
500 assert_se(streq(str, "0123456789"));
503 static void test_strrep(void) {
504 _cleanup_free_ char *one, *three, *zero;
505 one = strrep("waldo", 1);
506 three = strrep("waldo", 3);
507 zero = strrep("waldo", 0);
509 assert_se(streq(one, "waldo"));
510 assert_se(streq(three, "waldowaldowaldo"));
511 assert_se(streq(zero, ""));
514 static void test_parse_user_at_host(void) {
515 _cleanup_free_ char *both = strdup("waldo@waldoscomputer");
516 _cleanup_free_ char *onlyhost = strdup("mikescomputer");
517 char *user = NULL, *host = NULL;
519 parse_user_at_host(both, &user, &host);
520 assert_se(streq(user, "waldo"));
521 assert_se(streq(host, "waldoscomputer"));
524 parse_user_at_host(onlyhost, &user, &host);
525 assert_se(user == NULL);
526 assert_se(streq(host, "mikescomputer"));
529 static void test_split_pair(void) {
530 _cleanup_free_ char *a = NULL, *b = NULL;
532 assert_se(split_pair("", "", &a, &b) == -EINVAL);
533 assert_se(split_pair("foo=bar", "", &a, &b) == -EINVAL);
534 assert_se(split_pair("", "=", &a, &b) == -EINVAL);
535 assert_se(split_pair("foo=bar", "=", &a, &b) >= 0);
536 assert_se(streq(a, "foo"));
537 assert_se(streq(b, "bar"));
540 assert_se(split_pair("==", "==", &a, &b) >= 0);
541 assert_se(streq(a, ""));
542 assert_se(streq(b, ""));
546 assert_se(split_pair("===", "==", &a, &b) >= 0);
547 assert_se(streq(a, ""));
548 assert_se(streq(b, "="));
551 static void test_fstab_node_to_udev_node(void) {
554 n = fstab_node_to_udev_node("LABEL=applé/jack");
556 assert_se(streq(n, "/dev/disk/by-label/applé\\x2fjack"));
559 n = fstab_node_to_udev_node("PARTLABEL=pinkié pie");
561 assert_se(streq(n, "/dev/disk/by-partlabel/pinkié\\x20pie"));
564 n = fstab_node_to_udev_node("UUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
566 assert_se(streq(n, "/dev/disk/by-uuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
569 n = fstab_node_to_udev_node("PARTUUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
571 assert_se(streq(n, "/dev/disk/by-partuuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
575 n = fstab_node_to_udev_node("PONIES=awesome");
577 assert_se(streq(n, "PONIES=awesome"));
580 n = fstab_node_to_udev_node("/dev/xda1");
582 assert_se(streq(n, "/dev/xda1"));
586 static void test_get_files_in_directory(void) {
587 _cleanup_strv_free_ char **l = NULL, **t = NULL;
589 assert_se(get_files_in_directory("/tmp", &l) >= 0);
590 assert_se(get_files_in_directory(".", &t) >= 0);
591 assert_se(get_files_in_directory(".", NULL) >= 0);
594 int main(int argc, char *argv[]) {
598 test_parse_boolean();
616 test_foreach_word_quoted();
617 test_default_term_for_tty();
618 test_memdup_multiply();
619 test_bus_path_escape();
620 test_hostname_is_valid();
622 test_get_process_comm();
623 test_protect_errno();
627 test_parse_user_at_host();
629 test_fstab_node_to_udev_node();
630 test_get_files_in_directory();