]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/test/test-fileio.c
util-lib: split string parsing related calls from util.[ch] into parse-util.[ch]
[thirdparty/systemd.git] / src / test / test-fileio.c
CommitLineData
f73141d7
LP
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2013 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
22#include <stdio.h>
23#include <fcntl.h>
24#include <unistd.h>
25
1e5413f7 26#include "ctype.h"
3ffd4af2
LP
27#include "def.h"
28#include "env-util.h"
29#include "fd-util.h"
30#include "fileio.h"
6bedfcbb 31#include "parse-util.h"
3ffd4af2 32#include "process-util.h"
07630cea 33#include "string-util.h"
3ffd4af2
LP
34#include "strv.h"
35#include "util.h"
f73141d7
LP
36
37static void test_parse_env_file(void) {
095b30cb
ZJS
38 char t[] = "/tmp/test-fileio-in-XXXXXX",
39 p[] = "/tmp/test-fileio-out-XXXXXX";
f73141d7
LP
40 int fd, r;
41 FILE *f;
ebc05a09
HH
42 _cleanup_free_ char *one = NULL, *two = NULL, *three = NULL, *four = NULL, *five = NULL,
43 *six = NULL, *seven = NULL, *eight = NULL, *nine = NULL, *ten = NULL;
768100ef 44 _cleanup_strv_free_ char **a = NULL, **b = NULL;
f73141d7 45 char **i;
768100ef 46 unsigned k;
f73141d7 47
2d5bdf5b 48 fd = mkostemp_safe(p, O_RDWR|O_CLOEXEC);
d514feaa
TA
49 assert_se(fd >= 0);
50 close(fd);
095b30cb 51
2d5bdf5b 52 fd = mkostemp_safe(t, O_RDWR|O_CLOEXEC);
f73141d7
LP
53 assert_se(fd >= 0);
54
55 f = fdopen(fd, "w");
56 assert_se(f);
57
58 fputs("one=BAR \n"
59 "# comment\n"
60 " # comment \n"
98f59e59 61 " ; comment \n"
f73141d7
LP
62 " two = bar \n"
63 "invalid line\n"
98f59e59 64 "invalid line #comment\n"
f73141d7
LP
65 "three = \"333\n"
66 "xxxx\"\n"
67 "four = \'44\\\"44\'\n"
68 "five = \'55\\\'55\' \"FIVE\" cinco \n"
69 "six = seis sechs\\\n"
70 " sis\n"
98f59e59
HH
71 "seven=\"sevenval\" #nocomment\n"
72 "eight=eightval #nocomment\n"
ebc05a09
HH
73 "export nine=nineval\n"
74 "ten=", f);
f73141d7
LP
75
76 fflush(f);
77 fclose(f);
78
717603e3 79 r = load_env_file(NULL, t, NULL, &a);
ebc05a09
HH
80 assert_se(r >= 0);
81
82 STRV_FOREACH(i, a)
83 log_info("Got: <%s>", *i);
84
5fba7bbf
TA
85 assert_se(streq_ptr(a[0], "one=BAR"));
86 assert_se(streq_ptr(a[1], "two=bar"));
87 assert_se(streq_ptr(a[2], "three=333\nxxxx"));
88 assert_se(streq_ptr(a[3], "four=44\"44"));
89 assert_se(streq_ptr(a[4], "five=55\'55FIVEcinco"));
90 assert_se(streq_ptr(a[5], "six=seis sechs sis"));
91 assert_se(streq_ptr(a[6], "seven=sevenval#nocomment"));
92 assert_se(streq_ptr(a[7], "eight=eightval #nocomment"));
93 assert_se(streq_ptr(a[8], "export nine=nineval"));
94 assert_se(streq_ptr(a[9], "ten="));
ebc05a09
HH
95 assert_se(a[10] == NULL);
96
039f0e70 97 strv_env_clean(a);
ebc05a09 98
ebc05a09
HH
99 k = 0;
100 STRV_FOREACH(i, b) {
101 log_info("Got2: <%s>", *i);
102 assert_se(streq(*i, a[k++]));
103 }
104
f73141d7
LP
105 r = parse_env_file(
106 t, NULL,
107 "one", &one,
108 "two", &two,
109 "three", &three,
110 "four", &four,
111 "five", &five,
112 "six", &six,
113 "seven", &seven,
db537209 114 "eight", &eight,
ebc05a09
HH
115 "export nine", &nine,
116 "ten", &ten,
f73141d7
LP
117 NULL);
118
119 assert_se(r >= 0);
120
121 log_info("one=[%s]", strna(one));
122 log_info("two=[%s]", strna(two));
123 log_info("three=[%s]", strna(three));
124 log_info("four=[%s]", strna(four));
125 log_info("five=[%s]", strna(five));
126 log_info("six=[%s]", strna(six));
127 log_info("seven=[%s]", strna(seven));
db537209 128 log_info("eight=[%s]", strna(eight));
ebc05a09
HH
129 log_info("export nine=[%s]", strna(nine));
130 log_info("ten=[%s]", strna(nine));
f73141d7
LP
131
132 assert_se(streq(one, "BAR"));
133 assert_se(streq(two, "bar"));
134 assert_se(streq(three, "333\nxxxx"));
135 assert_se(streq(four, "44\"44"));
136 assert_se(streq(five, "55\'55FIVEcinco"));
137 assert_se(streq(six, "seis sechs sis"));
98f59e59
HH
138 assert_se(streq(seven, "sevenval#nocomment"));
139 assert_se(streq(eight, "eightval #nocomment"));
ebc05a09
HH
140 assert_se(streq(nine, "nineval"));
141 assert_se(ten == NULL);
f73141d7 142
095b30cb 143 r = write_env_file(p, a);
98f59e59
HH
144 assert_se(r >= 0);
145
717603e3 146 r = load_env_file(NULL, p, NULL, &b);
98f59e59
HH
147 assert_se(r >= 0);
148
f73141d7 149 unlink(t);
095b30cb 150 unlink(p);
f73141d7
LP
151}
152
ac4c8d6d
ZJS
153static void test_parse_multiline_env_file(void) {
154 char t[] = "/tmp/test-fileio-in-XXXXXX",
155 p[] = "/tmp/test-fileio-out-XXXXXX";
156 int fd, r;
157 FILE *f;
158 _cleanup_strv_free_ char **a = NULL, **b = NULL;
159 char **i;
160
2d5bdf5b 161 fd = mkostemp_safe(p, O_RDWR|O_CLOEXEC);
d514feaa
TA
162 assert_se(fd >= 0);
163 close(fd);
ac4c8d6d 164
2d5bdf5b 165 fd = mkostemp_safe(t, O_RDWR|O_CLOEXEC);
ac4c8d6d
ZJS
166 assert_se(fd >= 0);
167
168 f = fdopen(fd, "w");
169 assert_se(f);
170
171 fputs("one=BAR\\\n"
172 " VAR\\\n"
173 "\tGAR\n"
174 "#comment\n"
175 "two=\"bar\\\n"
176 " var\\\n"
177 "\tgar\"\n"
178 "#comment\n"
179 "tri=\"bar \\\n"
180 " var \\\n"
181 "\tgar \"\n", f);
182
183 fflush(f);
184 fclose(f);
185
717603e3 186 r = load_env_file(NULL, t, NULL, &a);
ac4c8d6d
ZJS
187 assert_se(r >= 0);
188
189 STRV_FOREACH(i, a)
190 log_info("Got: <%s>", *i);
191
5fba7bbf
TA
192 assert_se(streq_ptr(a[0], "one=BAR VAR\tGAR"));
193 assert_se(streq_ptr(a[1], "two=bar var\tgar"));
194 assert_se(streq_ptr(a[2], "tri=bar var \tgar "));
ac4c8d6d
ZJS
195 assert_se(a[3] == NULL);
196
197 r = write_env_file(p, a);
198 assert_se(r >= 0);
199
717603e3 200 r = load_env_file(NULL, p, NULL, &b);
ac4c8d6d
ZJS
201 assert_se(r >= 0);
202
203 unlink(t);
204 unlink(p);
205}
206
207
68fee104
ZJS
208static void test_executable_is_script(void) {
209 char t[] = "/tmp/test-executable-XXXXXX";
210 int fd, r;
211 FILE *f;
212 char *command;
213
2d5bdf5b 214 fd = mkostemp_safe(t, O_RDWR|O_CLOEXEC);
68fee104
ZJS
215 assert_se(fd >= 0);
216
217 f = fdopen(fd, "w");
218 assert_se(f);
219
220 fputs("#! /bin/script -a -b \ngoo goo", f);
221 fflush(f);
222
223 r = executable_is_script(t, &command);
224 assert_se(r > 0);
225 assert_se(streq(command, "/bin/script"));
226 free(command);
227
228 r = executable_is_script("/bin/sh", &command);
229 assert_se(r == 0);
230
231 r = executable_is_script("/usr/bin/yum", &command);
232 assert_se(r > 0 || r == -ENOENT);
233 if (r > 0) {
234 assert_se(startswith(command, "/"));
235 free(command);
236 }
237
238 fclose(f);
239 unlink(t);
240}
241
69ab8088 242static void test_status_field(void) {
1e5413f7
ZJS
243 _cleanup_free_ char *t = NULL, *p = NULL, *s = NULL, *z = NULL;
244 unsigned long long total = 0, buffers = 0;
442e0083 245 int r;
69ab8088 246
c4cd1d4d 247 assert_se(get_proc_field("/proc/self/status", "Threads", WHITESPACE, &t) == 0);
69ab8088
ZJS
248 puts(t);
249 assert_se(streq(t, "1"));
250
c4cd1d4d 251 r = get_proc_field("/proc/meminfo", "MemTotal", WHITESPACE, &p);
1e5413f7 252 if (r != -ENOENT) {
bdf7026e 253 assert_se(r == 0);
1e5413f7
ZJS
254 puts(p);
255 assert_se(safe_atollu(p, &total) == 0);
256 }
69ab8088 257
c4cd1d4d 258 r = get_proc_field("/proc/meminfo", "Buffers", WHITESPACE, &s);
1e5413f7 259 if (r != -ENOENT) {
bdf7026e 260 assert_se(r == 0);
1e5413f7
ZJS
261 puts(s);
262 assert_se(safe_atollu(s, &buffers) == 0);
263 }
69ab8088 264
2b01a801 265 if (p)
bdf7026e 266 assert_se(buffers < total);
1e5413f7
ZJS
267
268 /* Seccomp should be a good test for field full of zeros. */
c4cd1d4d 269 r = get_proc_field("/proc/meminfo", "Seccomp", WHITESPACE, &z);
1e5413f7 270 if (r != -ENOENT) {
bdf7026e 271 assert_se(r == 0);
1e5413f7
ZJS
272 puts(z);
273 assert_se(safe_atollu(z, &buffers) == 0);
274 }
275}
276
277static void test_capeff(void) {
278 int pid, p;
279
280 for (pid = 0; pid < 2; pid++) {
281 _cleanup_free_ char *capeff = NULL;
282 int r;
283
284 r = get_process_capeff(0, &capeff);
285 log_info("capeff: '%s' (r=%d)", capeff, r);
286
287 if (r == -ENOENT || r == -EPERM)
288 return;
289
bdf7026e
TA
290 assert_se(r == 0);
291 assert_se(*capeff);
1e5413f7 292 p = capeff[strspn(capeff, DIGITS "abcdefABCDEF")];
bdf7026e 293 assert_se(!p || isspace(p));
1e5413f7 294 }
69ab8088
ZJS
295}
296
0709b743
RC
297static void test_write_string_stream(void) {
298 char fn[] = "/tmp/test-write_string_stream-XXXXXX";
299 _cleanup_fclose_ FILE *f = NULL;
300 int fd;
301 char buf[64];
302
303 fd = mkostemp_safe(fn, O_RDWR);
304 assert_se(fd >= 0);
305
306 f = fdopen(fd, "r");
307 assert_se(f);
40beecdb 308 assert_se(write_string_stream(f, "boohoo", true) < 0);
0709b743 309
76082570 310 f = freopen(fn, "r+", f);
0709b743
RC
311 assert_se(f);
312
40beecdb 313 assert_se(write_string_stream(f, "boohoo", true) == 0);
0709b743
RC
314 rewind(f);
315
316 assert_se(fgets(buf, sizeof(buf), f));
317 assert_se(streq(buf, "boohoo\n"));
318
40beecdb
DM
319 f = freopen(fn, "w+", f);
320 assert_se(f);
321
322 assert_se(write_string_stream(f, "boohoo", false) == 0);
323 rewind(f);
324
325 assert_se(fgets(buf, sizeof(buf), f));
326 printf(">%s<", buf);
327 assert_se(streq(buf, "boohoo"));
328
0709b743
RC
329 unlink(fn);
330}
331
332static void test_write_string_file(void) {
333 char fn[] = "/tmp/test-write_string_file-XXXXXX";
76082570
RC
334 char buf[64] = {};
335 _cleanup_close_ int fd;
0709b743
RC
336
337 fd = mkostemp_safe(fn, O_RDWR);
338 assert_se(fd >= 0);
339
4c1fc3e4 340 assert_se(write_string_file(fn, "boohoo", WRITE_STRING_FILE_CREATE) == 0);
0709b743 341
cca0efb0 342 assert_se(read(fd, buf, sizeof(buf)) == 7);
0709b743
RC
343 assert_se(streq(buf, "boohoo\n"));
344
345 unlink(fn);
346}
347
e07995a3
RC
348static void test_write_string_file_no_create(void) {
349 char fn[] = "/tmp/test-write_string_file_no_create-XXXXXX";
350 _cleanup_close_ int fd;
351 char buf[64] = {0};
352
353 fd = mkostemp_safe(fn, O_RDWR);
354 assert_se(fd >= 0);
355
4c1fc3e4
DM
356 assert_se(write_string_file("/a/file/which/does/not/exists/i/guess", "boohoo", 0) < 0);
357 assert_se(write_string_file(fn, "boohoo", 0) == 0);
e07995a3 358
696c24fc 359 assert_se(read(fd, buf, sizeof(buf)) == strlen("boohoo\n"));
e07995a3
RC
360 assert_se(streq(buf, "boohoo\n"));
361
362 unlink(fn);
363}
364
e07995a3
RC
365static void test_load_env_file_pairs(void) {
366 char fn[] = "/tmp/test-load_env_file_pairs-XXXXXX";
367 int fd;
368 int r;
369 _cleanup_fclose_ FILE *f = NULL;
370 _cleanup_strv_free_ char **l = NULL;
371 char **k, **v;
372
373 fd = mkostemp_safe(fn, O_RDWR);
374 assert_se(fd >= 0);
375
376 r = write_string_file(fn,
377 "NAME=\"Arch Linux\"\n"
378 "ID=arch\n"
379 "PRETTY_NAME=\"Arch Linux\"\n"
380 "ANSI_COLOR=\"0;36\"\n"
381 "HOME_URL=\"https://www.archlinux.org/\"\n"
382 "SUPPORT_URL=\"https://bbs.archlinux.org/\"\n"
4c1fc3e4
DM
383 "BUG_REPORT_URL=\"https://bugs.archlinux.org/\"\n",
384 WRITE_STRING_FILE_CREATE);
e07995a3
RC
385 assert_se(r == 0);
386
387 f = fdopen(fd, "r");
388 assert_se(f);
389
390 r = load_env_file_pairs(f, fn, NULL, &l);
391 assert_se(r >= 0);
392
393 assert_se(strv_length(l) == 14);
394 STRV_FOREACH_PAIR(k, v, l) {
395 assert_se(STR_IN_SET(*k, "NAME", "ID", "PRETTY_NAME", "ANSI_COLOR", "HOME_URL", "SUPPORT_URL", "BUG_REPORT_URL"));
396 printf("%s=%s\n", *k, *v);
397 if (streq(*k, "NAME")) assert_se(streq(*v, "Arch Linux"));
398 if (streq(*k, "ID")) assert_se(streq(*v, "arch"));
399 if (streq(*k, "PRETTY_NAME")) assert_se(streq(*v, "Arch Linux"));
400 if (streq(*k, "ANSI_COLOR")) assert_se(streq(*v, "0;36"));
401 if (streq(*k, "HOME_URL")) assert_se(streq(*v, "https://www.archlinux.org/"));
402 if (streq(*k, "SUPPORT_URL")) assert_se(streq(*v, "https://bbs.archlinux.org/"));
403 if (streq(*k, "BUG_REPORT_URL")) assert_se(streq(*v, "https://bugs.archlinux.org/"));
404 }
405
406 unlink(fn);
407}
408
f73141d7 409int main(int argc, char *argv[]) {
1e5413f7
ZJS
410 log_parse_environment();
411 log_open();
412
f73141d7 413 test_parse_env_file();
ac4c8d6d 414 test_parse_multiline_env_file();
68fee104 415 test_executable_is_script();
69ab8088 416 test_status_field();
1e5413f7 417 test_capeff();
0709b743
RC
418 test_write_string_stream();
419 test_write_string_file();
e07995a3 420 test_write_string_file_no_create();
e07995a3 421 test_load_env_file_pairs();
1e5413f7 422
f73141d7
LP
423 return 0;
424}