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