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."));
218 static void test_delete_chars(void) {
220 char input[] = " hello, waldo. abc";
222 r = delete_chars(input, WHITESPACE);
223 assert_se(streq(r, "hello,waldo.abc"));
226 static void test_in_charset(void) {
227 assert_se(in_charset("dddaaabbbcccc", "abcd"));
228 assert_se(!in_charset("dddaaabbbcccc", "abc f"));
231 static void test_hexchar(void) {
232 assert_se(hexchar(0xa) == 'a');
233 assert_se(hexchar(0x0) == '0');
236 static void test_unhexchar(void) {
237 assert_se(unhexchar('a') == 0xA);
238 assert_se(unhexchar('A') == 0xA);
239 assert_se(unhexchar('0') == 0x0);
242 static void test_octchar(void) {
243 assert_se(octchar(00) == '0');
244 assert_se(octchar(07) == '7');
247 static void test_unoctchar(void) {
248 assert_se(unoctchar('0') == 00);
249 assert_se(unoctchar('7') == 07);
252 static void test_decchar(void) {
253 assert_se(decchar(0) == '0');
254 assert_se(decchar(9) == '9');
257 static void test_undecchar(void) {
258 assert_se(undecchar('0') == 0);
259 assert_se(undecchar('9') == 9);
262 static void test_cescape(void) {
263 _cleanup_free_ char *escaped;
264 escaped = cescape("abc\\\"\b\f\n\r\t\v\003\177\234\313");
265 assert_se(streq(escaped, "abc\\\\\\\"\\b\\f\\n\\r\\t\\v\\003\\177\\234\\313"));
268 static void test_cunescape(void) {
269 _cleanup_free_ char *unescaped;
270 unescaped = cunescape("abc\\\\\\\"\\b\\f\\n\\r\\t\\v\\003\\177\\234\\313");
271 assert_se(streq(unescaped, "abc\\\"\b\f\n\r\t\v\003\177\234\313"));
274 static void test_foreach_word(void) {
278 const char test[] = "test abc d\te f ";
279 const char * const expected[] = {
289 FOREACH_WORD(w, l, test, state) {
290 assert_se(strneq(expected[i++], w, l));
294 static void test_foreach_word_quoted(void) {
298 const char test[] = "test a b c 'd' e '' '' hhh '' '' \"a b c\"";
299 const char * const expected[] = {
315 printf("<%s>\n", test);
316 FOREACH_WORD_QUOTED(w, l, test, state) {
317 _cleanup_free_ char *t = NULL;
319 assert_se(t = strndup(w, l));
320 assert_se(strneq(expected[i++], w, l));
325 static void test_default_term_for_tty(void) {
326 puts(default_term_for_tty("/dev/tty23"));
327 puts(default_term_for_tty("/dev/ttyS23"));
328 puts(default_term_for_tty("/dev/tty0"));
329 puts(default_term_for_tty("/dev/pty0"));
330 puts(default_term_for_tty("/dev/pts/0"));
331 puts(default_term_for_tty("/dev/console"));
332 puts(default_term_for_tty("tty23"));
333 puts(default_term_for_tty("ttyS23"));
334 puts(default_term_for_tty("tty0"));
335 puts(default_term_for_tty("pty0"));
336 puts(default_term_for_tty("pts/0"));
337 puts(default_term_for_tty("console"));
340 static void test_memdup_multiply(void) {
341 int org[] = {1, 2, 3};
344 dup = (int*)memdup_multiply(org, sizeof(int), 3);
347 assert_se(dup[0] == 1);
348 assert_se(dup[1] == 2);
349 assert_se(dup[2] == 3);
353 static void test_bus_path_escape_one(const char *a, const char *b) {
354 _cleanup_free_ char *t = NULL, *x = NULL, *y = NULL;
356 assert_se(t = bus_path_escape(a));
357 assert_se(streq(t, b));
359 assert_se(x = bus_path_unescape(t));
360 assert_se(streq(a, x));
362 assert_se(y = bus_path_unescape(b));
363 assert_se(streq(a, y));
366 static void test_bus_path_escape(void) {
367 test_bus_path_escape_one("foo123bar", "foo123bar");
368 test_bus_path_escape_one("foo.bar", "foo_2ebar");
369 test_bus_path_escape_one("foo_2ebar", "foo_5f2ebar");
370 test_bus_path_escape_one("", "_");
371 test_bus_path_escape_one("_", "_5f");
372 test_bus_path_escape_one("1", "_31");
373 test_bus_path_escape_one(":1", "_3a1");
376 static void test_hostname_is_valid(void) {
377 assert(hostname_is_valid("foobar"));
378 assert(hostname_is_valid("foobar.com"));
379 assert(!hostname_is_valid("fööbar"));
380 assert(!hostname_is_valid(""));
381 assert(!hostname_is_valid("."));
382 assert(!hostname_is_valid(".."));
383 assert(!hostname_is_valid("foobar."));
384 assert(!hostname_is_valid(".foobar"));
385 assert(!hostname_is_valid("foo..bar"));
386 assert(!hostname_is_valid("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"));
389 static void test_u64log2(void) {
390 assert(u64log2(0) == 0);
391 assert(u64log2(8) == 3);
392 assert(u64log2(9) == 3);
393 assert(u64log2(15) == 3);
394 assert(u64log2(16) == 4);
395 assert(u64log2(1024*1024) == 20);
396 assert(u64log2(1024*1024+5) == 20);
399 static void test_get_process_comm(void) {
400 _cleanup_free_ char *a = NULL, *c = NULL, *d = NULL, *f = NULL, *i = NULL;
401 unsigned long long b;
408 assert_se(get_process_comm(1, &a) >= 0);
409 log_info("pid1 comm: '%s'", a);
411 assert_se(get_starttime_of_pid(1, &b) >= 0);
412 log_info("pid1 starttime: '%llu'", b);
414 assert_se(get_process_cmdline(1, 0, true, &c) >= 0);
415 log_info("pid1 cmdline: '%s'", c);
417 assert_se(get_process_cmdline(1, 8, false, &d) >= 0);
418 log_info("pid1 cmdline truncated: '%s'", d);
420 assert_se(get_parent_of_pid(1, &e) >= 0);
421 log_info("pid1 ppid: '%llu'", (unsigned long long) e);
424 assert_se(is_kernel_thread(1) == 0);
426 r = get_process_exe(1, &f);
427 assert_se(r >= 0 || r == -EACCES);
428 log_info("pid1 exe: '%s'", strna(f));
430 assert_se(get_process_uid(1, &u) == 0);
431 log_info("pid1 uid: '%llu'", (unsigned long long) u);
434 assert_se(get_process_gid(1, &g) == 0);
435 log_info("pid1 gid: '%llu'", (unsigned long long) g);
438 assert(get_ctty_devnr(1, &h) == -ENOENT);
440 getenv_for_pid(1, "PATH", &i);
441 log_info("pid1 $PATH: '%s'", strna(i));
444 static void test_protect_errno(void) {
453 static void test_parse_bytes(void) {
456 assert_se(parse_bytes("111", &bytes) == 0);
457 assert_se(bytes == 111);
459 assert_se(parse_bytes(" 112 B", &bytes) == 0);
460 assert_se(bytes == 112);
462 assert_se(parse_bytes("3 K", &bytes) == 0);
463 assert_se(bytes == 3*1024);
465 assert_se(parse_bytes(" 4 M 11K", &bytes) == 0);
466 assert_se(bytes == 4*1024*1024 + 11 * 1024);
468 assert_se(parse_bytes("3B3G", &bytes) == 0);
469 assert_se(bytes == 3ULL*1024*1024*1024 + 3);
471 assert_se(parse_bytes("3B3G4T", &bytes) == 0);
472 assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
474 assert_se(parse_bytes("12P", &bytes) == 0);
475 assert_se(bytes == 12ULL * 1024*1024*1024*1024*1024);
477 assert_se(parse_bytes("3E 2P", &bytes) == 0);
478 assert_se(bytes == (3 * 1024 + 2ULL) * 1024*1024*1024*1024*1024);
480 assert_se(parse_bytes("12X", &bytes) == -EINVAL);
482 assert_se(parse_bytes("1024E", &bytes) == -ERANGE);
483 assert_se(parse_bytes("-1", &bytes) == -ERANGE);
484 assert_se(parse_bytes("-1024E", &bytes) == -ERANGE);
486 assert_se(parse_bytes("-1024P", &bytes) == -ERANGE);
488 assert_se(parse_bytes("-10B 20K", &bytes) == -ERANGE);
491 static void test_strextend(void) {
492 _cleanup_free_ char *str = strdup("0123");
493 strextend(&str, "456", "78", "9", NULL);
494 assert_se(streq(str, "0123456789"));
497 static void test_strrep(void) {
498 _cleanup_free_ char *one, *three, *zero;
499 one = strrep("waldo", 1);
500 three = strrep("waldo", 3);
501 zero = strrep("waldo", 0);
503 assert_se(streq(one, "waldo"));
504 assert_se(streq(three, "waldowaldowaldo"));
505 assert_se(streq(zero, ""));
508 static void test_parse_user_at_host(void) {
509 _cleanup_free_ char *both = strdup("waldo@waldoscomputer");
510 _cleanup_free_ char *onlyhost = strdup("mikescomputer");
511 char *user = NULL, *host = NULL;
513 parse_user_at_host(both, &user, &host);
514 assert_se(streq(user, "waldo"));
515 assert_se(streq(host, "waldoscomputer"));
518 parse_user_at_host(onlyhost, &user, &host);
519 assert_se(user == NULL);
520 assert_se(streq(host, "mikescomputer"));
523 static void test_split_pair(void) {
524 _cleanup_free_ char *a = NULL, *b = NULL;
526 assert_se(split_pair("", "", &a, &b) == -EINVAL);
527 assert_se(split_pair("foo=bar", "", &a, &b) == -EINVAL);
528 assert_se(split_pair("", "=", &a, &b) == -EINVAL);
529 assert_se(split_pair("foo=bar", "=", &a, &b) >= 0);
530 assert_se(streq(a, "foo"));
531 assert_se(streq(b, "bar"));
534 assert_se(split_pair("==", "==", &a, &b) >= 0);
535 assert_se(streq(a, ""));
536 assert_se(streq(b, ""));
540 assert_se(split_pair("===", "==", &a, &b) >= 0);
541 assert_se(streq(a, ""));
542 assert_se(streq(b, "="));
545 int main(int argc, char *argv[]) {
549 test_parse_boolean();
567 test_foreach_word_quoted();
568 test_default_term_for_tty();
569 test_memdup_multiply();
570 test_bus_path_escape();
571 test_hostname_is_valid();
573 test_get_process_comm();
574 test_protect_errno();
578 test_parse_user_at_host();