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."));
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_foreach_word(void) {
267 const char test[] = "test abc d\te f ";
268 const char * const expected[] = {
278 FOREACH_WORD(w, l, test, state) {
279 assert_se(strneq(expected[i++], w, l));
283 static void test_foreach_word_quoted(void) {
287 const char test[] = "test a b c 'd' e '' '' hhh '' '' \"a b c\"";
288 const char * const expected[] = {
304 printf("<%s>\n", test);
305 FOREACH_WORD_QUOTED(w, l, test, state) {
306 _cleanup_free_ char *t = NULL;
308 assert_se(t = strndup(w, l));
309 assert_se(strneq(expected[i++], w, l));
314 static void test_default_term_for_tty(void) {
315 puts(default_term_for_tty("/dev/tty23"));
316 puts(default_term_for_tty("/dev/ttyS23"));
317 puts(default_term_for_tty("/dev/tty0"));
318 puts(default_term_for_tty("/dev/pty0"));
319 puts(default_term_for_tty("/dev/pts/0"));
320 puts(default_term_for_tty("/dev/console"));
321 puts(default_term_for_tty("tty23"));
322 puts(default_term_for_tty("ttyS23"));
323 puts(default_term_for_tty("tty0"));
324 puts(default_term_for_tty("pty0"));
325 puts(default_term_for_tty("pts/0"));
326 puts(default_term_for_tty("console"));
329 static void test_memdup_multiply(void) {
330 int org[] = {1, 2, 3};
333 dup = (int*)memdup_multiply(org, sizeof(int), 3);
336 assert_se(dup[0] == 1);
337 assert_se(dup[1] == 2);
338 assert_se(dup[2] == 3);
342 static void test_bus_path_escape_one(const char *a, const char *b) {
343 _cleanup_free_ char *t = NULL, *x = NULL, *y = NULL;
345 assert_se(t = bus_path_escape(a));
346 assert_se(streq(t, b));
348 assert_se(x = bus_path_unescape(t));
349 assert_se(streq(a, x));
351 assert_se(y = bus_path_unescape(b));
352 assert_se(streq(a, y));
355 static void test_bus_path_escape(void) {
356 test_bus_path_escape_one("foo123bar", "foo123bar");
357 test_bus_path_escape_one("foo.bar", "foo_2ebar");
358 test_bus_path_escape_one("foo_2ebar", "foo_5f2ebar");
359 test_bus_path_escape_one("", "_");
360 test_bus_path_escape_one("_", "_5f");
361 test_bus_path_escape_one("1", "_31");
362 test_bus_path_escape_one(":1", "_3a1");
365 static void test_hostname_is_valid(void) {
366 assert(hostname_is_valid("foobar"));
367 assert(hostname_is_valid("foobar.com"));
368 assert(!hostname_is_valid("fööbar"));
369 assert(!hostname_is_valid(""));
370 assert(!hostname_is_valid("."));
371 assert(!hostname_is_valid(".."));
372 assert(!hostname_is_valid("foobar."));
373 assert(!hostname_is_valid(".foobar"));
374 assert(!hostname_is_valid("foo..bar"));
375 assert(!hostname_is_valid("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"));
378 static void test_u64log2(void) {
379 assert(u64log2(0) == 0);
380 assert(u64log2(8) == 3);
381 assert(u64log2(9) == 3);
382 assert(u64log2(15) == 3);
383 assert(u64log2(16) == 4);
384 assert(u64log2(1024*1024) == 20);
385 assert(u64log2(1024*1024+5) == 20);
388 static void test_get_process_comm(void) {
389 _cleanup_free_ char *a = NULL, *c = NULL, *d = NULL, *f = NULL, *i = NULL;
390 unsigned long long b;
397 assert_se(get_process_comm(1, &a) >= 0);
398 log_info("pid1 comm: '%s'", a);
400 assert_se(get_starttime_of_pid(1, &b) >= 0);
401 log_info("pid1 starttime: '%llu'", b);
403 assert_se(get_process_cmdline(1, 0, true, &c) >= 0);
404 log_info("pid1 cmdline: '%s'", c);
406 assert_se(get_process_cmdline(1, 8, false, &d) >= 0);
407 log_info("pid1 cmdline truncated: '%s'", d);
409 assert_se(get_parent_of_pid(1, &e) >= 0);
410 log_info("pid1 ppid: '%llu'", (unsigned long long) e);
413 assert_se(is_kernel_thread(1) == 0);
415 r = get_process_exe(1, &f);
416 assert_se(r >= 0 || r == -EACCES);
417 log_info("pid1 exe: '%s'", strna(f));
419 assert_se(get_process_uid(1, &u) == 0);
420 log_info("pid1 uid: '%llu'", (unsigned long long) u);
423 assert_se(get_process_gid(1, &g) == 0);
424 log_info("pid1 gid: '%llu'", (unsigned long long) g);
427 assert(get_ctty_devnr(1, &h) == -ENOENT);
429 getenv_for_pid(1, "PATH", &i);
430 log_info("pid1 $PATH: '%s'", strna(i));
433 static void test_protect_errno(void) {
442 static void test_parse_bytes(void) {
445 assert_se(parse_bytes("111", &bytes) == 0);
446 assert_se(bytes == 111);
448 assert_se(parse_bytes(" 112 B", &bytes) == 0);
449 assert_se(bytes == 112);
451 assert_se(parse_bytes("3 K", &bytes) == 0);
452 assert_se(bytes == 3*1024);
454 assert_se(parse_bytes(" 4 M 11K", &bytes) == 0);
455 assert_se(bytes == 4*1024*1024 + 11 * 1024);
457 assert_se(parse_bytes("3B3G", &bytes) == 0);
458 assert_se(bytes == 3ULL*1024*1024*1024 + 3);
460 assert_se(parse_bytes("3B3G4T", &bytes) == 0);
461 assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
463 assert_se(parse_bytes("12P", &bytes) == 0);
464 assert_se(bytes == 12ULL * 1024*1024*1024*1024*1024);
466 assert_se(parse_bytes("3E 2P", &bytes) == 0);
467 assert_se(bytes == (3 * 1024 + 2ULL) * 1024*1024*1024*1024*1024);
469 assert_se(parse_bytes("12X", &bytes) == -EINVAL);
471 assert_se(parse_bytes("1024E", &bytes) == -ERANGE);
472 assert_se(parse_bytes("-1", &bytes) == -ERANGE);
473 assert_se(parse_bytes("-1024E", &bytes) == -ERANGE);
475 assert_se(parse_bytes("-1024P", &bytes) == -ERANGE);
477 assert_se(parse_bytes("-10B 20K", &bytes) == -ERANGE);
480 int main(int argc, char *argv[]) {
484 test_parse_boolean();
500 test_foreach_word_quoted();
501 test_default_term_for_tty();
502 test_memdup_multiply();
503 test_bus_path_escape();
504 test_hostname_is_valid();
506 test_get_process_comm();
507 test_protect_errno();