From b839101aacb38131f0f4313b1b76316e663e58e9 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 23 Mar 2023 12:33:41 +0100 Subject: fileio: add new helper fdopen_independent() This is a combination of fdopen() and fd_reopen(). i.e. it first reopens the fd, and then converts that into a FILE*. We do this at various places already manually. let's move this into a helper call of its own. --- src/test/test-fileio.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'src/test/test-fileio.c') diff --git a/src/test/test-fileio.c b/src/test/test-fileio.c index 2e05992c18..1a9a8a5ddc 100644 --- a/src/test/test-fileio.c +++ b/src/test/test-fileio.c @@ -14,6 +14,7 @@ #include "fileio.h" #include "fs-util.h" #include "io-util.h" +#include "memfd-util.h" #include "parse-util.h" #include "path-util.h" #include "process-util.h" @@ -1072,4 +1073,46 @@ TEST(test_read_virtual_file) { test_read_virtual_file_one(SIZE_MAX); } +TEST(test_fdopen_independent) { +#define TEST_TEXT "this is some random test text we are going to write to a memfd" + _cleanup_close_ int fd = -EBADF; + _cleanup_fclose_ FILE *f = NULL; + char buf[STRLEN(TEST_TEXT) + 1]; + + fd = memfd_new("fdopen_independent"); + if (fd < 0) { + assert_se(ERRNO_IS_NOT_SUPPORTED(fd)); + return; + } + + assert_se(write(fd, TEST_TEXT, strlen(TEST_TEXT)) == strlen(TEST_TEXT)); + /* we'll leave the read offset at the end of the memfd, the fdopen_independent() descriptors should + * start at the beginning anyway */ + + assert_se(fdopen_independent(fd, "re", &f) >= 0); + zero(buf); + assert_se(fread(buf, 1, sizeof(buf), f) == strlen(TEST_TEXT)); + assert_se(streq(buf, TEST_TEXT)); + assert_se((fcntl(fileno(f), F_GETFL) & O_ACCMODE) == O_RDONLY); + assert_se(FLAGS_SET(fcntl(fileno(f), F_GETFD), FD_CLOEXEC)); + f = safe_fclose(f); + + assert_se(fdopen_independent(fd, "r", &f) >= 0); + zero(buf); + assert_se(fread(buf, 1, sizeof(buf), f) == strlen(TEST_TEXT)); + assert_se(streq(buf, TEST_TEXT)); + assert_se((fcntl(fileno(f), F_GETFL) & O_ACCMODE) == O_RDONLY); + assert_se(!FLAGS_SET(fcntl(fileno(f), F_GETFD), FD_CLOEXEC)); + f = safe_fclose(f); + + assert_se(fdopen_independent(fd, "r+e", &f) >= 0); + zero(buf); + assert_se(fread(buf, 1, sizeof(buf), f) == strlen(TEST_TEXT)); + assert_se(streq(buf, TEST_TEXT)); + assert_se((fcntl(fileno(f), F_GETFL) & O_ACCMODE) == O_RDWR); + assert_se(FLAGS_SET(fcntl(fileno(f), F_GETFD), FD_CLOEXEC)); + f = safe_fclose(f); +} + + DEFINE_TEST_MAIN(LOG_DEBUG); -- cgit v1.2.1