]> Savannah Git Hosting - gnulib.git/commitdiff
fcntl: Work around NetBSD bug with F_DUPFD_CLOEXEC.
authorBruno Haible <bruno@clisp.org>
Sun, 29 Nov 2020 20:13:33 +0000 (21:13 +0100)
committerBruno Haible <bruno@clisp.org>
Sun, 29 Nov 2020 20:13:33 +0000 (21:13 +0100)
* m4/fcntl.m4 (gl_FUNC_FCNTL): Test whether F_DUPFD_CLOEXEC actually
works.
* lib/fcntl.c (rpl_fcntl_DUPFD_CLOEXEC): On NetBSD, use the same
fallback implementation as on Haiku.
* tests/test-fcntl.c (main): Add a test whether F_DUPFD_CLOEXEC is
effective.
* doc/posix-functions/fcntl.texi: Mention the NetBSD bug.

ChangeLog
doc/posix-functions/fcntl.texi
lib/fcntl.c
m4/fcntl.m4
tests/test-fcntl.c

index d6fd4aca6782c2e67dd6fe0fb65e15e8d4b7ac06..69d6e49459b702c814c4dd9b6bd4144d83780cf6 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2020-11-29  Bruno Haible  <bruno@clisp.org>
+
+       fcntl: Work around NetBSD bug with F_DUPFD_CLOEXEC.
+       * m4/fcntl.m4 (gl_FUNC_FCNTL): Test whether F_DUPFD_CLOEXEC actually
+       works.
+       * lib/fcntl.c (rpl_fcntl_DUPFD_CLOEXEC): On NetBSD, use the same
+       fallback implementation as on Haiku.
+       * tests/test-fcntl.c (main): Add a test whether F_DUPFD_CLOEXEC is
+       effective.
+       * doc/posix-functions/fcntl.texi: Mention the NetBSD bug.
+
 2020-11-29  Bruno Haible  <bruno@clisp.org>
 
        spawn-pipe: Fix build on OS/2 kLIBC (regression 2020-11-28).
index 887f8d4ec57ea63eefe53646a1981304635deb26..831a19477c2724bb92db51668786f062ea824069 100644 (file)
@@ -22,6 +22,11 @@ Mac OS X 10.5, FreeBSD 6.0, NetBSD 5.0, OpenBSD 6.7, AIX 7.1, HP-UX 11,
 IRIX 6.5, Solaris 11 2010-11, Cygwin 1.7.1.
 Note that the gnulib replacement code is functional but not atomic.
 
+@item
+The @code{F_DUPFD_CLOEXEC} action of this function does not set the
+@code{FD_CLOEXEC} flag on some platforms:
+NetBSD 9.0.
+
 @item
 The @code{F_DUPFD_CLOEXEC} action of this function sets the
 @code{FD_CLOEXEC} flag on the wrong file descriptor on some platforms:
index 8cd1531527d6e3dfc7b08cfeb510bd80583bd664..59bb3ca91ea5d7c2fb5b6e133855fdce2240e5c9 100644 (file)
@@ -491,7 +491,9 @@ rpl_fcntl_DUPFD_CLOEXEC (int fd, int target)
 #if !HAVE_FCNTL
   result = dupfd (fd, target, O_CLOEXEC);
 #else /* HAVE_FCNTL */
-# if defined __HAIKU__
+# if defined __NetBSD__ || defined __HAIKU__
+  /* On NetBSD 9.0, the system fcntl (fd, F_DUPFD_CLOEXEC, target)
+     has only the same effect as fcntl (fd, F_DUPFD, target).  */
   /* On Haiku, the system fcntl (fd, F_DUPFD_CLOEXEC, target) sets
      the FD_CLOEXEC flag on fd, not on target.  Therefore avoid the
      system fcntl in this case.  */
index ea24f3d64ef6234855fa5141315801eeccc57ff1..547ff40b804f0e9f936a20aa94b7f30b359dc316 100644 (file)
@@ -1,4 +1,4 @@
-# fcntl.m4 serial 10
+# fcntl.m4 serial 11
 dnl Copyright (C) 2009-2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -81,15 +81,29 @@ AC_DEFUN([gl_FUNC_FCNTL],
           behavior does not match POSIX]) ;;
     esac
 
