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