chiark / gitweb /
add new systemd-escape tool
[elogind.git] / src / test / test-util.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2010 Lennart Poettering
7   Copyright 2013 Thomas H.P. Andersen
8
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.
13
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.
18
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/>.
21 ***/
22
23 #include <string.h>
24 #include <unistd.h>
25 #include <fcntl.h>
26 #include <locale.h>
27 #include <errno.h>
28 #include <signal.h>
29
30 #include "util.h"
31 #include "mkdir.h"
32 #include "strv.h"
33 #include "def.h"
34 #include "fileio.h"
35 #include "conf-parser.h"
36
37 static void test_streq_ptr(void) {
38         assert_se(streq_ptr(NULL, NULL));
39         assert_se(!streq_ptr("abc", "cdef"));
40 }
41
42 static void test_align_power2(void) {
43         unsigned long i, p2;
44
45         assert_se(ALIGN_POWER2(0) == 0);
46         assert_se(ALIGN_POWER2(1) == 1);
47         assert_se(ALIGN_POWER2(2) == 2);
48         assert_se(ALIGN_POWER2(3) == 4);
49         assert_se(ALIGN_POWER2(12) == 16);
50
51         assert_se(ALIGN_POWER2(ULONG_MAX) == 0);
52         assert_se(ALIGN_POWER2(ULONG_MAX - 1) == 0);
53         assert_se(ALIGN_POWER2(ULONG_MAX - 1024) == 0);
54         assert_se(ALIGN_POWER2(ULONG_MAX / 2) == ULONG_MAX / 2 + 1);
55         assert_se(ALIGN_POWER2(ULONG_MAX + 1) == 0);
56
57         for (i = 1; i < 131071; ++i) {
58                 for (p2 = 1; p2 < i; p2 <<= 1)
59                         /* empty */ ;
60
61                 assert_se(ALIGN_POWER2(i) == p2);
62         }
63
64         for (i = ULONG_MAX - 1024; i < ULONG_MAX; ++i) {
65                 for (p2 = 1; p2 && p2 < i; p2 <<= 1)
66                         /* empty */ ;
67
68                 assert_se(ALIGN_POWER2(i) == p2);
69         }
70 }
71
72 static void test_first_word(void) {
73         assert_se(first_word("Hello", ""));
74         assert_se(first_word("Hello", "Hello"));
75         assert_se(first_word("Hello world", "Hello"));
76         assert_se(first_word("Hello\tworld", "Hello"));
77         assert_se(first_word("Hello\nworld", "Hello"));
78         assert_se(first_word("Hello\rworld", "Hello"));
79         assert_se(first_word("Hello ", "Hello"));
80
81         assert_se(!first_word("Hello", "Hellooo"));
82         assert_se(!first_word("Hello", "xxxxx"));
83         assert_se(!first_word("Hellooo", "Hello"));
84 }
85
86 static void test_close_many(void) {
87         int fds[3];
88         char name0[] = "/tmp/test-close-many.XXXXXX";
89         char name1[] = "/tmp/test-close-many.XXXXXX";
90         char name2[] = "/tmp/test-close-many.XXXXXX";
91
92         fds[0] = mkostemp_safe(name0, O_RDWR|O_CLOEXEC);
93         fds[1] = mkostemp_safe(name1, O_RDWR|O_CLOEXEC);
94         fds[2] = mkostemp_safe(name2, O_RDWR|O_CLOEXEC);
95
96         close_many(fds, 2);
97
98         assert_se(fcntl(fds[0], F_GETFD) == -1);
99         assert_se(fcntl(fds[1], F_GETFD) == -1);
100         assert_se(fcntl(fds[2], F_GETFD) >= 0);
101
102         safe_close(fds[2]);
103
104         unlink(name0);
105         unlink(name1);
106         unlink(name2);
107 }
108
109 static void test_parse_boolean(void) {
110         assert_se(parse_boolean("1") == 1);
111         assert_se(parse_boolean("y") == 1);
112         assert_se(parse_boolean("Y") == 1);
113         assert_se(parse_boolean("yes") == 1);
114         assert_se(parse_boolean("YES") == 1);
115         assert_se(parse_boolean("true") == 1);
116         assert_se(parse_boolean("TRUE") == 1);
117         assert_se(parse_boolean("on") == 1);
118         assert_se(parse_boolean("ON") == 1);
119
120         assert_se(parse_boolean("0") == 0);
121         assert_se(parse_boolean("n") == 0);
122         assert_se(parse_boolean("N") == 0);
123         assert_se(parse_boolean("no") == 0);
124         assert_se(parse_boolean("NO") == 0);
125         assert_se(parse_boolean("false") == 0);
126         assert_se(parse_boolean("FALSE") == 0);
127         assert_se(parse_boolean("off") == 0);
128         assert_se(parse_boolean("OFF") == 0);
129
130         assert_se(parse_boolean("garbage") < 0);
131         assert_se(parse_boolean("") < 0);
132 }
133
134 static void test_parse_pid(void) {
135         int r;
136         pid_t pid;
137
138         r = parse_pid("100", &pid);
139         assert_se(r == 0);
140         assert_se(pid == 100);
141
142         r = parse_pid("0x7FFFFFFF", &pid);
143         assert_se(r == 0);
144         assert_se(pid == 2147483647);
145
146         pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
147         r = parse_pid("0", &pid);
148         assert_se(r == -ERANGE);
149         assert_se(pid == 65);
150
151         pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
152         r = parse_pid("-100", &pid);
153         assert_se(r == -ERANGE);
154         assert_se(pid == 65);
155
156         pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
157         r = parse_pid("0xFFFFFFFFFFFFFFFFF", &pid);
158         assert(r == -ERANGE);
159         assert_se(pid == 65);
160 }
161
162 static void test_parse_uid(void) {
163         int r;
164         uid_t uid;
165
166         r = parse_uid("100", &uid);
167         assert_se(r == 0);
168         assert_se(uid == 100);
169 }
170
171 static void test_safe_atolli(void) {
172         int r;
173         long long l;
174
175         r = safe_atolli("12345", &l);
176         assert_se(r == 0);
177         assert_se(l == 12345);
178
179         r = safe_atolli("junk", &l);
180         assert_se(r == -EINVAL);
181 }
182
183 static void test_safe_atod(void) {
184         int r;
185         double d;
186         char *e;
187
188         r = safe_atod("junk", &d);
189         assert_se(r == -EINVAL);
190
191         r = safe_atod("0.2244", &d);
192         assert_se(r == 0);
193         assert_se(abs(d - 0.2244) < 0.000001);
194
195         r = safe_atod("0,5", &d);
196         assert_se(r == -EINVAL);
197
198         errno = 0;
199         strtod("0,5", &e);
200         assert_se(*e == ',');
201
202         /* Check if this really is locale independent */
203         setlocale(LC_NUMERIC, "de_DE.utf8");
204
205         r = safe_atod("0.2244", &d);
206         assert_se(r == 0);
207         assert_se(abs(d - 0.2244) < 0.000001);
208
209         r = safe_atod("0,5", &d);
210         assert_se(r == -EINVAL);
211
212         errno = 0;
213         assert_se(abs(strtod("0,5", &e) - 0.5) < 0.00001);
214
215         /* And check again, reset */
216         setlocale(LC_NUMERIC, "C");
217
218         r = safe_atod("0.2244", &d);
219         assert_se(r == 0);
220         assert_se(abs(d - 0.2244) < 0.000001);
221
222         r = safe_atod("0,5", &d);
223         assert_se(r == -EINVAL);
224
225         errno = 0;
226         strtod("0,5", &e);
227         assert_se(*e == ',');
228 }
229
230 static void test_strappend(void) {
231         _cleanup_free_ char *t1, *t2, *t3, *t4;
232
233         t1 = strappend(NULL, NULL);
234         assert_se(streq(t1, ""));
235
236         t2 = strappend(NULL, "suf");
237         assert_se(streq(t2, "suf"));
238
239         t3 = strappend("pre", NULL);
240         assert_se(streq(t3, "pre"));
241
242         t4 = strappend("pre", "suf");
243         assert_se(streq(t4, "presuf"));
244 }
245
246 static void test_strstrip(void) {
247         char *r;
248         char input[] = "   hello, waldo.   ";
249
250         r = strstrip(input);
251         assert_se(streq(r, "hello, waldo."));
252 }
253
254 static void test_delete_chars(void) {
255         char *r;
256         char input[] = "   hello, waldo.   abc";
257
258         r = delete_chars(input, WHITESPACE);
259         assert_se(streq(r, "hello,waldo.abc"));
260 }
261
262 static void test_in_charset(void) {
263         assert_se(in_charset("dddaaabbbcccc", "abcd"));
264         assert_se(!in_charset("dddaaabbbcccc", "abc f"));
265 }
266
267 static void test_hexchar(void) {
268         assert_se(hexchar(0xa) == 'a');
269         assert_se(hexchar(0x0) == '0');
270 }
271
272 static void test_unhexchar(void) {
273         assert_se(unhexchar('a') == 0xA);
274         assert_se(unhexchar('A') == 0xA);
275         assert_se(unhexchar('0') == 0x0);
276 }
277
278 static void test_octchar(void) {
279         assert_se(octchar(00) == '0');
280         assert_se(octchar(07) == '7');
281 }
282
283 static void test_unoctchar(void) {
284         assert_se(unoctchar('0') == 00);
285         assert_se(unoctchar('7') == 07);
286 }
287
288 static void test_decchar(void) {
289         assert_se(decchar(0) == '0');
290         assert_se(decchar(9) == '9');
291 }
292
293 static void test_undecchar(void) {
294         assert_se(undecchar('0') == 0);
295         assert_se(undecchar('9') == 9);
296 }
297
298 static void test_cescape(void) {
299         _cleanup_free_ char *escaped;
300
301         assert_se(escaped = cescape("abc\\\"\b\f\n\r\t\v\a\003\177\234\313"));
302         assert_se(streq(escaped, "abc\\\\\\\"\\b\\f\\n\\r\\t\\v\\a\\003\\177\\234\\313"));
303 }
304
305 static void test_cunescape(void) {
306         _cleanup_free_ char *unescaped;
307
308         assert_se(unescaped = cunescape("abc\\\\\\\"\\b\\f\\a\\n\\r\\t\\v\\003\\177\\234\\313\\000\\x00"));
309         assert_se(streq(unescaped, "abc\\\"\b\f\a\n\r\t\v\003\177\234\313\\000\\x00"));
310 }
311
312 static void test_foreach_word(void) {
313         char *w, *state;
314         size_t l;
315         int i = 0;
316         const char test[] = "test abc d\te   f   ";
317         const char * const expected[] = {
318                 "test",
319                 "abc",
320                 "d",
321                 "e",
322                 "f",
323                 "",
324                 NULL
325         };
326
327         FOREACH_WORD(w, l, test, state) {
328                 assert_se(strneq(expected[i++], w, l));
329         }
330 }
331
332 static void test_foreach_word_quoted(void) {
333         char *w, *state;
334         size_t l;
335         int i = 0;
336         const char test[] = "test a b c 'd' e '' '' hhh '' '' \"a b c\"";
337         const char * const expected[] = {
338                 "test",
339                 "a",
340                 "b",
341                 "c",
342                 "d",
343                 "e",
344                 "",
345                 "",
346                 "hhh",
347                 "",
348                 "",
349                 "a b c",
350                 NULL
351         };
352
353         printf("<%s>\n", test);
354         FOREACH_WORD_QUOTED(w, l, test, state) {
355                 _cleanup_free_ char *t = NULL;
356
357                 assert_se(t = strndup(w, l));
358                 assert_se(strneq(expected[i++], w, l));
359                 printf("<%s>\n", t);
360         }
361 }
362
363 static void test_default_term_for_tty(void) {
364         puts(default_term_for_tty("/dev/tty23"));
365         puts(default_term_for_tty("/dev/ttyS23"));
366         puts(default_term_for_tty("/dev/tty0"));
367         puts(default_term_for_tty("/dev/pty0"));
368         puts(default_term_for_tty("/dev/pts/0"));
369         puts(default_term_for_tty("/dev/console"));
370         puts(default_term_for_tty("tty23"));
371         puts(default_term_for_tty("ttyS23"));
372         puts(default_term_for_tty("tty0"));
373         puts(default_term_for_tty("pty0"));
374         puts(default_term_for_tty("pts/0"));
375         puts(default_term_for_tty("console"));
376 }
377
378 static void test_memdup_multiply(void) {
379         int org[] = {1, 2, 3};
380         int *dup;
381
382         dup = (int*)memdup_multiply(org, sizeof(int), 3);
383
384         assert_se(dup);
385         assert_se(dup[0] == 1);
386         assert_se(dup[1] == 2);
387         assert_se(dup[2] == 3);
388         free(dup);
389 }
390
391 static void test_hostname_is_valid(void) {
392         assert(hostname_is_valid("foobar"));
393         assert(hostname_is_valid("foobar.com"));
394         assert(!hostname_is_valid("fööbar"));
395         assert(!hostname_is_valid(""));
396         assert(!hostname_is_valid("."));
397         assert(!hostname_is_valid(".."));
398         assert(!hostname_is_valid("foobar."));
399         assert(!hostname_is_valid(".foobar"));
400         assert(!hostname_is_valid("foo..bar"));
401         assert(!hostname_is_valid("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"));
402 }
403
404 static void test_u64log2(void) {
405         assert(u64log2(0) == 0);
406         assert(u64log2(8) == 3);
407         assert(u64log2(9) == 3);
408         assert(u64log2(15) == 3);
409         assert(u64log2(16) == 4);
410         assert(u64log2(1024*1024) == 20);
411         assert(u64log2(1024*1024+5) == 20);
412 }
413
414 static void test_get_process_comm(void) {
415         struct stat st;
416         _cleanup_free_ char *a = NULL, *c = NULL, *d = NULL, *f = NULL, *i = NULL;
417         unsigned long long b;
418         pid_t e;
419         uid_t u;
420         gid_t g;
421         dev_t h;
422         int r;
423
424         if (stat("/proc/1/comm", &st) == 0) {
425                 assert_se(get_process_comm(1, &a) >= 0);
426                 log_info("pid1 comm: '%s'", a);
427         } else {
428                 log_warning("/proc/1/comm does not exist.");
429         }
430
431         assert_se(get_starttime_of_pid(1, &b) >= 0);
432         log_info("pid1 starttime: '%llu'", b);
433
434         assert_se(get_process_cmdline(1, 0, true, &c) >= 0);
435         log_info("pid1 cmdline: '%s'", c);
436
437         assert_se(get_process_cmdline(1, 8, false, &d) >= 0);
438         log_info("pid1 cmdline truncated: '%s'", d);
439
440         assert_se(get_parent_of_pid(1, &e) >= 0);
441         log_info("pid1 ppid: "PID_FMT, e);
442         assert_se(e == 0);
443
444         assert_se(is_kernel_thread(1) == 0);
445
446         r = get_process_exe(1, &f);
447         assert_se(r >= 0 || r == -EACCES);
448         log_info("pid1 exe: '%s'", strna(f));
449
450         assert_se(get_process_uid(1, &u) == 0);
451         log_info("pid1 uid: "UID_FMT, u);
452         assert_se(u == 0);
453
454         assert_se(get_process_gid(1, &g) == 0);
455         log_info("pid1 gid: "GID_FMT, g);
456         assert_se(g == 0);
457
458         assert(get_ctty_devnr(1, &h) == -ENOENT);
459
460         getenv_for_pid(1, "PATH", &i);
461         log_info("pid1 $PATH: '%s'", strna(i));
462 }
463
464 static void test_protect_errno(void) {
465         errno = 12;
466         {
467                 PROTECT_ERRNO;
468                 errno = 11;
469         }
470         assert(errno == 12);
471 }
472
473 static void test_parse_size(void) {
474         off_t bytes;
475
476         assert_se(parse_size("111", 1024, &bytes) == 0);
477         assert_se(bytes == 111);
478
479         assert_se(parse_size("111.4", 1024, &bytes) == 0);
480         assert_se(bytes == 111);
481
482         assert_se(parse_size(" 112 B", 1024, &bytes) == 0);
483         assert_se(bytes == 112);
484
485         assert_se(parse_size(" 112.6 B", 1024, &bytes) == 0);
486         assert_se(bytes == 112);
487
488         assert_se(parse_size("3.5 K", 1024, &bytes) == 0);
489         assert_se(bytes == 3*1024 + 512);
490
491         assert_se(parse_size("3. K", 1024, &bytes) == 0);
492         assert_se(bytes == 3*1024);
493
494         assert_se(parse_size("3.0 K", 1024, &bytes) == 0);
495         assert_se(bytes == 3*1024);
496
497         assert_se(parse_size("3. 0 K", 1024, &bytes) == -EINVAL);
498
499         assert_se(parse_size(" 4 M 11.5K", 1024, &bytes) == 0);
500         assert_se(bytes == 4*1024*1024 + 11 * 1024 + 512);
501
502         assert_se(parse_size("3B3.5G", 1024, &bytes) == -EINVAL);
503
504         assert_se(parse_size("3.5G3B", 1024, &bytes) == 0);
505         assert_se(bytes == 3ULL*1024*1024*1024 + 512*1024*1024 + 3);
506
507         assert_se(parse_size("3.5G 4B", 1024, &bytes) == 0);
508         assert_se(bytes == 3ULL*1024*1024*1024 + 512*1024*1024 + 4);
509
510         assert_se(parse_size("3B3G4T", 1024, &bytes) == -EINVAL);
511
512         assert_se(parse_size("4T3G3B", 1024, &bytes) == 0);
513         assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
514
515         assert_se(parse_size(" 4 T 3 G 3 B", 1024, &bytes) == 0);
516         assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
517
518         assert_se(parse_size("12P", 1024, &bytes) == 0);
519         assert_se(bytes == 12ULL * 1024*1024*1024*1024*1024);
520
521         assert_se(parse_size("12P12P", 1024, &bytes) == -EINVAL);
522
523         assert_se(parse_size("3E 2P", 1024, &bytes) == 0);
524         assert_se(bytes == (3 * 1024 + 2ULL) * 1024*1024*1024*1024*1024);
525
526         assert_se(parse_size("12X", 1024, &bytes) == -EINVAL);
527
528         assert_se(parse_size("12.5X", 1024, &bytes) == -EINVAL);
529
530         assert_se(parse_size("12.5e3", 1024, &bytes) == -EINVAL);
531
532         assert_se(parse_size("1024E", 1024, &bytes) == -ERANGE);
533         assert_se(parse_size("-1", 1024, &bytes) == -ERANGE);
534         assert_se(parse_size("-1024E", 1024, &bytes) == -ERANGE);
535
536         assert_se(parse_size("-1024P", 1024, &bytes) == -ERANGE);
537
538         assert_se(parse_size("-10B 20K", 1024, &bytes) == -ERANGE);
539 }
540
541 static void test_config_parse_iec_off(void) {
542         off_t offset = 0;
543         assert_se(config_parse_iec_off(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4M", &offset, NULL) == 0);
544         assert_se(offset == 4 * 1024 * 1024);
545
546         assert_se(config_parse_iec_off(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4.5M", &offset, NULL) == 0);
547 }
548
549 static void test_strextend(void) {
550         _cleanup_free_ char *str = strdup("0123");
551         strextend(&str, "456", "78", "9", NULL);
552         assert_se(streq(str, "0123456789"));
553 }
554
555 static void test_strrep(void) {
556         _cleanup_free_ char *one, *three, *zero;
557         one = strrep("waldo", 1);
558         three = strrep("waldo", 3);
559         zero = strrep("waldo", 0);
560
561         assert_se(streq(one, "waldo"));
562         assert_se(streq(three, "waldowaldowaldo"));
563         assert_se(streq(zero, ""));
564 }
565
566 static void test_split_pair(void) {
567         _cleanup_free_ char *a = NULL, *b = NULL;
568
569         assert_se(split_pair("", "", &a, &b) == -EINVAL);
570         assert_se(split_pair("foo=bar", "", &a, &b) == -EINVAL);
571         assert_se(split_pair("", "=", &a, &b) == -EINVAL);
572         assert_se(split_pair("foo=bar", "=", &a, &b) >= 0);
573         assert_se(streq(a, "foo"));
574         assert_se(streq(b, "bar"));
575         free(a);
576         free(b);
577         assert_se(split_pair("==", "==", &a, &b) >= 0);
578         assert_se(streq(a, ""));
579         assert_se(streq(b, ""));
580         free(a);
581         free(b);
582
583         assert_se(split_pair("===", "==", &a, &b) >= 0);
584         assert_se(streq(a, ""));
585         assert_se(streq(b, "="));
586 }
587
588 static void test_fstab_node_to_udev_node(void) {
589         char *n;
590
591         n = fstab_node_to_udev_node("LABEL=applé/jack");
592         puts(n);
593         assert_se(streq(n, "/dev/disk/by-label/applé\\x2fjack"));
594         free(n);
595
596         n = fstab_node_to_udev_node("PARTLABEL=pinkié pie");
597         puts(n);
598         assert_se(streq(n, "/dev/disk/by-partlabel/pinkié\\x20pie"));
599         free(n);
600
601         n = fstab_node_to_udev_node("UUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
602         puts(n);
603         assert_se(streq(n, "/dev/disk/by-uuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
604         free(n);
605
606         n = fstab_node_to_udev_node("PARTUUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
607         puts(n);
608         assert_se(streq(n, "/dev/disk/by-partuuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
609         free(n);
610
611         n = fstab_node_to_udev_node("PONIES=awesome");
612         puts(n);
613         assert_se(streq(n, "PONIES=awesome"));
614         free(n);
615
616         n = fstab_node_to_udev_node("/dev/xda1");
617         puts(n);
618         assert_se(streq(n, "/dev/xda1"));
619         free(n);
620 }
621
622 static void test_get_files_in_directory(void) {
623         _cleanup_strv_free_ char **l = NULL, **t = NULL;
624
625         assert_se(get_files_in_directory("/tmp", &l) >= 0);
626         assert_se(get_files_in_directory(".", &t) >= 0);
627         assert_se(get_files_in_directory(".", NULL) >= 0);
628 }
629
630 static void test_in_set(void) {
631         assert_se(IN_SET(1, 1));
632         assert_se(IN_SET(1, 1, 2, 3, 4));
633         assert_se(IN_SET(2, 1, 2, 3, 4));
634         assert_se(IN_SET(3, 1, 2, 3, 4));
635         assert_se(IN_SET(4, 1, 2, 3, 4));
636         assert_se(!IN_SET(0, 1));
637         assert_se(!IN_SET(0, 1, 2, 3, 4));
638 }
639
640 static void test_writing_tmpfile(void) {
641         char name[] = "/tmp/test-systemd_writing_tmpfile.XXXXXX";
642         _cleanup_free_ char *contents = NULL;
643         size_t size;
644         int fd, r;
645         struct iovec iov[3];
646
647         IOVEC_SET_STRING(iov[0], "abc\n");
648         IOVEC_SET_STRING(iov[1], ALPHANUMERICAL "\n");
649         IOVEC_SET_STRING(iov[2], "");
650
651         fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
652         printf("tmpfile: %s", name);
653
654         r = writev(fd, iov, 3);
655         assert(r >= 0);
656
657         r = read_full_file(name, &contents, &size);
658         assert(r == 0);
659         printf("contents: %s", contents);
660         assert(streq(contents, "abc\n" ALPHANUMERICAL "\n"));
661
662         unlink(name);
663 }
664
665 static void test_hexdump(void) {
666         uint8_t data[146];
667         unsigned i;
668
669         hexdump(stdout, NULL, 0);
670         hexdump(stdout, "", 0);
671         hexdump(stdout, "", 1);
672         hexdump(stdout, "x", 1);
673         hexdump(stdout, "x", 2);
674         hexdump(stdout, "foobar", 7);
675         hexdump(stdout, "f\nobar", 7);
676         hexdump(stdout, "xxxxxxxxxxxxxxxxxxxxyz", 23);
677
678         for (i = 0; i < ELEMENTSOF(data); i++)
679                 data[i] = i*2;
680
681         hexdump(stdout, data, sizeof(data));
682 }
683
684 static void test_log2i(void) {
685         assert_se(log2i(1) == 0);
686         assert_se(log2i(2) == 1);
687         assert_se(log2i(3) == 1);
688         assert_se(log2i(4) == 2);
689         assert_se(log2i(32) == 5);
690         assert_se(log2i(33) == 5);
691         assert_se(log2i(63) == 5);
692         assert_se(log2i(INT_MAX) == sizeof(int)*8-2);
693 }
694
695 static void test_foreach_string(void) {
696         const char * const t[] = {
697                 "foo",
698                 "bar",
699                 "waldo",
700                 NULL
701         };
702         const char *x;
703         unsigned i = 0;
704
705         FOREACH_STRING(x, "foo", "bar", "waldo")
706                 assert_se(streq_ptr(t[i++], x));
707
708         assert_se(i == 3);
709
710         FOREACH_STRING(x, "zzz")
711                 assert_se(streq(x, "zzz"));
712 }
713
714 static void test_filename_is_safe(void) {
715         char foo[FILENAME_MAX+2];
716         int i;
717
718         assert_se(!filename_is_safe(""));
719         assert_se(!filename_is_safe("/bar/foo"));
720         assert_se(!filename_is_safe("/"));
721         assert_se(!filename_is_safe("."));
722         assert_se(!filename_is_safe(".."));
723
724         for (i=0; i<FILENAME_MAX+1; i++)
725                 foo[i] = 'a';
726         foo[FILENAME_MAX+1] = '\0';
727
728         assert_se(!filename_is_safe(foo));
729
730         assert_se(filename_is_safe("foo_bar-333"));
731         assert_se(filename_is_safe("o.o"));
732 }
733
734 static void test_ascii_strlower(void) {
735         char a[] = "AabBcC Jk Ii Od LKJJJ kkd LK";
736         assert_se(streq(ascii_strlower(a), "aabbcc jk ii od lkjjj kkd lk"));
737 }
738
739 static void test_files_same(void) {
740         _cleanup_close_ int fd = -1;
741         char name[] = "/tmp/test-files_same.XXXXXX";
742         char name_alias[] = "/tmp/test-files_same.alias";
743
744         fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
745         assert_se(fd >= 0);
746         assert_se(symlink(name, name_alias) >= 0);
747
748         assert_se(files_same(name, name));
749         assert_se(files_same(name, name_alias));
750
751         unlink(name);
752         unlink(name_alias);
753 }
754
755 static void test_is_valid_documentation_url(void) {
756         assert_se(is_valid_documentation_url("http://www.freedesktop.org/wiki/Software/systemd"));
757         assert_se(is_valid_documentation_url("https://www.kernel.org/doc/Documentation/binfmt_misc.txt"));
758         assert_se(is_valid_documentation_url("file:foo"));
759         assert_se(is_valid_documentation_url("man:systemd.special(7)"));
760         assert_se(is_valid_documentation_url("info:bar"));
761
762         assert_se(!is_valid_documentation_url("foo:"));
763         assert_se(!is_valid_documentation_url("info:"));
764         assert_se(!is_valid_documentation_url(""));
765 }
766
767 static void test_file_in_same_dir(void) {
768         assert_se(streq(file_in_same_dir("/", "a"), "/a"));
769         assert_se(streq(file_in_same_dir("/", "/a"), "/a"));
770         assert_se(streq(file_in_same_dir("", "a"), "a"));
771         assert_se(streq(file_in_same_dir("a/", "a"), "a/a"));
772         assert_se(streq(file_in_same_dir("bar/foo", "bar"), "bar/bar"));
773 }
774
775 static void test_endswith(void) {
776         assert_se(endswith("foobar", "bar"));
777         assert_se(endswith("foobar", ""));
778         assert_se(endswith("foobar", "foobar"));
779         assert_se(endswith("", ""));
780
781         assert_se(!endswith("foobar", "foo"));
782         assert_se(!endswith("foobar", "foobarfoofoo"));
783 }
784
785 static void test_close_nointr(void) {
786         char name[] = "/tmp/test-test-close_nointr.XXXXXX";
787         int fd;
788
789         fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
790         assert_se(fd >= 0);
791         assert_se(close_nointr(fd) >= 0);
792         assert_se(close_nointr(fd) < 0);
793
794         unlink(name);
795 }
796
797
798 static void test_unlink_noerrno(void) {
799         char name[] = "/tmp/test-close_nointr.XXXXXX";
800         int fd;
801
802         fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
803         assert_se(fd >= 0);
804         assert_se(close_nointr(fd) >= 0);
805
806         {
807                 PROTECT_ERRNO;
808                 errno = -42;
809                 assert_se(unlink_noerrno(name) >= 0);
810                 assert_se(errno == -42);
811                 assert_se(unlink_noerrno(name) < 0);
812                 assert_se(errno == -42);
813         }
814 }
815
816 static void test_readlink_and_make_absolute(void) {
817         char tempdir[] = "/tmp/test-readlink_and_make_absolute";
818         char name[] = "/tmp/test-readlink_and_make_absolute/original";
819         char name2[] = "test-readlink_and_make_absolute/original";
820         char name_alias[] = "/tmp/test-readlink_and_make_absolute-alias";
821         char *r = NULL;
822
823         assert(mkdir_safe(tempdir, 0755, getuid(), getgid()) >= 0);
824         assert_se(touch(name) >= 0);
825
826         assert_se(symlink(name, name_alias) >= 0);
827         assert_se(readlink_and_make_absolute(name_alias, &r) >= 0);
828         assert_se(streq(r, name));
829         free(r);
830         assert_se(unlink(name_alias) >= 0);
831
832         assert_se(chdir(tempdir) >= 0);
833         assert_se(symlink(name2, name_alias) >= 0);
834         assert_se(readlink_and_make_absolute(name_alias, &r) >= 0);
835         assert_se(streq(r, name));
836         free(r);
837         assert_se(unlink(name_alias) >= 0);
838
839         assert_se(rm_rf_dangerous(tempdir, false, true, false) >= 0);
840 }
841
842 static void test_read_one_char(void) {
843         char r;
844         bool need_nl;
845         char name[] = "/tmp/test-read_one_char.XXXXXX";
846         _cleanup_close_ int fd = -1;
847         FILE *file;
848
849         fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
850         assert_se(fd >= 0);
851         file = fdopen(fd, "r+");
852         assert_se(file);
853         assert_se(fputs("c\n", file) >= 0);
854         rewind(file);
855
856         assert_se(read_one_char(file, &r, 1000000, &need_nl) >= 0);
857         assert_se(!need_nl);
858         assert_se(r == 'c');
859         assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
860
861         rewind(file);
862         assert_se(fputs("foobar\n", file) >= 0);
863         rewind(file);
864         assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
865
866         rewind(file);
867         assert_se(fputs("\n", file) >= 0);
868         rewind(file);
869         assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
870
871         unlink(name);
872 }
873
874 static void test_ignore_signals(void) {
875         assert_se(ignore_signals(SIGINT, -1) >= 0);
876         assert_se(kill(getpid(), SIGINT) >= 0);
877         assert_se(ignore_signals(SIGUSR1, SIGUSR2, SIGTERM, SIGPIPE, -1) >= 0);
878         assert_se(kill(getpid(), SIGUSR1) >= 0);
879         assert_se(kill(getpid(), SIGUSR2) >= 0);
880         assert_se(kill(getpid(), SIGTERM) >= 0);
881         assert_se(kill(getpid(), SIGPIPE) >= 0);
882         assert_se(default_signals(SIGINT, SIGUSR1, SIGUSR2, SIGTERM, SIGPIPE, -1) >= 0);
883 }
884
885 static void test_strshorten(void) {
886         char s[] = "foobar";
887
888         assert_se(strlen(strshorten(s, 6)) == 6);
889         assert_se(strlen(strshorten(s, 12)) == 6);
890         assert_se(strlen(strshorten(s, 2)) == 2);
891         assert_se(strlen(strshorten(s, 0)) == 0);
892 }
893
894 int main(int argc, char *argv[]) {
895         log_parse_environment();
896         log_open();
897
898         test_streq_ptr();
899         test_align_power2();
900         test_first_word();
901         test_close_many();
902         test_parse_boolean();
903         test_parse_pid();
904         test_parse_uid();
905         test_safe_atolli();
906         test_safe_atod();
907         test_strappend();
908         test_strstrip();
909         test_delete_chars();
910         test_in_charset();
911         test_hexchar();
912         test_unhexchar();
913         test_octchar();
914         test_unoctchar();
915         test_decchar();
916         test_undecchar();
917         test_cescape();
918         test_cunescape();
919         test_foreach_word();
920         test_foreach_word_quoted();
921         test_default_term_for_tty();
922         test_memdup_multiply();
923         test_hostname_is_valid();
924         test_u64log2();
925         test_get_process_comm();
926         test_protect_errno();
927         test_parse_size();
928         test_config_parse_iec_off();
929         test_strextend();
930         test_strrep();
931         test_split_pair();
932         test_fstab_node_to_udev_node();
933         test_get_files_in_directory();
934         test_in_set();
935         test_writing_tmpfile();
936         test_hexdump();
937         test_log2i();
938         test_foreach_string();
939         test_filename_is_safe();
940         test_ascii_strlower();
941         test_files_same();
942         test_is_valid_documentation_url();
943         test_file_in_same_dir();
944         test_endswith();
945         test_close_nointr();
946         test_unlink_noerrno();
947         test_readlink_and_make_absolute();
948         test_read_one_char();
949         test_ignore_signals();
950         test_strshorten();
951
952         return 0;
953 }