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