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_parse_user_at_host(void) {
494 _cleanup_free_ char *both = strdup("waldo@waldoscomputer");
495 _cleanup_free_ char *onlyhost = strdup("mikescomputer");
496 char *user = NULL, *host = NULL;
498 parse_user_at_host(both, &user, &host);
499 assert_se(streq(user, "waldo"));
500 assert_se(streq(host, "waldoscomputer"));
503 parse_user_at_host(onlyhost, &user, &host);
504 assert_se(user == NULL);
505 assert_se(streq(host, "mikescomputer"));
508 static void test_split_pair(void) {
509 _cleanup_free_ char *a = NULL, *b = NULL;
511 assert_se(split_pair("", "", &a, &b) == -EINVAL);
512 assert_se(split_pair("foo=bar", "", &a, &b) == -EINVAL);
513 assert_se(split_pair("", "=", &a, &b) == -EINVAL);
514 assert_se(split_pair("foo=bar", "=", &a, &b) >= 0);
515 assert_se(streq(a, "foo"));
516 assert_se(streq(b, "bar"));
519 assert_se(split_pair("==", "==", &a, &b) >= 0);
520 assert_se(streq(a, ""));
521 assert_se(streq(b, ""));
525 assert_se(split_pair("===", "==", &a, &b) >= 0);
526 assert_se(streq(a, ""));
527 assert_se(streq(b, "="));
530 static void test_fstab_node_to_udev_node(void) {
533 n = fstab_node_to_udev_node("LABEL=applé/jack");
535 assert_se(streq(n, "/dev/disk/by-label/applé\\x2fjack"));
538 n = fstab_node_to_udev_node("PARTLABEL=pinkié pie");
540 assert_se(streq(n, "/dev/disk/by-partlabel/pinkié\\x20pie"));
543 n = fstab_node_to_udev_node("UUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
545 assert_se(streq(n, "/dev/disk/by-uuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
548 n = fstab_node_to_udev_node("PARTUUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
550 assert_se(streq(n, "/dev/disk/by-partuuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
554 n = fstab_node_to_udev_node("PONIES=awesome");
556 assert_se(streq(n, "PONIES=awesome"));
559 n = fstab_node_to_udev_node("/dev/xda1");
561 assert_se(streq(n, "/dev/xda1"));
565 static void test_get_files_in_directory(void) {
566 _cleanup_strv_free_ char **l = NULL, **t = NULL;
568 assert_se(get_files_in_directory("/tmp", &l) >= 0);
569 assert_se(get_files_in_directory(".", &t) >= 0);
570 assert_se(get_files_in_directory(".", NULL) >= 0);
573 static void test_in_set(void) {
574 assert_se(IN_SET(1, 1));
575 assert_se(IN_SET(1, 1, 2, 3, 4));
576 assert_se(IN_SET(2, 1, 2, 3, 4));
577 assert_se(IN_SET(3, 1, 2, 3, 4));
578 assert_se(IN_SET(4, 1, 2, 3, 4));
579 assert_se(!IN_SET(0, 1));
580 assert_se(!IN_SET(0, 1, 2, 3, 4));
583 static void test_writing_tmpfile(void) {
584 char name[] = "/tmp/test-systemd_writing_tmpfile.XXXXXX";
585 _cleanup_free_ char *contents;
590 IOVEC_SET_STRING(iov[0], "abc\n");
591 IOVEC_SET_STRING(iov[1], ALPHANUMERICAL "\n");
592 IOVEC_SET_STRING(iov[2], "");
594 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
595 printf("tmpfile: %s", name);
597 r = writev(fd, iov, 3);
600 r = read_full_file(name, &contents, &size);
602 printf("contents: %s", contents);
603 assert(streq(contents, "abc\n" ALPHANUMERICAL "\n"));
606 int main(int argc, char *argv[]) {
610 test_parse_boolean();
628 test_foreach_word_quoted();
629 test_default_term_for_tty();
630 test_memdup_multiply();
631 test_hostname_is_valid();
633 test_get_process_comm();
634 test_protect_errno();
638 test_parse_user_at_host();
640 test_fstab_node_to_udev_node();
641 test_get_files_in_directory();
643 test_writing_tmpfile();