]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
fd-util: introduce fd_reopen() helper for reopening an fd
authorLennart Poettering <lennart@poettering.net>
Mon, 26 Mar 2018 11:25:51 +0000 (13:25 +0200)
committerLennart Poettering <lennart@poettering.net>
Thu, 29 Mar 2018 13:33:12 +0000 (15:33 +0200)
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
src/basic/fd-util.h
src/test/test-fs-util.c
src/tmpfiles/tmpfiles.c

index 0726aac38cb124064bbc71a24466d40028b4505b..8bb8c9a6297531141ea64b10e7d3243f27d80025 100644 (file)
@@ -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;
+}
index 007580b48f4ac3d740e20c830483d075c99737e2..163b096b1a4b3a3606e18ddf299de09b87b49e89 100644 (file)
@@ -113,3 +113,5 @@ static inline int make_null_stdio(void) {
                 (fd) = -1;                      \
                 _fd_;                           \
         })
+
+int fd_reopen(int fd, int flags);
index 9fe79502c8677624bb3e7ad6733c020a75d98d32..7a7541f272b7bb8fd62d381ebf7723f4256cd60d 100644 (file)
@@ -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);
index 61e76570b1524d125308869755ad3a2c5e7d8541..9ac5ae12d067a3d8ee7786c42fbd97292923e1b0 100644 (file)
@@ -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;