From f2324783ceee84fbd24fd66f34d379fa1e6dc887 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 26 Mar 2018 13:25:51 +0200 Subject: [PATCH] fd-util: introduce fd_reopen() helper for reopening an fd We have the same code for this in place at various locations, let's unify that. Also, let's repurpose test-fs-util.c as a test for this new helper cal.. --- src/basic/fd-util.c | 27 ++++++++++++++++++++------- src/basic/fd-util.h | 2 ++ src/test/test-fs-util.c | 6 +----- src/tmpfiles/tmpfiles.c | 5 +---- 4 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/basic/fd-util.c b/src/basic/fd-util.c index 0726aac38c..8bb8c9a629 100644 --- a/src/basic/fd-util.c +++ b/src/basic/fd-util.c @@ -427,7 +427,6 @@ int move_fd(int from, int to, int cloexec) { int acquire_data_fd(const void *data, size_t size, unsigned flags) { - char procfs_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)]; _cleanup_close_pair_ int pipefds[2] = { -1, -1 }; char pattern[] = "/dev/shm/data-fd-XXXXXX"; _cleanup_close_ int fd = -1; @@ -537,12 +536,7 @@ try_dev_shm: return -EIO; /* Let's reopen the thing, in order to get an O_RDONLY fd for the original O_RDWR one */ - xsprintf(procfs_path, "/proc/self/fd/%i", fd); - r = open(procfs_path, O_RDONLY|O_CLOEXEC); - if (r < 0) - return -errno; - - return r; + return fd_reopen(fd, O_RDONLY|O_CLOEXEC); } try_dev_shm_without_o_tmpfile: @@ -725,3 +719,22 @@ finish: return r; } + +int fd_reopen(int fd, int flags) { + char procfs_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)]; + int new_fd; + + /* Reopens the specified fd with new flags. This is useful for convert an O_PATH fd into a regular one, or to + * turn O_RDWR fds into O_RDONLY fds. + * + * This doesn't work on sockets (since they cannot be open()ed, ever). + * + * This implicitly resets the file read index to 0. */ + + xsprintf(procfs_path, "/proc/self/fd/%i", fd); + new_fd = open(procfs_path, flags); + if (new_fd < 0) + return -errno; + + return new_fd; +} diff --git a/src/basic/fd-util.h b/src/basic/fd-util.h index 007580b48f..163b096b1a 100644 --- a/src/basic/fd-util.h +++ b/src/basic/fd-util.h @@ -113,3 +113,5 @@ static inline int make_null_stdio(void) { (fd) = -1; \ _fd_; \ }) + +int fd_reopen(int fd, int flags); diff --git a/src/test/test-fs-util.c b/src/test/test-fs-util.c index 9fe79502c8..7a7541f272 100644 --- a/src/test/test-fs-util.c +++ b/src/test/test-fs-util.c @@ -270,17 +270,13 @@ static void test_chase_symlinks(void) { pfd = chase_symlinks(p, NULL, CHASE_OPEN, NULL); if (pfd != -ENOENT) { - char procfs[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(pfd) + 1]; _cleanup_close_ int fd = -1; sd_id128_t a, b; assert_se(pfd >= 0); - xsprintf(procfs, "/proc/self/fd/%i", pfd); - - fd = open(procfs, O_RDONLY|O_CLOEXEC); + fd = fd_reopen(pfd, O_RDONLY|O_CLOEXEC); assert_se(fd >= 0); - safe_close(pfd); assert_se(id128_read_fd(fd, ID128_PLAIN, &a) >= 0); diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index 61e76570b1..9ac5ae12d0 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -1186,7 +1186,6 @@ static int parse_attribute_from_arg(Item *item) { } static int fd_set_attribute(Item *item, int fd, const struct stat *st) { - char procfs_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)]; _cleanup_close_ int procfs_fd = -1; _cleanup_free_ char *path = NULL; unsigned f; @@ -1213,9 +1212,7 @@ static int fd_set_attribute(Item *item, int fd, const struct stat *st) { if (!S_ISDIR(st->st_mode)) f &= ~FS_DIRSYNC_FL; - xsprintf(procfs_path, "/proc/self/fd/%i", fd); - - procfs_fd = open(procfs_path, O_RDONLY|O_CLOEXEC|O_NOATIME); + procfs_fd = fd_reopen(fd, O_RDONLY|O_CLOEXEC|O_NOATIME); if (procfs_fd < 0) return -errno;