-    dnl Many systems lack F_DUPFD_CLOEXEC
+    dnl Many systems lack F_DUPFD_CLOEXEC.
+    dnl NetBSD 9.0 declares F_DUPFD_CLOEXEC but it works only like F_DUPFD.
     AC_CACHE_CHECK([whether fcntl understands F_DUPFD_CLOEXEC],
       [gl_cv_func_fcntl_f_dupfd_cloexec],
-      [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
-#include <fcntl.h>
-#ifndef F_DUPFD_CLOEXEC
-choke me
-#endif
-         ]])],
+      [AC_RUN_IFELSE(
+         [AC_LANG_SOURCE(
+            [[#include <fcntl.h>
+              #include <unistd.h>
+              int main (int argc, char *argv[])
+              {
+                if (argc == 1)
+                  /* parent process */
+                  {
+                    if (fcntl (1, F_DUPFD_CLOEXEC, 10) < 0)
+                      return 1;
+                    return execl ("./conftest", "./conftest", "child", NULL);
+                  }
+                else
+                  /* child process */
+                  return (fcntl (10, F_GETFL) < 0 ? 0 : 42);
+              }
+            ]])
+         ],
          [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
 #ifdef __linux__
 /* The Linux kernel only added F_DUPFD_CLOEXEC in 2.6.24, so we always replace
@@ -98,12 +112,22 @@ choke me
 #endif
            ]])],
            [gl_cv_func_fcntl_f_dupfd_cloexec=yes],
-           [gl_cv_func_fcntl_f_dupfd_cloexec="needs runtime check"])],
-         [gl_cv_func_fcntl_f_dupfd_cloexec=no])])
-    if test "$gl_cv_func_fcntl_f_dupfd_cloexec" != yes; then
-      gl_REPLACE_FCNTL
-      dnl No witness macro needed for this bug.
-    fi
+           [gl_cv_func_fcntl_f_dupfd_cloexec="needs runtime check"])
+         ],
+         [gl_cv_func_fcntl_f_dupfd_cloexec=no],
+         [case "$host_os" in
+                     # Guess no on NetBSD.
+            netbsd*) gl_cv_func_fcntl_f_dupfd_cloexec="guessing no" ;;
+            *)       gl_cv_func_fcntl_f_dupfd_cloexec="$gl_cross_guess_normal" ;;
+          esac
+         ])
+      ])
+    case "$gl_cv_func_fcntl_f_dupfd_cloexec" in
+      *yes) ;;
+      *)    gl_REPLACE_FCNTL
+            dnl No witness macro needed for this bug.
+            ;;
+    esac
   fi
   dnl Replace fcntl() for supporting the gnulib-defined fchdir() function,
   dnl to keep fchdir's bookkeeping up-to-date.
index 9ef354c03d8e49957c5a5d9a5f0a6bf0a639639c..c734e41351cec2ab7ef82ddd4d495442a5850f1c 100644 (file)
@@ -212,8 +212,12 @@ check_flags (void)
 }
 
 int
-main (void)
+main (int argc, char *argv[])
 {
+  if (argc > 1)
+    /* child process */
+    return (is_open (10) ? 42 : 0);
+
   const char *file = "test-fcntl.tmp";
   int fd;
   int bad_fd = getdtablesize ();
@@ -411,5 +415,11 @@ main (void)
   ASSERT (close (fd) == 0);
   ASSERT (unlink (file) == 0);
 
-  return 0;
+  /* Test whether F_DUPFD_CLOEXEC is effective.  */
+  ASSERT (fcntl (1, F_DUPFD_CLOEXEC, 10) >= 0);
+#if defined _WIN32 && !defined __CYGWIN__
+  return _execl ("./test-fcntl", "./test-fcntl", "child", NULL);
+#else
+  return execl ("./test-fcntl", "./test-fcntl", "child", NULL);
+#endif
 }