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/>.
34 static void test_streq_ptr(void) {
35 assert_se(streq_ptr(NULL, NULL));
36 assert_se(!streq_ptr("abc", "cdef"));
39 static void test_first_word(void) {
40 assert_se(first_word("Hello", ""));
41 assert_se(first_word("Hello", "Hello"));
42 assert_se(first_word("Hello world", "Hello"));
43 assert_se(first_word("Hello\tworld", "Hello"));
44 assert_se(first_word("Hello\nworld", "Hello"));
45 assert_se(first_word("Hello\rworld", "Hello"));
46 assert_se(first_word("Hello ", "Hello"));
48 assert_se(!first_word("Hello", "Hellooo"));
49 assert_se(!first_word("Hello", "xxxxx"));
50 assert_se(!first_word("Hellooo", "Hello"));
53 static void test_close_many(void) {
55 char name0[] = "/tmp/test-close-many.XXXXXX";
56 char name1[] = "/tmp/test-close-many.XXXXXX";
57 char name2[] = "/tmp/test-close-many.XXXXXX";
59 fds[0] = mkostemp_safe(name0, O_RDWR|O_CLOEXEC);
60 fds[1] = mkostemp_safe(name1, O_RDWR|O_CLOEXEC);
61 fds[2] = mkostemp_safe(name2, O_RDWR|O_CLOEXEC);
65 assert_se(fcntl(fds[0], F_GETFD) == -1);
66 assert_se(fcntl(fds[1], F_GETFD) == -1);
67 assert_se(fcntl(fds[2], F_GETFD) >= 0);
69 close_nointr_nofail(fds[2]);
76 static void test_parse_boolean(void) {
77 assert_se(parse_boolean("1") == 1);
78 assert_se(parse_boolean("y") == 1);
79 assert_se(parse_boolean("Y") == 1);
80 assert_se(parse_boolean("yes") == 1);
81 assert_se(parse_boolean("YES") == 1);
82 assert_se(parse_boolean("true") == 1);
83 assert_se(parse_boolean("TRUE") == 1);
84 assert_se(parse_boolean("on") == 1);
85 assert_se(parse_boolean("ON") == 1);
87 assert_se(parse_boolean("0") == 0);
88 assert_se(parse_boolean("n") == 0);
89 assert_se(parse_boolean("N") == 0);
90 assert_se(parse_boolean("no") == 0);
91 assert_se(parse_boolean("NO") == 0);
92 assert_se(parse_boolean("false") == 0);
93 assert_se(parse_boolean("FALSE") == 0);
94 assert_se(parse_boolean("off") == 0);
95 assert_se(parse_boolean("OFF") == 0);
97 assert_se(parse_boolean("garbage") < 0);
98 assert_se(parse_boolean("") < 0);
101 static void test_parse_pid(void) {
105 r = parse_pid("100", &pid);
107 assert_se(pid == 100);
109 r = parse_pid("0x7FFFFFFF", &pid);
111 assert_se(pid == 2147483647);
113 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
114 r = parse_pid("0", &pid);
115 assert_se(r == -ERANGE);
116 assert_se(pid == 65);
118 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
119 r = parse_pid("-100", &pid);
120 assert_se(r == -ERANGE);
121 assert_se(pid == 65);
123 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
124 r = parse_pid("0xFFFFFFFFFFFFFFFFF", &pid);
125 assert(r == -ERANGE);
126 assert_se(pid == 65);
129 static void test_parse_uid(void) {
133 r = parse_uid("100", &uid);
135 assert_se(uid == 100);
138 static void test_safe_atolli(void) {
142 r = safe_atolli("12345", &l);
144 assert_se(l == 12345);
146 r = safe_atolli("junk", &l);
147 assert_se(r == -EINVAL);
150 static void test_safe_atod(void) {
155 r = safe_atod("junk", &d);
156 assert_se(r == -EINVAL);
158 r = safe_atod("0.2244", &d);
160 assert_se(abs(d - 0.2244) < 0.000001);
162 r = safe_atod("0,5", &d);
163 assert_se(r == -EINVAL);
167 assert_se(*e == ',');
169 /* Check if this really is locale independent */
170 setlocale(LC_NUMERIC, "de_DE.utf8");
172 r = safe_atod("0.2244", &d);
174 assert_se(abs(d - 0.2244) < 0.000001);
176 r = safe_atod("0,5", &d);
177 assert_se(r == -EINVAL);
180 assert_se(abs(strtod("0,5", &e) - 0.5) < 0.00001);
182 /* And check again, reset */
183 setlocale(LC_NUMERIC, "C");
185 r = safe_atod("0.2244", &d);
187 assert_se(abs(d - 0.2244) < 0.000001);
189 r = safe_atod("0,5", &d);
190 assert_se(r == -EINVAL);
194 assert_se(*e == ',');
197 static void test_strappend(void) {
198 _cleanup_free_ char *t1, *t2, *t3, *t4;
200 t1 = strappend(NULL, NULL);
201 assert_se(streq(t1, ""));
203 t2 = strappend(NULL, "suf");
204 assert_se(streq(t2, "suf"));
206 t3 = strappend("pre", NULL);
207 assert_se(streq(t3, "pre"));
209 t4 = strappend("pre", "suf");
210 assert_se(streq(t4, "presuf"));
213 static void test_strstrip(void) {
215 char input[] = " hello, waldo. ";
218 assert_se(streq(r, "hello, waldo."));
221 static void test_delete_chars(void) {
223 char input[] = " hello, waldo. abc";
225 r = delete_chars(input, WHITESPACE);
226 assert_se(streq(r, "hello,waldo.abc"));
229 static void test_in_charset(void) {
230 assert_se(in_charset("dddaaabbbcccc", "abcd"));
231 assert_se(!in_charset("dddaaabbbcccc", "abc f"));
234 static void test_hexchar(void) {
235 assert_se(hexchar(0xa) == 'a');
236 assert_se(hexchar(0x0) == '0');
239 static void test_unhexchar(void) {
240 assert_se(unhexchar('a') == 0xA);
241 assert_se(unhexchar('A') == 0xA);
242 assert_se(unhexchar('0') == 0x0);
245 static void test_octchar(void) {
246 assert_se(octchar(00) == '0');
247 assert_se(octchar(07) == '7');
250 static void test_unoctchar(void) {
251 assert_se(unoctchar('0') == 00);
252 assert_se(unoctchar('7') == 07);
255 static void test_decchar(void) {
256 assert_se(decchar(0) == '0');
257 assert_se(decchar(9) == '9');
260 static void test_undecchar(void) {
261 assert_se(undecchar('0') == 0);
262 assert_se(undecchar('9') == 9);
265 static void test_cescape(void) {
266 _cleanup_free_ char *escaped;
267 escaped = cescape("abc\\\"\b\f\n\r\t\v\003\177\234\313");
268 assert_se(streq(escaped, "abc\\\\\\\"\\b\\f\\n\\r\\t\\v\\003\\177\\234\\313"));
271 static void test_cunescape(void) {
272 _cleanup_free_ char *unescaped;
273 unescaped = cunescape("abc\\\\\\\"\\b\\f\\n\\r\\t\\v\\003\\177\\234\\313");
274 assert_se(streq(unescaped, "abc\\\"\b\f\n\r\t\v\003\177\234\313"));
277 static void test_foreach_word(void) {
281 const char test[] = "test abc d\te f ";
282 const char * const expected[] = {
292 FOREACH_WORD(w, l, test, state) {
293 assert_se(strneq(expected[i++], w, l));
297 static void test_foreach_word_quoted(void) {
301 const char test[] = "test a b c 'd' e '' '' hhh '' '' \"a b c\"";
302 const char * const expected[] = {
318 printf("<%s>\n", test);
319 FOREACH_WORD_QUOTED(w, l, test, state) {
320 _cleanup_free_ char *t = NULL;
322 assert_se(t = strndup(w, l));
323 assert_se(strneq(expected[i++], w, l));
328 static void test_default_term_for_tty(void) {
329 puts(default_term_for_tty("/dev/tty23"));
330 puts(default_term_for_tty("/dev/ttyS23"));
331 puts(default_term_for_tty("/dev/tty0"));
332 puts(default_term_for_tty("/dev/pty0"));
333 puts(default_term_for_tty("/dev/pts/0"));
334 puts(default_term_for_tty("/dev/console"));
335 puts(default_term_for_tty("tty23"));
336 puts(default_term_for_tty("ttyS23"));
337 puts(default_term_for_tty("tty0"));
338 puts(default_term_for_tty("pty0"));
339 puts(default_term_for_tty("pts/0"));
340 puts(default_term_for_tty("console"));
343 static void test_memdup_multiply(void) {
344 int org[] = {1, 2, 3};
347 dup = (int*)memdup_multiply(org, sizeof(int), 3);
350 assert_se(dup[0] == 1);
351 assert_se(dup[1] == 2);
352 assert_se(dup[2] == 3);
356 static void test_hostname_is_valid(void) {
357 assert(hostname_is_valid("foobar"));
358 assert(hostname_is_valid("foobar.com"));
359 assert(!hostname_is_valid("fööbar"));
360 assert(!hostname_is_valid(""));
361 assert(!hostname_is_valid("."));
362 assert(!hostname_is_valid(".."));
363 assert(!hostname_is_valid("foobar."));
364 assert(!hostname_is_valid(".foobar"));
365 assert(!hostname_is_valid("foo..bar"));
366 assert(!hostname_is_valid("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"));
369 static void test_u64log2(void) {
370 assert(u64log2(0) == 0);
371 assert(u64log2(8) == 3);
372 assert(u64log2(9) == 3);
373 assert(u64log2(15) == 3);
374 assert(u64log2(16) == 4);
375 assert(u64log2(1024*1024) == 20);
376 assert(u64log2(1024*1024+5) == 20);
379 static void test_get_process_comm(void) {
381 _cleanup_free_ char *a = NULL, *c = NULL, *d = NULL, *f = NULL, *i = NULL;
382 unsigned long long b;
389 if (stat("/proc/1/comm", &st) == 0) {
390 assert_se(get_process_comm(1, &a) >= 0);
391 log_info("pid1 comm: '%s'", a);
393 log_warning("/proc/1/comm does not exist.");
396 assert_se(get_starttime_of_pid(1, &b) >= 0);
397 log_info("pid1 starttime: '%llu'", b);
399 assert_se(get_process_cmdline(1, 0, true, &c) >= 0);
400 log_info("pid1 cmdline: '%s'", c);
402 assert_se(get_process_cmdline(1, 8, false, &d) >= 0);
403 log_info("pid1 cmdline truncated: '%s'", d);
405 assert_se(get_parent_of_pid(1, &e) >= 0);
406 log_info("pid1 ppid: '%llu'", (unsigned long long) e);
409 assert_se(is_kernel_thread(1) == 0);
411 r = get_process_exe(1, &f);
412 assert_se(r >= 0 || r == -EACCES);
413 log_info("pid1 exe: '%s'", strna(f));
415 assert_se(get_process_uid(1, &u) == 0);
416 log_info("pid1 uid: '%llu'", (unsigned long long) u);
419 assert_se(get_process_gid(1, &g) == 0);
420 log_info("pid1 gid: '%llu'", (unsigned long long) g);
423 assert(get_ctty_devnr(1, &h) == -ENOENT);
425 getenv_for_pid(1, "PATH", &i);
426 log_info("pid1 $PATH: '%s'", strna(i));
429 static void test_protect_errno(void) {
438 static void test_parse_bytes(void) {
441 assert_se(parse_bytes("111", &bytes) == 0);
442 assert_se(bytes == 111);
444 assert_se(parse_bytes(" 112 B", &bytes) == 0);
445 assert_se(bytes == 112);
447 assert_se(parse_bytes("3 K", &bytes) == 0);
448 assert_se(bytes == 3*1024);
450 assert_se(parse_bytes(" 4 M 11K", &bytes) == 0);
451 assert_se(bytes == 4*1024*1024 + 11 * 1024);
453 assert_se(parse_bytes("3B3G", &bytes) == 0);
454 assert_se(bytes == 3ULL*1024*1024*1024 + 3);
456 assert_se(parse_bytes("3B3G4T", &bytes) == 0);
457 assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
459 assert_se(parse_bytes("12P", &bytes) == 0);
460 assert_se(bytes == 12ULL * 1024*1024*1024*1024*1024);
462 assert_se(parse_bytes("3E 2P", &bytes) == 0);
463 assert_se(bytes == (3 * 1024 + 2ULL) * 1024*1024*1024*1024*1024);
465 assert_se(parse_bytes("12X", &bytes) == -EINVAL);
467 assert_se(parse_bytes("1024E", &bytes) == -ERANGE);
468 assert_se(parse_bytes("-1", &bytes) == -ERANGE);
469 assert_se(parse_bytes("-1024E", &bytes) == -ERANGE);
471 assert_se(parse_bytes("-1024P", &bytes) == -ERANGE);
473 assert_se(parse_bytes("-10B 20K", &bytes) == -ERANGE);
476 static void test_strextend(void) {
477 _cleanup_free_ char *str = strdup("0123");
478 strextend(&str, "456", "78", "9", NULL);
479 assert_se(streq(str, "0123456789"));
482 static void test_strrep(void) {
483 _cleanup_free_ char *one, *three, *zero;
484 one = strrep("waldo", 1);
485 three = strrep("waldo", 3);
486 zero = strrep("waldo", 0);
488 assert_se(streq(one, "waldo"));
489 assert_se(streq(three, "waldowaldowaldo"));
490 assert_se(streq(zero, ""));
493 static void test_split_pair(void) {
494 _cleanup_free_ char *a = NULL, *b = NULL;
496 assert_se(split_pair("", "", &a, &b) == -EINVAL);
497 assert_se(split_pair("foo=bar", "", &a, &b) == -EINVAL);
498 assert_se(split_pair("", "=", &a, &b) == -EINVAL);
499 assert_se(split_pair("foo=bar", "=", &a, &b) >= 0);
500 assert_se(streq(a, "foo"));
501 assert_se(streq(b, "bar"));
504 assert_se(split_pair("==", "==", &a, &b) >= 0);
505 assert_se(streq(a, ""));
506 assert_se(streq(b, ""));
510 assert_se(split_pair("===", "==", &a, &b) >= 0);
511 assert_se(streq(a, ""));
512 assert_se(streq(b, "="));
515 static void test_fstab_node_to_udev_node(void) {
518 n = fstab_node_to_udev_node("LABEL=applé/jack");
520 assert_se(streq(n, "/dev/disk/by-label/applé\\x2fjack"));
523 n = fstab_node_to_udev_node("PARTLABEL=pinkié pie");
525 assert_se(streq(n, "/dev/disk/by-partlabel/pinkié\\x20pie"));
528 n = fstab_node_to_udev_node("UUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
530 assert_se(streq(n, "/dev/disk/by-uuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
533 n = fstab_node_to_udev_node("PARTUUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
535 assert_se(streq(n, "/dev/disk/by-partuuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
539 n = fstab_node_to_udev_node("PONIES=awesome");
541 assert_se(streq(n, "PONIES=awesome"));
544 n = fstab_node_to_udev_node("/dev/xda1");
546 assert_se(streq(n, "/dev/xda1"));
550 static void test_get_files_in_directory(void) {
551 _cleanup_strv_free_ char **l = NULL, **t = NULL;
553 assert_se(get_files_in_directory("/tmp", &l) >= 0);
554 assert_se(get_files_in_directory(".", &t) >= 0);
555 assert_se(get_files_in_directory(".", NULL) >= 0);
558 static void test_in_set(void) {
559 assert_se(IN_SET(1, 1));
560 assert_se(IN_SET(1, 1, 2, 3, 4));
561 assert_se(IN_SET(2, 1, 2, 3, 4));
562 assert_se(IN_SET(3, 1, 2, 3, 4));
563 assert_se(IN_SET(4, 1, 2, 3, 4));
564 assert_se(!IN_SET(0, 1));
565 assert_se(!IN_SET(0, 1, 2, 3, 4));
568 static void test_writing_tmpfile(void) {
569 char name[] = "/tmp/test-systemd_writing_tmpfile.XXXXXX";
570 _cleanup_free_ char *contents = NULL;
575 IOVEC_SET_STRING(iov[0], "abc\n");
576 IOVEC_SET_STRING(iov[1], ALPHANUMERICAL "\n");
577 IOVEC_SET_STRING(iov[2], "");
579 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
580 printf("tmpfile: %s", name);
582 r = writev(fd, iov, 3);
585 r = read_full_file(name, &contents, &size);
587 printf("contents: %s", contents);
588 assert(streq(contents, "abc\n" ALPHANUMERICAL "\n"));
591 int main(int argc, char *argv[]) {
595 test_parse_boolean();
613 test_foreach_word_quoted();
614 test_default_term_for_tty();
615 test_memdup_multiply();
616 test_hostname_is_valid();
618 test_get_process_comm();
619 test_protect_errno();
624 test_fstab_node_to_udev_node();
625 test_get_files_in_directory();
627 test_writing_tmpfile();