Make safeguard against incorrect flags for fsync more portable.
authorTom Lane
Tue, 1 Jul 2025 16:08:20 +0000 (12:08 -0400)
committerTom Lane
Tue, 1 Jul 2025 16:08:20 +0000 (12:08 -0400)
The existing code assumed that O_RDONLY is defined as 0, but this is
not required by POSIX and is not true on GNU Hurd.  We can avoid
the assumption by relying on O_ACCMODE to mask the fcntl() result.
(Hopefully, all supported platforms define that.)

Author: Michael Banck 
Co-authored-by: Samuel Thibault
Reviewed-by: Tom Lane
Discussion: https://postgr.es/m/6862e8d1.050a0220[email protected]
Discussion: https://postgr.es/m/68480868.5d0a0220[email protected]
Backpatch-through: 13

src/backend/storage/file/fd.c

index 0e8299dd55646eb46abdaa922d2cfd463aeb8d84..a4ec7959f31cfffcd267ffeeaf3fd1ebf013d33d 100644 (file)
@@ -400,25 +400,22 @@ pg_fsync(int fd)
     * portable, even if it runs ok on the current system.
     *
     * We assert here that a descriptor for a file was opened with write
-    * permissions (either O_RDWR or O_WRONLY) and for a directory without
-    * write permissions (O_RDONLY).
+    * permissions (i.e., not O_RDONLY) and for a directory without write
+    * permissions (O_RDONLY).  Notice that the assertion check is made even
+    * if fsync() is disabled.
     *
-    * Ignore any fstat errors and let the follow-up fsync() do its work.
-    * Doing this sanity check here counts for the case where fsync() is
-    * disabled.
+    * If fstat() fails, ignore it and let the follow-up fsync() complain.
     */
    if (fstat(fd, &st) == 0)
    {
        int         desc_flags = fcntl(fd, F_GETFL);
 
-       /*
-        * O_RDONLY is historically 0, so just make sure that for directories
-        * no write flags are used.
-        */
+       desc_flags &= O_ACCMODE;
+
        if (S_ISDIR(st.st_mode))
-           Assert((desc_flags & (O_RDWR | O_WRONLY)) == 0);
+           Assert(desc_flags == O_RDONLY);
        else
-           Assert((desc_flags & (O_RDWR | O_WRONLY)) != 0);
+           Assert(desc_flags != O_RDONLY);
    }
    errno = 0;
 #endif