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