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