]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
fd-util: introduce fd_vet_accmode()
authorMike Yuan <me@yhndnzj.com>
Tue, 11 Nov 2025 18:04:38 +0000 (19:04 +0100)
committerMike Yuan <me@yhndnzj.com>
Wed, 12 Nov 2025 14:44:50 +0000 (15:44 +0100)
Inspired by #39674

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

index 74feb8ad4b8ea87287c733815b4c07ed40cd8bb1..310f5b82b5bf094447ad264f02da122e03f6dd96 100644 (file)
@@ -960,6 +960,41 @@ int fd_is_opath(int fd) {
         return FLAGS_SET(r, O_PATH);
 }
 
+int fd_vet_accmode(int fd, int mode) {
+        int flags;
+
+        /* Check if fd is opened with desired access mode.
+         *
+         * Returns > 0 on strict match, == 0 if opened for both reading and writing (partial match),
+         * -EPROTOTYPE otherwise. O_PATH fds are always refused with -EBADFD.
+         *
+         * Note that while on O_DIRECTORY -EISDIR will be returned, this should not be relied upon as
+         * the flag might not have been specified when open() was called originally. */
+
+        assert(fd >= 0);
+        assert(IN_SET(mode, O_RDONLY, O_WRONLY, O_RDWR));
+
+        flags = fcntl(fd, F_GETFL);
+        if (flags < 0)
+                return -errno;
+
+        if (FLAGS_SET(flags, O_DIRECTORY))
+                return -EISDIR;
+
+        if (FLAGS_SET(flags, O_PATH))
+                return -EBADFD;
+
+        flags &= O_ACCMODE_STRICT;
+
+        if (flags == mode)
+                return 1;
+
+        if (flags == O_RDWR)
+                return 0;
+
+        return -EPROTOTYPE;
+}
+
 int fd_verify_safe_flags_full(int fd, int extra_flags) {
         int flags, unexpected_flags;
 
index 95184c5783a6d377753bfb83847553fbdc82bead..baa81b6a66284daae9e7ae5646752cd59a6055b3 100644 (file)
@@ -151,6 +151,7 @@ int fd_reopen_propagate_append_and_position(int fd, int flags);
 int fd_reopen_condition(int fd, int flags, int mask, int *ret_new_fd);
 
 int fd_is_opath(int fd);
+int fd_vet_accmode(int fd, int mode);
 
 int fd_verify_safe_flags_full(int fd, int extra_flags);
 static inline int fd_verify_safe_flags(int fd) {