changeset 39542:e213d1fe9560

fcntl: Fix F_DUPFD_CLOEXEC behaviour on Haiku. * lib/fcntl.c (rpl_fcntl): For F_DUPFD_CLOEXEC, don't even try the system fcntl. * doc/posix-functions/fcntl.texi: Document the issue.
author Bruno Haible <bruno@clisp.org>
date Thu, 06 Sep 2018 18:36:02 +0200
parents cff88062aa45
children 0c5ff60f6864
files ChangeLog doc/posix-functions/fcntl.texi lib/fcntl.c
diffstat 3 files changed, 22 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Thu Sep 06 14:50:04 2018 +0200
+++ b/ChangeLog	Thu Sep 06 18:36:02 2018 +0200
@@ -1,3 +1,10 @@
+2018-09-06  Bruno Haible  <bruno@clisp.org>
+
+	fcntl: Fix F_DUPFD_CLOEXEC behaviour on Haiku.
+	* lib/fcntl.c (rpl_fcntl): For F_DUPFD_CLOEXEC, don't even try the
+	system fcntl.
+	* doc/posix-functions/fcntl.texi: Document the issue.
+
 2018-09-06  Bruno Haible  <bruno@clisp.org>
 
 	count-trailing-zeros tests: Rely on limits-h module.
--- a/doc/posix-functions/fcntl.texi	Thu Sep 06 14:50:04 2018 +0200
+++ b/doc/posix-functions/fcntl.texi	Thu Sep 06 18:36:02 2018 +0200
@@ -22,13 +22,18 @@
 Note that the gnulib replacement code is functional but not atomic.
 
 @item
+The @code{F_DUPFD_CLOEXEC} action of this function sets the
+@code{FD_CLOEXEC} flag on the wrong file descriptor on some platforms:
+Haiku.
+
+@item
 The @code{F_DUPFD} action of this function does not reject
 out-of-range targets properly on some platforms:
 AIX 7.1, Cygwin 1.5.x, Haiku.
 
 @item
 The @code{F_DUPFD} action of this function mistakenly clears
-FD_CLOEXEC on the source descriptor on some platforms:
+@code{FD_CLOEXEC} on the source descriptor on some platforms:
 Haiku.
 @end itemize
 
--- a/lib/fcntl.c	Thu Sep 06 14:50:04 2018 +0200
+++ b/lib/fcntl.c	Thu Sep 06 18:36:02 2018 +0200
@@ -329,6 +329,12 @@
         result = dupfd (fd, target, O_CLOEXEC);
         break;
 #else /* HAVE_FCNTL */
+# if defined __HAIKU__
+        /* On Haiku, the system fcntl (fd, F_DUPFD_CLOEXEC, target) sets
+           the O_CLOEXEC flag on fd, not on target.  Therefore avoid the
+           system fcntl in this case.  */
+#  define have_dupfd_cloexec -1
+# else
         /* Try the system call first, if the headers claim it exists
            (that is, if GNULIB_defined_F_DUPFD_CLOEXEC is 0), since we
            may be running with a glibc that has the macro but with an
@@ -343,10 +349,10 @@
             if (0 <= result || errno != EINVAL)
               {
                 have_dupfd_cloexec = 1;
-# if REPLACE_FCHDIR
+#  if REPLACE_FCHDIR
                 if (0 <= result)
                   result = _gl_register_dup (fd, result);
-# endif
+#  endif
               }
             else
               {
@@ -357,6 +363,7 @@
               }
           }
         else
+# endif
           result = rpl_fcntl (fd, F_DUPFD, target);
         if (0 <= result && have_dupfd_cloexec == -1)
           {