#include "strv.h"
#include "tests.h"
#include "tmpfile-util.h"
-#include "util.h"
-static void test_parse_env_file(void) {
+TEST(parse_env_file) {
_cleanup_(unlink_tempfilep) char
t[] = "/tmp/test-fileio-in-XXXXXX",
p[] = "/tmp/test-fileio-out-XXXXXX";
*six = NULL, *seven = NULL, *eight = NULL, *nine = NULL, *ten = NULL,
*eleven = NULL, *twelve = NULL, *thirteen = NULL;
_cleanup_strv_free_ char **a = NULL, **b = NULL;
- char **i;
unsigned k;
int r;
"eleven", &eleven,
"twelve", &twelve,
"thirteen", &thirteen);
-
- assert_se(r >= 0);
+ assert_se(r == 0);
log_info("one=[%s]", strna(one));
log_info("two=[%s]", strna(two));
assert_se(streq(from_shell, value));
}
-static void test_parse_multiline_env_file(void) {
+TEST(parse_multiline_env_file) {
_cleanup_(unlink_tempfilep) char
t[] = "/tmp/test-fileio-in-XXXXXX",
p[] = "/tmp/test-fileio-out-XXXXXX";
FILE *f;
_cleanup_strv_free_ char **a = NULL, **b = NULL;
- char **i;
int r;
assert_se(fmkostemp_safe(t, "w", &f) == 0);
assert_se(r >= 0);
}
-static void test_merge_env_file(void) {
+TEST(merge_env_file) {
_cleanup_(unlink_tempfilep) char t[] = "/tmp/test-fileio-XXXXXX";
_cleanup_fclose_ FILE *f = NULL;
_cleanup_strv_free_ char **a = NULL;
- char **i;
int r;
assert_se(fmkostemp_safe(t, "w", &f) == 0);
"zzzz=${foobar:-${nothing}}\n"
"zzzzz=${nothing:+${nothing}}\n"
, WRITE_STRING_FILE_AVOID_NEWLINE);
- assert(r >= 0);
+ assert_se(r >= 0);
r = merge_env_file(&a, NULL, t);
assert_se(r >= 0);
assert_se(a[10] == NULL);
}
-static void test_merge_env_file_invalid(void) {
+TEST(merge_env_file_invalid) {
_cleanup_(unlink_tempfilep) char t[] = "/tmp/test-fileio-XXXXXX";
_cleanup_fclose_ FILE *f = NULL;
_cleanup_strv_free_ char **a = NULL;
- char **i;
int r;
assert_se(fmkostemp_safe(t, "w", &f) == 0);
"#\n"
"\n\n" /* empty line */
, WRITE_STRING_FILE_AVOID_NEWLINE);
- assert(r >= 0);
+ assert_se(r >= 0);
r = merge_env_file(&a, NULL, t);
assert_se(r >= 0);
assert_se(strv_isempty(a));
}
-static void test_executable_is_script(void) {
+TEST(executable_is_script) {
_cleanup_(unlink_tempfilep) char t[] = "/tmp/test-fileio-XXXXXX";
_cleanup_fclose_ FILE *f = NULL;
char *command;
int r;
- log_info("/* %s */", __func__);
-
assert_se(fmkostemp_safe(t, "w", &f) == 0);
fputs("#! /bin/script -a -b \ngoo goo", f);
fflush(f);
}
}
-static void test_status_field(void) {
+TEST(status_field) {
_cleanup_free_ char *t = NULL, *p = NULL, *s = NULL, *z = NULL;
unsigned long long total = 0, buffers = 0;
int r;
- log_info("/* %s */", __func__);
-
assert_se(get_proc_field("/proc/self/status", "Threads", WHITESPACE, &t) == 0);
puts(t);
assert_se(streq(t, "1"));
}
}
-static void test_capeff(void) {
- log_info("/* %s */", __func__);
-
+TEST(capeff) {
for (int pid = 0; pid < 2; pid++) {
_cleanup_free_ char *capeff = NULL;
int r, p;
}
}
-static void test_write_string_stream(void) {
+TEST(write_string_stream) {
_cleanup_(unlink_tempfilep) char fn[] = "/tmp/test-write_string_stream-XXXXXX";
_cleanup_fclose_ FILE *f = NULL;
int fd;
char buf[64];
- log_info("/* %s */", __func__);
-
fd = mkostemp_safe(fn);
assert_se(fd >= 0);
assert_se(streq(buf, "boohoo"));
}
-static void test_write_string_file(void) {
+TEST(write_string_file) {
_cleanup_(unlink_tempfilep) char fn[] = "/tmp/test-write_string_file-XXXXXX";
char buf[64] = {};
_cleanup_close_ int fd;
- log_info("/* %s */", __func__);
-
fd = mkostemp_safe(fn);
assert_se(fd >= 0);
assert_se(streq(buf, "boohoo\n"));
}
-static void test_write_string_file_no_create(void) {
+TEST(write_string_file_no_create) {
_cleanup_(unlink_tempfilep) char fn[] = "/tmp/test-write_string_file_no_create-XXXXXX";
_cleanup_close_ int fd;
char buf[64] = {};
- log_info("/* %s */", __func__);
-
fd = mkostemp_safe(fn);
assert_se(fd >= 0);
assert_se(streq(buf, "boohoo\n"));
}
-static void test_write_string_file_verify(void) {
+TEST(write_string_file_verify) {
_cleanup_free_ char *buf = NULL, *buf2 = NULL;
int r;
- log_info("/* %s */", __func__);
-
r = read_one_line_file("/proc/version", &buf);
if (ERRNO_IS_PRIVILEGE(r))
return;
assert_se(write_string_file("/proc/version", buf2, WRITE_STRING_FILE_VERIFY_ON_FAILURE|WRITE_STRING_FILE_AVOID_NEWLINE) == 0);
}
-static void test_load_env_file_pairs(void) {
+TEST(load_env_file_pairs) {
_cleanup_(unlink_tempfilep) char fn[] = "/tmp/test-load_env_file_pairs-XXXXXX";
int fd, r;
_cleanup_fclose_ FILE *f = NULL;
_cleanup_strv_free_ char **l = NULL;
- char **k, **v;
-
- log_info("/* %s */", __func__);
fd = mkostemp_safe(fn);
assert_se(fd >= 0);
}
}
-static void test_search_and_fopen(void) {
+TEST(search_and_fopen) {
static const char* const dirs[] = {
"/tmp/foo/bar",
"/tmp",
char name[] = "/tmp/test-search_and_fopen.XXXXXX";
_cleanup_fclose_ FILE *f = NULL;
_cleanup_free_ char *p = NULL;
- _cleanup_close_ int fd = -1;
+ _cleanup_close_ int fd = -EBADF;
const char *e;
int r;
- log_info("/* %s */", __func__);
-
fd = mkostemp_safe(name);
assert_se(fd >= 0);
fd = safe_close(fd);
f = safe_fclose(f);
p = mfree(p);
- r = search_and_fopen("/a/file/which/does/not/exist/i/guess", "r", NULL, (const char**) dirs, &f, &p);
+ r = search_and_fopen("/a/file/which/does/not/exist/i/guess", "re", NULL, (const char**) dirs, &f, &p);
assert_se(r == -ENOENT);
- r = search_and_fopen("afilewhichdoesnotexistiguess", "r", NULL, (const char**) dirs, &f, &p);
+ r = search_and_fopen("afilewhichdoesnotexistiguess", "re", NULL, (const char**) dirs, &f, &p);
assert_se(r == -ENOENT);
r = unlink(name);
assert_se(r == 0);
- r = search_and_fopen(basename(name), "r", NULL, (const char**) dirs, &f, &p);
+ r = search_and_fopen(basename(name), "re", NULL, (const char**) dirs, &f, &p);
assert_se(r == -ENOENT);
}
-static void test_search_and_fopen_nulstr(void) {
+TEST(search_and_fopen_nulstr) {
static const char dirs[] =
"/tmp/foo/bar\0"
"/tmp\0";
- log_info("/* %s */", __func__);
-
_cleanup_(unlink_tempfilep) char name[] = "/tmp/test-search_and_fopen.XXXXXX";
_cleanup_fclose_ FILE *f = NULL;
_cleanup_free_ char *p = NULL;
- _cleanup_close_ int fd = -1;
+ _cleanup_close_ int fd = -EBADF;
const char *e;
int r;
f = safe_fclose(f);
p = mfree(p);
- r = search_and_fopen_nulstr("/a/file/which/does/not/exist/i/guess", "r", NULL, dirs, &f, &p);
+ r = search_and_fopen_nulstr("/a/file/which/does/not/exist/i/guess", "re", NULL, dirs, &f, &p);
assert_se(r == -ENOENT);
- r = search_and_fopen_nulstr("afilewhichdoesnotexistiguess", "r", NULL, dirs, &f, &p);
+ r = search_and_fopen_nulstr("afilewhichdoesnotexistiguess", "re", NULL, dirs, &f, &p);
assert_se(r == -ENOENT);
r = unlink(name);
assert_se(r == 0);
- r = search_and_fopen_nulstr(basename(name), "r", NULL, dirs, &f, &p);
+ r = search_and_fopen_nulstr(basename(name), "re", NULL, dirs, &f, &p);
assert_se(r == -ENOENT);
}
-static void test_writing_tmpfile(void) {
+TEST(writing_tmpfile) {
_cleanup_(unlink_tempfilep) char name[] = "/tmp/test-systemd_writing_tmpfile.XXXXXX";
_cleanup_free_ char *contents = NULL;
size_t size;
- _cleanup_close_ int fd = -1;
+ _cleanup_close_ int fd = -EBADF;
int r;
- log_info("/* %s */", __func__);
-
struct iovec iov[] = {
IOVEC_MAKE_STRING("abc\n"),
IOVEC_MAKE_STRING(ALPHANUMERICAL "\n"),
assert_se(streq(contents, "abc\n" ALPHANUMERICAL "\n"));
}
-static void test_tempfn(void) {
+TEST(tempfn) {
char *ret = NULL, *p;
- log_info("/* %s */", __func__);
-
assert_se(tempfn_xxxxxx("/foo/bar/waldo", NULL, &ret) >= 0);
assert_se(streq_ptr(ret, "/foo/bar/.#waldoXXXXXX"));
free(ret);
DISABLE_WARNING_TYPE_LIMITS;
-static void test_fgetc(void) {
+TEST(fgetc) {
_cleanup_fclose_ FILE *f = NULL;
char c;
- assert_se(f = fmemopen_unlocked((void*) chars, sizeof(chars), "re"));
+ assert_se(f = fmemopen_unlocked((void*) chars, sizeof(chars), "r"));
for (size_t i = 0; i < sizeof(chars); i++) {
assert_se(safe_fgetc(f, &c) == 1);
assert_se(read_line(f, 1024, &line) == 0 && streq(line, ""));
}
-static void test_read_line(void) {
+TEST(read_line1) {
_cleanup_fclose_ FILE *f = NULL;
- log_info("/* %s */", __func__);
-
- assert_se(f = fmemopen_unlocked((void*) buffer, sizeof(buffer), "re"));
+ assert_se(f = fmemopen_unlocked((void*) buffer, sizeof(buffer), "r"));
test_read_line_one_file(f);
}
-static void test_read_line2(void) {
+TEST(read_line2) {
_cleanup_(unlink_tempfilep) char name[] = "/tmp/test-fileio.XXXXXX";
int fd;
_cleanup_fclose_ FILE *f = NULL;
- log_info("/* %s */", __func__);
-
fd = mkostemp_safe(name);
assert_se(fd >= 0);
assert_se((size_t) write(fd, buffer, sizeof(buffer)) == sizeof(buffer));
test_read_line_one_file(f);
}
-static void test_read_line3(void) {
+TEST(read_line3) {
_cleanup_fclose_ FILE *f = NULL;
_cleanup_free_ char *line = NULL;
int r;
- log_info("/* %s */", __func__);
-
f = fopen("/proc/uptime", "re");
if (!f && IN_SET(errno, ENOENT, EPERM))
return;
assert_se(read_line(f, LINE_MAX, NULL) == 0);
}
-static void test_read_line4(void) {
+TEST(read_line4) {
static const struct {
size_t length;
const char *string;
}
}
-static void test_read_nul_string(void) {
+TEST(read_nul_string) {
static const char test[] = "string nr. 1\0"
"string nr. 2\n\0"
"\377empty string follows\0"
_cleanup_fclose_ FILE *f = NULL;
_cleanup_free_ char *s = NULL;
- log_info("/* %s */", __func__);
-
assert_se(f = fmemopen_unlocked((void*) test, sizeof(test)-1, "r"));
assert_se(read_nul_string(f, LONG_LINE_MAX, &s) == 13 && streq_ptr(s, "string nr. 1"));
assert_se(read_nul_string(f, LONG_LINE_MAX, &s) == 0 && streq_ptr(s, ""));
}
-static void test_read_full_file_socket(void) {
+TEST(read_full_file_socket) {
_cleanup_(rm_rf_physical_and_freep) char *z = NULL;
_cleanup_close_ int listener = -1;
_cleanup_free_ char *data = NULL, *clientname = NULL;
union sockaddr_union sa;
- const char *j;
+ const char *j, *jj;
size_t size;
pid_t pid;
int r;
- log_info("/* %s */", __func__);
-
listener = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0);
assert_se(listener >= 0);
assert_se(bind(listener, &sa.sa, SOCKADDR_UN_LEN(sa.un)) >= 0);
assert_se(listen(listener, 1) >= 0);
+ /* Make sure the socket doesn't fit into a struct sockaddr_un, but we can still access it */
+ jj = strjoina(z, "/a_very_long_patha_very_long_patha_very_long_patha_very_long_patha_very_long_patha_very_long_patha_very_long_patha_very_long_path");
+ assert_se(strlen(jj) > sizeof_field(struct sockaddr_un, sun_path));
+ assert_se(rename(j, jj) >= 0);
+
/* Bind the *client* socket to some randomized name, to verify that this works correctly. */
assert_se(asprintf(&clientname, "@%" PRIx64 "/test-bindname", random_u64()) >= 0);
if (r == 0) {
union sockaddr_union peer = {};
socklen_t peerlen = sizeof(peer);
- _cleanup_close_ int rfd = -1;
+ _cleanup_close_ int rfd = -EBADF;
/* child */
rfd = accept4(listener, NULL, 0, SOCK_CLOEXEC);
_exit(EXIT_SUCCESS);
}
- assert_se(read_full_file_full(AT_FDCWD, j, UINT64_MAX, SIZE_MAX, 0, NULL, &data, &size) == -ENXIO);
- assert_se(read_full_file_full(AT_FDCWD, j, UINT64_MAX, SIZE_MAX, READ_FULL_FILE_CONNECT_SOCKET, clientname, &data, &size) >= 0);
+ assert_se(read_full_file_full(AT_FDCWD, jj, UINT64_MAX, SIZE_MAX, 0, NULL, &data, &size) == -ENXIO);
+ assert_se(read_full_file_full(AT_FDCWD, jj, UINT64_MAX, SIZE_MAX, READ_FULL_FILE_CONNECT_SOCKET, clientname, &data, &size) >= 0);
assert_se(size == strlen(TEST_STR));
assert_se(streq(data, TEST_STR));
#undef TEST_STR
}
-static void test_read_full_file_offset_size(void) {
+TEST(read_full_file_offset_size) {
_cleanup_fclose_ FILE *f = NULL;
_cleanup_(unlink_and_freep) char *fn = NULL;
_cleanup_free_ char *rbuf = NULL;
size_t rbuf_size;
uint8_t buf[4711];
- log_info("/* %s */", __func__);
-
random_bytes(buf, sizeof(buf));
assert_se(tempfn_random_child(NULL, NULL, &fn) >= 0);
assert_se(memcmp(buf, rbuf, rbuf_size) == 0);
rbuf = mfree(rbuf);
+ assert_se(read_full_file_full(AT_FDCWD, fn, UINT64_MAX, 128, READ_FULL_FILE_FAIL_WHEN_LARGER, NULL, &rbuf, &rbuf_size) == -E2BIG);
+ assert_se(read_full_file_full(AT_FDCWD, fn, UINT64_MAX, sizeof(buf)-1, READ_FULL_FILE_FAIL_WHEN_LARGER, NULL, &rbuf, &rbuf_size) == -E2BIG);
+ assert_se(read_full_file_full(AT_FDCWD, fn, UINT64_MAX, sizeof(buf), READ_FULL_FILE_FAIL_WHEN_LARGER, NULL, &rbuf, &rbuf_size) >= 0);
+ assert_se(rbuf_size == sizeof(buf));
+ assert_se(memcmp(buf, rbuf, rbuf_size) == 0);
+ rbuf = mfree(rbuf);
+
+ assert_se(read_full_file_full(AT_FDCWD, fn, 47, 128, READ_FULL_FILE_FAIL_WHEN_LARGER, NULL, &rbuf, &rbuf_size) == -E2BIG);
+ assert_se(read_full_file_full(AT_FDCWD, fn, 47, sizeof(buf)-47-1, READ_FULL_FILE_FAIL_WHEN_LARGER, NULL, &rbuf, &rbuf_size) == -E2BIG);
+ assert_se(read_full_file_full(AT_FDCWD, fn, 47, sizeof(buf)-47, READ_FULL_FILE_FAIL_WHEN_LARGER, NULL, &rbuf, &rbuf_size) >= 0);
+ assert_se(rbuf_size == sizeof(buf)-47);
+ assert_se(memcmp(buf+47, rbuf, rbuf_size) == 0);
+ rbuf = mfree(rbuf);
+
+ assert_se(read_full_file_full(AT_FDCWD, fn, UINT64_MAX, sizeof(buf)+1, READ_FULL_FILE_FAIL_WHEN_LARGER, NULL, &rbuf, &rbuf_size) >= 0);
+ assert_se(rbuf_size == sizeof(buf));
+ assert_se(memcmp(buf, rbuf, rbuf_size) == 0);
+ rbuf = mfree(rbuf);
+
assert_se(read_full_file_full(AT_FDCWD, fn, 1234, SIZE_MAX, 0, NULL, &rbuf, &rbuf_size) >= 0);
assert_se(rbuf_size == sizeof(buf) - 1234);
assert_se(memcmp(buf + 1234, rbuf, rbuf_size) == 0);
rbuf = mfree(rbuf);
}
-static void test_read_virtual_file(size_t max_size) {
- const char *filename;
+static void test_read_virtual_file_one(size_t max_size) {
int r;
log_info("/* %s (max_size=%zu) */", __func__, max_size);
FOREACH_STRING(filename,
"/proc/1/cmdline",
"/etc/nsswitch.conf",
- "/sys/kernel/uevent_seqnum") {
+ "/sys/kernel/uevent_seqnum",
+ "/proc/kcore",
+ "/proc/kallsyms",
+ "/proc/self/exe",
+ "/proc/self/pagemap") {
_cleanup_free_ char *buf = NULL;
size_t size = 0;
r = read_virtual_file(filename, max_size, &buf, &size);
if (r < 0) {
log_info_errno(r, "read_virtual_file(\"%s\", %zu): %m", filename, max_size);
- assert_se(ERRNO_IS_PRIVILEGE(r) || r == -ENOENT);
+ assert_se(ERRNO_IS_PRIVILEGE(r) || /* /proc/kcore is not accessible to unpriv */
+ IN_SET(r,
+ -ENOENT, /* Some of the files might be absent */
+ -EINVAL, /* too small reads from /proc/self/pagemap trigger EINVAL */
+ -EFBIG)); /* /proc/kcore and /proc/self/pagemap should be too large */
} else
log_info("read_virtual_file(\"%s\", %zu): %s (%zu bytes)", filename, max_size, r ? "non-truncated" : "truncated", size);
}
}
-int main(int argc, char *argv[]) {
- test_setup_logging(LOG_DEBUG);
-
- test_parse_env_file();
- test_parse_multiline_env_file();
- test_merge_env_file();
- test_merge_env_file_invalid();
- test_executable_is_script();
- test_status_field();
- test_capeff();
- test_write_string_stream();
- test_write_string_file();
- test_write_string_file_no_create();
- test_write_string_file_verify();
- test_load_env_file_pairs();
- test_search_and_fopen();
- test_search_and_fopen_nulstr();
- test_writing_tmpfile();
- test_tempfn();
- test_fgetc();
- test_read_line();
- test_read_line2();
- test_read_line3();
- test_read_line4();
- test_read_nul_string();
- test_read_full_file_socket();
- test_read_full_file_offset_size();
- test_read_virtual_file(0);
- test_read_virtual_file(1);
- test_read_virtual_file(2);
- test_read_virtual_file(20);
- test_read_virtual_file(4096);
- test_read_virtual_file(4097);
- test_read_virtual_file(SIZE_MAX);
-
- return 0;
+TEST(test_read_virtual_file) {
+ test_read_virtual_file_one(0);
+ test_read_virtual_file_one(1);
+ test_read_virtual_file_one(2);
+ test_read_virtual_file_one(20);
+ test_read_virtual_file_one(4096);
+ test_read_virtual_file_one(4097);
+ test_read_virtual_file_one(SIZE_MAX);
}
+
+DEFINE_TEST_MAIN(LOG_DEBUG);