]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
fd-util: introduce proc_fd_enoent_errno helper
authorMike Yuan <me@yhndnzj.com>
Mon, 20 May 2024 11:28:23 +0000 (19:28 +0800)
committerMike Yuan <me@yhndnzj.com>
Tue, 21 May 2024 16:50:44 +0000 (00:50 +0800)
Currently, if proc_mounted() != 0, some functions
propagate -ENOENT while others return -EBADF.
Let's make things consistent, by introducing
a static inline helper responsible for finding out
the appropriate errno.

src/basic/fd-util.c
src/basic/fd-util.h
src/basic/fs-util.c
src/basic/inotify-util.c

index da4ee63add8c163c40535cabc18085083119b5d2..24f06b1ebc7d37fa4841c0ceb661b48403006c1c 100644 (file)
@@ -617,16 +617,8 @@ int fd_get_path(int fd, char **ret) {
                 return safe_getcwd(ret);
 
         r = readlink_malloc(FORMAT_PROC_FD_PATH(fd), ret);
-        if (r == -ENOENT) {
-                /* ENOENT can mean two things: that the fd does not exist or that /proc is not mounted. Let's make
-                 * things debuggable and distinguish the two. */
-
-                if (proc_mounted() == 0)
-                        return -ENOSYS;  /* /proc is not available or not set up properly, we're most likely in some chroot
-                                          * environment. */
-                return -EBADF; /* The directory exists, hence it's the fd that doesn't. */
-        }
-
+        if (r == -ENOENT)
+                return proc_fd_enoent_errno();
         return r;
 }
 
@@ -823,8 +815,6 @@ finish:
 }
 
 int fd_reopen(int fd, int flags) {
-        int r;
-
         assert(fd >= 0 || fd == AT_FDCWD);
         assert(!FLAGS_SET(flags, O_CREAT));
 
@@ -860,13 +850,7 @@ int fd_reopen(int fd, int flags) {
                 if (errno != ENOENT)
                         return -errno;
 
-                r = proc_mounted();
-                if (r == 0)
-                        return -ENOSYS; /* if we have no /proc/, the concept is not implementable */
-
-                return r > 0 ? -EBADF : -ENOENT; /* If /proc/ is definitely around then this means the fd is
-                                                  * not valid, otherwise let's propagate the original
-                                                  * error */
+                return proc_fd_enoent_errno();
         }
 
         return new_fd;
@@ -1136,3 +1120,18 @@ char *format_proc_pid_fd_path(char buf[static PROC_PID_FD_PATH_MAX], pid_t pid,
         assert_se(snprintf_ok(buf, PROC_PID_FD_PATH_MAX, "/proc/" PID_FMT "/fd/%i", pid == 0 ? getpid_cached() : pid, fd));
         return buf;
 }
+
+int proc_fd_enoent_errno(void) {
+        int r;
+
+        /* When ENOENT is returned during the use of FORMAT_PROC_FD_PATH, it can mean two things:
+         * that the fd does not exist or that /proc/ is not mounted.
+         * Let's make things debuggable and figure out the most appropriate errno. */
+
+        r = proc_mounted();
+        if (r == 0)
+                return -ENOSYS;  /* /proc/ is not available or not set up properly, we're most likely
+                                    in some chroot environment. */
+        return r > 0 ? -EBADF : -ENOENT; /* If /proc/ is definitely around then this means the fd is
+                                            not valid, otherwise let's propagate the original ENOENT. */
+}
index af17481dd868afcfdd885ae6d73b5013f6ff2362..a047c3a3f411f3f37061e30c3d1820b8def1416f 100644 (file)
@@ -161,6 +161,8 @@ char *format_proc_pid_fd_path(char buf[static PROC_PID_FD_PATH_MAX], pid_t pid,
 #define FORMAT_PROC_PID_FD_PATH(pid, fd)                                \
         format_proc_pid_fd_path((char[PROC_PID_FD_PATH_MAX]) {}, (pid), (fd))
 
+int proc_fd_enoent_errno(void);
+
 const char *accmode_to_string(int flags);
 
 /* Like ASSERT_PTR, but for fds */
index 6bb4587f817bb73d36e335d5d34f43953effee0f..13995cf7a74a0a9dd6e5fa03fe5f7a2aa7631187 100644 (file)
@@ -313,10 +313,7 @@ int fchmod_opath(int fd, mode_t m) {
                 if (errno != ENOENT)
                         return -errno;
 
-                if (proc_mounted() == 0)
-                        return -ENOSYS; /* if we have no /proc/, the concept is not implementable */
-
-                return -ENOENT;
+                return proc_fd_enoent_errno();
         }
 
         return 0;
@@ -339,10 +336,7 @@ int futimens_opath(int fd, const struct timespec ts[2]) {
                 if (errno != ENOENT)
                         return -errno;
 
-                if (proc_mounted() == 0)
-                        return -ENOSYS;
-
-                return -ENOENT;
+                return proc_fd_enoent_errno();
         }
 
         return 0;
@@ -685,14 +679,7 @@ int access_fd(int fd, int mode) {
                 if (errno != ENOENT)
                         return -errno;
 
-                /* ENOENT can mean two things: that the fd does not exist or that /proc is not mounted. Let's
-                 * make things debuggable and distinguish the two. */
-
-                if (proc_mounted() == 0)
-                        return -ENOSYS;  /* /proc is not available or not set up properly, we're most likely in some chroot
-                                          * environment. */
-
-                return -EBADF; /* The directory exists, hence it's the fd that doesn't. */
+                return proc_fd_enoent_errno();
         }
 
         return 0;
index ee9b416c8735d555c447a7dbaab083fed79df3f4..d8cbb0450915b146f7426d65e741fb64d450ba64 100644 (file)
@@ -42,7 +42,10 @@ bool inotify_event_next(
 }
 
 int inotify_add_watch_fd(int fd, int what, uint32_t mask) {
-        int wd, r;
+        int wd;
+
+        assert(fd >= 0);
+        assert(what >= 0);
 
         /* This is like inotify_add_watch(), except that the file to watch is not referenced by a path, but by an fd */
         wd = inotify_add_watch(fd, FORMAT_PROC_FD_PATH(what), mask);
@@ -50,14 +53,7 @@ int inotify_add_watch_fd(int fd, int what, uint32_t mask) {
                 if (errno != ENOENT)
                         return -errno;
 
-                /* Didn't work with ENOENT? If so, then either /proc/ isn't mounted, or the fd is bad */
-                r = proc_mounted();
-                if (r == 0)
-                        return -ENOSYS;
-                if (r > 0)
-                        return -EBADF;
-
-                return -ENOENT; /* OK, no clue, let's propagate the original error */
+                return proc_fd_enoent_errno();
         }
 
         return wd;