From fc12f35ab10cca4dc698ddee31b5e2bbeeb54167 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Tue, 25 Jan 2011 22:06:16 -0700 Subject: [PATCH] fcntl: work around Haiku F_DUPFD bugs * m4/fcntl.m4 (gl_FUNC_FCNTL): Also catch Haiku errno bug. * lib/fcntl.c (rpl_fcntl) [F_DUPFD]: Work around Haiku losing cloexec bit on duplication. * doc/posix-functions/fcntl.texi (fcntl): Document the bug. Signed-off-by: Eric Blake --- ChangeLog | 8 ++++++++ doc/posix-functions/fcntl.texi | 7 ++++++- lib/fcntl.c | 14 ++++++++++++++ m4/fcntl.m4 | 9 +++++++-- 4 files changed, 35 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index c6700ecf9..452806227 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2011-01-26 Eric Blake + + fcntl: work around Haiku F_DUPFD bugs + * m4/fcntl.m4 (gl_FUNC_FCNTL): Also catch Haiku errno bug. + * lib/fcntl.c (rpl_fcntl) [F_DUPFD]: Work around Haiku losing + cloexec bit on duplication. + * doc/posix-functions/fcntl.texi (fcntl): Document the bug. + 2011-01-26 Bruno Haible Enable memory leak tests on AIX. diff --git a/doc/posix-functions/fcntl.texi b/doc/posix-functions/fcntl.texi index a0511ec37..161af1e79 100644 --- a/doc/posix-functions/fcntl.texi +++ b/doc/posix-functions/fcntl.texi @@ -19,7 +19,12 @@ Note that the gnulib replacement code is functional but not atomic. @item The @code{F_DUPFD} action of this function does not reject out-of-range targets properly on some platforms: -Cygwin 1.5.x. +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: +Haiku. @item This function is missing on some platforms: diff --git a/lib/fcntl.c b/lib/fcntl.c index 25a79c544..d6a328c1c 100644 --- a/lib/fcntl.c +++ b/lib/fcntl.c @@ -187,7 +187,21 @@ rpl_fcntl (int fd, int action, /* arg */...) errno = EINVAL; else { + /* Haiku alpha 2 loses fd flags on original. */ + int flags = fcntl (fd, F_GETFD); + if (flags < 0) + { + result = -1; + break; + } result = fcntl (fd, action, target); + if (0 <= result && fcntl (fd, F_SETFD, flags) == -1) + { + int saved_errno = errno; + close (result); + result = -1; + errno = saved_errno; + } # if REPLACE_FCHDIR if (0 <= result) result = _gl_register_dup (fd, result); diff --git a/m4/fcntl.m4 b/m4/fcntl.m4 index 3a86f2ca4..a93ed85a3 100644 --- a/m4/fcntl.m4 +++ b/m4/fcntl.m4 @@ -1,4 +1,4 @@ -# fcntl.m4 serial 3 +# fcntl.m4 serial 4 dnl Copyright (C) 2009-2011 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -24,11 +24,16 @@ AC_DEFUN([gl_FUNC_FCNTL], gl_REPLACE_FCNTL else dnl cygwin 1.5.x F_DUPFD has wrong errno, and allows negative target + dnl haiku alpha 2 F_DUPFD has wrong errno AC_CACHE_CHECK([whether fcntl handles F_DUPFD correctly], [gl_cv_func_fcntl_f_dupfd_works], [AC_RUN_IFELSE([AC_LANG_PROGRAM([[ #include -]], [[return fcntl (0, F_DUPFD, -1) != -1; +#include +]], [[int result = 0; + if (fcntl (0, F_DUPFD, -1) != -1) result |= 1; + if (errno != EINVAL) result |= 2; + return result; ]])], [gl_cv_func_fcntl_f_dupfd_works=yes], [gl_cv_func_fcntl_f_dupfd_works=no], -- 2.11.0