chiark / gitweb /
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)
committerSven Eden <yamakuzure@gmx.net>
Fri, 24 Aug 2018 14:47:08 +0000 (16:47 +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

index 8ae79fb6948f0929c28155b8fa30407dcd3a5a6a..21c9d8b87203544081e2e9fae6b4107c1bccc49d 100644 (file)
@@ -431,7 +431,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;
@@ -541,12 +540,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:
@@ -729,3 +723,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 cb4677ec403686cc87a98d1abdc99313b21bc6e8..0f5a950f175a7a6fb7feb673f3e857ba4105f136 100644 (file)
@@ -117,3 +117,5 @@ static inline int make_null_stdio(void) {
                 (fd) = -1;                      \
                 _fd_;                           \
         })
+
+int fd_reopen(int fd, int flags);
index ba01eea4e3bc156596760deb9abf9f9cbf8b15ef..35bb699c3de8305c80bf640069b974e558fc0575 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);