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_hostname_is_valid(void) {
355 assert(hostname_is_valid("foobar"));
356 assert(hostname_is_valid("foobar.com"));
357 assert(!hostname_is_valid("fööbar"));
358 assert(!hostname_is_valid(""));
359 assert(!hostname_is_valid("."));
360 assert(!hostname_is_valid(".."));
361 assert(!hostname_is_valid("foobar."));
362 assert(!hostname_is_valid(".foobar"));
363 assert(!hostname_is_valid("foo..bar"));
364 assert(!hostname_is_valid("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"));
367 static void test_u64log2(void) {
368 assert(u64log2(0) == 0);
369 assert(u64log2(8) == 3);
370 assert(u64log2(9) == 3);
371 assert(u64log2(15) == 3);
372 assert(u64log2(16) == 4);
373 assert(u64log2(1024*1024) == 20);
374 assert(u64log2(1024*1024+5) == 20);
377 static void test_get_process_comm(void) {
379 _cleanup_free_ char *a = NULL, *c = NULL, *d = NULL, *f = NULL, *i = NULL;
380 unsigned long long b;
387 if (stat("/proc/1/comm", &st) == 0) {
388 assert_se(get_process_comm(1, &a) >= 0);
389 log_info("pid1 comm: '%s'", a);
391 log_warning("/proc/1/comm does not exist.");
394 assert_se(get_starttime_of_pid(1, &b) >= 0);
395 log_info("pid1 starttime: '%llu'", b);
397 assert_se(get_process_cmdline(1, 0, true, &c) >= 0);
398 log_info("pid1 cmdline: '%s'", c);
400 assert_se(get_process_cmdline(1, 8, false, &d) >= 0);
401 log_info("pid1 cmdline truncated: '%s'", d);
403 assert_se(get_parent_of_pid(1, &e) >= 0);
404 log_info("pid1 ppid: '%llu'", (unsigned long long) e);
407 assert_se(is_kernel_thread(1) == 0);
409 r = get_process_exe(1, &f);
410 assert_se(r >= 0 || r == -EACCES);
411 log_info("pid1 exe: '%s'", strna(f));
413 assert_se(get_process_uid(1, &u) == 0);
414 log_info("pid1 uid: '%llu'", (unsigned long long) u);
417 assert_se(get_process_gid(1, &g) == 0);
418 log_info("pid1 gid: '%llu'", (unsigned long long) g);
421 assert(get_ctty_devnr(1, &h) == -ENOENT);
423 getenv_for_pid(1, "PATH", &i);
424 log_info("pid1 $PATH: '%s'", strna(i));
427 static void test_protect_errno(void) {
436 static void test_parse_bytes(void) {
439 assert_se(parse_bytes("111", &bytes) == 0);
440 assert_se(bytes == 111);
442 assert_se(parse_bytes(" 112 B", &bytes) == 0);
443 assert_se(bytes == 112);
445 assert_se(parse_bytes("3 K", &bytes) == 0);
446 assert_se(bytes == 3*1024);
448 assert_se(parse_bytes(" 4 M 11K", &bytes) == 0);
449 assert_se(bytes == 4*1024*1024 + 11 * 1024);
451 assert_se(parse_bytes("3B3G", &bytes) == 0);
452 assert_se(bytes == 3ULL*1024*1024*1024 + 3);
454 assert_se(parse_bytes("3B3G4T", &bytes) == 0);
455 assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
457 assert_se(parse_bytes("12P", &bytes) == 0);
458 assert_se(bytes == 12ULL * 1024*1024*1024*1024*1024);
460 assert_se(parse_bytes("3E 2P", &bytes) == 0);
461 assert_se(bytes == (3 * 1024 + 2ULL) * 1024*1024*1024*1024*1024);
463 assert_se(parse_bytes("12X", &bytes) == -EINVAL);
465 assert_se(parse_bytes("1024E", &bytes) == -ERANGE);
466 assert_se(parse_bytes("-1", &bytes) == -ERANGE);
467 assert_se(parse_bytes("-1024E", &bytes) == -ERANGE);
469 assert_se(parse_bytes("-1024P", &bytes) == -ERANGE);
471 assert_se(parse_bytes("-10B 20K", &bytes) == -ERANGE);
474 static void test_strextend(void) {
475 _cleanup_free_ char *str = strdup("0123");
476 strextend(&str, "456", "78", "9", NULL);
477 assert_se(streq(str, "0123456789"));
480 static void test_strrep(void) {
481 _cleanup_free_ char *one, *three, *zero;
482 one = strrep("waldo", 1);
483 three = strrep("waldo", 3);
484 zero = strrep("waldo", 0);
486 assert_se(streq(one, "waldo"));
487 assert_se(streq(three, "waldowaldowaldo"));
488 assert_se(streq(zero, ""));
491 static void test_parse_user_at_host(void) {
492 _cleanup_free_ char *both = strdup("waldo@waldoscomputer");
493 _cleanup_free_ char *onlyhost = strdup("mikescomputer");
494 char *user = NULL, *host = NULL;
496 parse_user_at_host(both, &user, &host);
497 assert_se(streq(user, "waldo"));
498 assert_se(streq(host, "waldoscomputer"));
501 parse_user_at_host(onlyhost, &user, &host);
502 assert_se(user == NULL);
503 assert_se(streq(host, "mikescomputer"));
506 static void test_split_pair(void) {
507 _cleanup_free_ char *a = NULL, *b = NULL;
509 assert_se(split_pair("", "", &a, &b) == -EINVAL);
510 assert_se(split_pair("foo=bar", "", &a, &b) == -EINVAL);
511 assert_se(split_pair("", "=", &a, &b) == -EINVAL);
512 assert_se(split_pair("foo=bar", "=", &a, &b) >= 0);
513 assert_se(streq(a, "foo"));
514 assert_se(streq(b, "bar"));
517 assert_se(split_pair("==", "==", &a, &b) >= 0);
518 assert_se(streq(a, ""));
519 assert_se(streq(b, ""));
523 assert_se(split_pair("===", "==", &a, &b) >= 0);
524 assert_se(streq(a, ""));
525 assert_se(streq(b, "="));
528 static void test_fstab_node_to_udev_node(void) {
531 n = fstab_node_to_udev_node("LABEL=applé/jack");
533 assert_se(streq(n, "/dev/disk/by-label/applé\\x2fjack"));
536 n = fstab_node_to_udev_node("PARTLABEL=pinkié pie");
538 assert_se(streq(n, "/dev/disk/by-partlabel/pinkié\\x20pie"));
541 n = fstab_node_to_udev_node("UUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
543 assert_se(streq(n, "/dev/disk/by-uuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
546 n = fstab_node_to_udev_node("PARTUUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
548 assert_se(streq(n, "/dev/disk/by-partuuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
552 n = fstab_node_to_udev_node("PONIES=awesome");
554 assert_se(streq(n, "PONIES=awesome"));
557 n = fstab_node_to_udev_node("/dev/xda1");
559 assert_se(streq(n, "/dev/xda1"));
563 static void test_get_files_in_directory(void) {
564 _cleanup_strv_free_ char **l = NULL, **t = NULL;
566 assert_se(get_files_in_directory("/tmp", &l) >= 0);
567 assert_se(get_files_in_directory(".", &t) >= 0);
568 assert_se(get_files_in_directory(".", NULL) >= 0);
571 static void test_in_set(void) {
572 assert_se(IN_SET(1, 1));
573 assert_se(IN_SET(1, 1, 2, 3, 4));
574 assert_se(IN_SET(2, 1, 2, 3, 4));
575 assert_se(IN_SET(3, 1, 2, 3, 4));
576 assert_se(IN_SET(4, 1, 2, 3, 4));
577 assert_se(!IN_SET(0, 1));
578 assert_se(!IN_SET(0, 1, 2, 3, 4));
581 int main(int argc, char *argv[]) {
585 test_parse_boolean();
603 test_foreach_word_quoted();
604 test_default_term_for_tty();
605 test_memdup_multiply();
606 test_hostname_is_valid();
608 test_get_process_comm();
609 test_protect_errno();
613 test_parse_user_at_host();
615 test_fstab_node_to_udev_node();
616 test_get_files_in_directory();