1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2013 Lennart Poettering
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.
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.
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/>.
26 #include "alloc-util.h"
32 #include "parse-util.h"
33 #include "process-util.h"
34 #include "string-util.h"
38 static void test_parse_env_file(void) {
39 char t
[] = "/tmp/test-fileio-in-XXXXXX",
40 p
[] = "/tmp/test-fileio-out-XXXXXX";
43 _cleanup_free_
char *one
= NULL
, *two
= NULL
, *three
= NULL
, *four
= NULL
, *five
= NULL
,
44 *six
= NULL
, *seven
= NULL
, *eight
= NULL
, *nine
= NULL
, *ten
= NULL
;
45 _cleanup_strv_free_
char **a
= NULL
, **b
= NULL
;
49 fd
= mkostemp_safe(p
, O_RDWR
|O_CLOEXEC
);
53 fd
= mkostemp_safe(t
, O_RDWR
|O_CLOEXEC
);
65 "invalid line #comment\n"
68 "four = \'44\\\"44\'\n"
69 "five = \'55\\\'55\' \"FIVE\" cinco \n"
70 "six = seis sechs\\\n"
72 "seven=\"sevenval\" #nocomment\n"
73 "eight=eightval #nocomment\n"
74 "export nine=nineval\n"
80 r
= load_env_file(NULL
, t
, NULL
, &a
);
84 log_info("Got: <%s>", *i
);
86 assert_se(streq_ptr(a
[0], "one=BAR"));
87 assert_se(streq_ptr(a
[1], "two=bar"));
88 assert_se(streq_ptr(a
[2], "three=333\nxxxx"));
89 assert_se(streq_ptr(a
[3], "four=44\"44"));
90 assert_se(streq_ptr(a
[4], "five=55\'55FIVEcinco"));
91 assert_se(streq_ptr(a
[5], "six=seis sechs sis"));
92 assert_se(streq_ptr(a
[6], "seven=sevenval#nocomment"));
93 assert_se(streq_ptr(a
[7], "eight=eightval #nocomment"));
94 assert_se(streq_ptr(a
[8], "export nine=nineval"));
95 assert_se(streq_ptr(a
[9], "ten="));
96 assert_se(a
[10] == NULL
);
102 log_info("Got2: <%s>", *i
);
103 assert_se(streq(*i
, a
[k
++]));
116 "export nine", &nine
,
122 log_info("one=[%s]", strna(one
));
123 log_info("two=[%s]", strna(two
));
124 log_info("three=[%s]", strna(three
));
125 log_info("four=[%s]", strna(four
));
126 log_info("five=[%s]", strna(five
));
127 log_info("six=[%s]", strna(six
));
128 log_info("seven=[%s]", strna(seven
));
129 log_info("eight=[%s]", strna(eight
));
130 log_info("export nine=[%s]", strna(nine
));
131 log_info("ten=[%s]", strna(nine
));
133 assert_se(streq(one
, "BAR"));
134 assert_se(streq(two
, "bar"));
135 assert_se(streq(three
, "333\nxxxx"));
136 assert_se(streq(four
, "44\"44"));
137 assert_se(streq(five
, "55\'55FIVEcinco"));
138 assert_se(streq(six
, "seis sechs sis"));
139 assert_se(streq(seven
, "sevenval#nocomment"));
140 assert_se(streq(eight
, "eightval #nocomment"));
141 assert_se(streq(nine
, "nineval"));
142 assert_se(ten
== NULL
);
144 r
= write_env_file(p
, a
);
147 r
= load_env_file(NULL
, p
, NULL
, &b
);
154 static void test_parse_multiline_env_file(void) {
155 char t
[] = "/tmp/test-fileio-in-XXXXXX",
156 p
[] = "/tmp/test-fileio-out-XXXXXX";
159 _cleanup_strv_free_
char **a
= NULL
, **b
= NULL
;
162 fd
= mkostemp_safe(p
, O_RDWR
|O_CLOEXEC
);
166 fd
= mkostemp_safe(t
, O_RDWR
|O_CLOEXEC
);
187 r
= load_env_file(NULL
, t
, NULL
, &a
);
191 log_info("Got: <%s>", *i
);
193 assert_se(streq_ptr(a
[0], "one=BAR VAR\tGAR"));
194 assert_se(streq_ptr(a
[1], "two=bar var\tgar"));
195 assert_se(streq_ptr(a
[2], "tri=bar var \tgar "));
196 assert_se(a
[3] == NULL
);
198 r
= write_env_file(p
, a
);
201 r
= load_env_file(NULL
, p
, NULL
, &b
);
209 static void test_executable_is_script(void) {
210 char t
[] = "/tmp/test-executable-XXXXXX";
215 fd
= mkostemp_safe(t
, O_RDWR
|O_CLOEXEC
);
221 fputs("#! /bin/script -a -b \ngoo goo", f
);
224 r
= executable_is_script(t
, &command
);
226 assert_se(streq(command
, "/bin/script"));
229 r
= executable_is_script("/bin/sh", &command
);
232 r
= executable_is_script("/usr/bin/yum", &command
);
233 assert_se(r
> 0 || r
== -ENOENT
);
235 assert_se(startswith(command
, "/"));
243 static void test_status_field(void) {
244 _cleanup_free_
char *t
= NULL
, *p
= NULL
, *s
= NULL
, *z
= NULL
;
245 unsigned long long total
= 0, buffers
= 0;
248 assert_se(get_proc_field("/proc/self/status", "Threads", WHITESPACE
, &t
) == 0);
250 assert_se(streq(t
, "1"));
252 r
= get_proc_field("/proc/meminfo", "MemTotal", WHITESPACE
, &p
);
256 assert_se(safe_atollu(p
, &total
) == 0);
259 r
= get_proc_field("/proc/meminfo", "Buffers", WHITESPACE
, &s
);
263 assert_se(safe_atollu(s
, &buffers
) == 0);
267 assert_se(buffers
< total
);
269 /* Seccomp should be a good test for field full of zeros. */
270 r
= get_proc_field("/proc/meminfo", "Seccomp", WHITESPACE
, &z
);
274 assert_se(safe_atollu(z
, &buffers
) == 0);
278 static void test_capeff(void) {
281 for (pid
= 0; pid
< 2; pid
++) {
282 _cleanup_free_
char *capeff
= NULL
;
285 r
= get_process_capeff(0, &capeff
);
286 log_info("capeff: '%s' (r=%d)", capeff
, r
);
288 if (r
== -ENOENT
|| r
== -EPERM
)
293 p
= capeff
[strspn(capeff
, DIGITS
"abcdefABCDEF")];
294 assert_se(!p
|| isspace(p
));
298 static void test_write_string_stream(void) {
299 char fn
[] = "/tmp/test-write_string_stream-XXXXXX";
300 _cleanup_fclose_
FILE *f
= NULL
;
304 fd
= mkostemp_safe(fn
, O_RDWR
);
309 assert_se(write_string_stream(f
, "boohoo", true) < 0);
311 f
= freopen(fn
, "r+", f
);
314 assert_se(write_string_stream(f
, "boohoo", true) == 0);
317 assert_se(fgets(buf
, sizeof(buf
), f
));
318 assert_se(streq(buf
, "boohoo\n"));
320 f
= freopen(fn
, "w+", f
);
323 assert_se(write_string_stream(f
, "boohoo", false) == 0);
326 assert_se(fgets(buf
, sizeof(buf
), f
));
328 assert_se(streq(buf
, "boohoo"));
333 static void test_write_string_file(void) {
334 char fn
[] = "/tmp/test-write_string_file-XXXXXX";
336 _cleanup_close_
int fd
;
338 fd
= mkostemp_safe(fn
, O_RDWR
);
341 assert_se(write_string_file(fn
, "boohoo", WRITE_STRING_FILE_CREATE
) == 0);
343 assert_se(read(fd
, buf
, sizeof(buf
)) == 7);
344 assert_se(streq(buf
, "boohoo\n"));
349 static void test_write_string_file_no_create(void) {
350 char fn
[] = "/tmp/test-write_string_file_no_create-XXXXXX";
351 _cleanup_close_
int fd
;
354 fd
= mkostemp_safe(fn
, O_RDWR
);
357 assert_se(write_string_file("/a/file/which/does/not/exists/i/guess", "boohoo", 0) < 0);
358 assert_se(write_string_file(fn
, "boohoo", 0) == 0);
360 assert_se(read(fd
, buf
, sizeof(buf
)) == strlen("boohoo\n"));
361 assert_se(streq(buf
, "boohoo\n"));
366 static void test_write_string_file_verify(void) {
367 _cleanup_free_
char *buf
= NULL
, *buf2
= NULL
;
370 assert_se(read_one_line_file("/proc/cmdline", &buf
) >= 0);
371 assert_se((buf2
= strjoin(buf
, "\n", NULL
)));
373 r
= write_string_file("/proc/cmdline", buf
, 0);
374 assert_se(r
== -EACCES
|| r
== -EIO
);
375 r
= write_string_file("/proc/cmdline", buf2
, 0);
376 assert_se(r
== -EACCES
|| r
== -EIO
);
378 assert_se(write_string_file("/proc/cmdline", buf
, WRITE_STRING_FILE_VERIFY_ON_FAILURE
) == 0);
379 assert_se(write_string_file("/proc/cmdline", buf2
, WRITE_STRING_FILE_VERIFY_ON_FAILURE
) == 0);
381 r
= write_string_file("/proc/cmdline", buf
, WRITE_STRING_FILE_VERIFY_ON_FAILURE
|WRITE_STRING_FILE_AVOID_NEWLINE
);
382 assert_se(r
== -EACCES
|| r
== -EIO
);
383 assert_se(write_string_file("/proc/cmdline", buf2
, WRITE_STRING_FILE_VERIFY_ON_FAILURE
|WRITE_STRING_FILE_AVOID_NEWLINE
) == 0);
386 static void test_load_env_file_pairs(void) {
387 char fn
[] = "/tmp/test-load_env_file_pairs-XXXXXX";
390 _cleanup_fclose_
FILE *f
= NULL
;
391 _cleanup_strv_free_
char **l
= NULL
;
394 fd
= mkostemp_safe(fn
, O_RDWR
);
397 r
= write_string_file(fn
,
398 "NAME=\"Arch Linux\"\n"
400 "PRETTY_NAME=\"Arch Linux\"\n"
401 "ANSI_COLOR=\"0;36\"\n"
402 "HOME_URL=\"https://www.archlinux.org/\"\n"
403 "SUPPORT_URL=\"https://bbs.archlinux.org/\"\n"
404 "BUG_REPORT_URL=\"https://bugs.archlinux.org/\"\n",
405 WRITE_STRING_FILE_CREATE
);
411 r
= load_env_file_pairs(f
, fn
, NULL
, &l
);
414 assert_se(strv_length(l
) == 14);
415 STRV_FOREACH_PAIR(k
, v
, l
) {
416 assert_se(STR_IN_SET(*k
, "NAME", "ID", "PRETTY_NAME", "ANSI_COLOR", "HOME_URL", "SUPPORT_URL", "BUG_REPORT_URL"));
417 printf("%s=%s\n", *k
, *v
);
418 if (streq(*k
, "NAME")) assert_se(streq(*v
, "Arch Linux"));
419 if (streq(*k
, "ID")) assert_se(streq(*v
, "arch"));
420 if (streq(*k
, "PRETTY_NAME")) assert_se(streq(*v
, "Arch Linux"));
421 if (streq(*k
, "ANSI_COLOR")) assert_se(streq(*v
, "0;36"));
422 if (streq(*k
, "HOME_URL")) assert_se(streq(*v
, "https://www.archlinux.org/"));
423 if (streq(*k
, "SUPPORT_URL")) assert_se(streq(*v
, "https://bbs.archlinux.org/"));
424 if (streq(*k
, "BUG_REPORT_URL")) assert_se(streq(*v
, "https://bugs.archlinux.org/"));
430 int main(int argc
, char *argv
[]) {
431 log_parse_environment();
434 test_parse_env_file();
435 test_parse_multiline_env_file();
436 test_executable_is_script();
439 test_write_string_stream();
440 test_write_string_file();
441 test_write_string_file_no_create();
442 test_write_string_file_verify();
443 test_load_env_file_pairs();