summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2018-03-26 13:25:51 +0200
committerLennart Poettering <lennart@poettering.net>2018-03-29 15:33:12 +0200
commitf2324783ceee84fbd24fd66f34d379fa1e6dc887 (patch)
tree8a11285a10b7aa91d3cebb407c2dc66c3be60401
parentc75436067f4b392ecf161e123279720dc5c3b33a (diff)
downloadsystemd-f2324783ceee84fbd24fd66f34d379fa1e6dc887.tar.gz
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..
-rw-r--r--src/basic/fd-util.c27
-rw-r--r--src/basic/fd-util.h2
-rw-r--r--src/test/test-fs-util.c6
-rw-r--r--src/tmpfiles/tmpfiles.c5
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;