# HG changeset patch # User Bruno Haible # Date 1316822893 -7200 # Node ID 45b9be95a5431c9022fc40280d54f1aea8511bfc # Parent 4583838a55878d91ea29d753a23853bd5291ce93 New module 'dup'. * lib/unistd.in.h (dup): Declare only if the 'dup' module is in use. Allow replacement. * lib/dup.c: New file. * lib/fchdir.c (rpl_dup): Remove function. * m4/dup.m4: New file. * m4/fchdir.m4 (gl_FUNC_FCHDIR): Don't set REPLACE_DUP here. * m4/unistd_h.m4 (gl_UNISTD_H): Test whether 'dup' is declared. (gl_UNISTD_H_DEFAULTS): Initialize GNULIB_DUP. * modules/unistd (Makefile.am): Substitute GNULIB_DUP. * modules/dup: New file. * tests/test-unistd-c++.cc: Check the signature of 'dup' only if the 'dup' module is in use. * modules/fdopendir (Depends-on): Add dup. * modules/fdutimensat-tests (Depends-on): Likewise. * modules/fts (Depends-on): Likewise. * modules/futimens-tests (Depends-on): Likewise. * modules/posix_spawnp-tests (Depends-on): Likewise. * modules/unistd-safer-tests (Depends-on): Likewise. * modules/utimens-tests (Depends-on): Likewise. * doc/posix-functions/dup.texi: Mention the new module and the problem on MSVC. diff --git a/ChangeLog b/ChangeLog --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,28 @@ +2011-09-23 Bruno Haible + + New module 'dup'. + * lib/unistd.in.h (dup): Declare only if the 'dup' module is in use. + Allow replacement. + * lib/dup.c: New file. + * lib/fchdir.c (rpl_dup): Remove function. + * m4/dup.m4: New file. + * m4/fchdir.m4 (gl_FUNC_FCHDIR): Don't set REPLACE_DUP here. + * m4/unistd_h.m4 (gl_UNISTD_H): Test whether 'dup' is declared. + (gl_UNISTD_H_DEFAULTS): Initialize GNULIB_DUP. + * modules/unistd (Makefile.am): Substitute GNULIB_DUP. + * modules/dup: New file. + * tests/test-unistd-c++.cc: Check the signature of 'dup' only if the + 'dup' module is in use. + * modules/fdopendir (Depends-on): Add dup. + * modules/fdutimensat-tests (Depends-on): Likewise. + * modules/fts (Depends-on): Likewise. + * modules/futimens-tests (Depends-on): Likewise. + * modules/posix_spawnp-tests (Depends-on): Likewise. + * modules/unistd-safer-tests (Depends-on): Likewise. + * modules/utimens-tests (Depends-on): Likewise. + * doc/posix-functions/dup.texi: Mention the new module and the problem + on MSVC. + 2011-09-23 Bruno Haible getdtablesize: Support for MSVC 9. diff --git a/doc/posix-functions/dup.texi b/doc/posix-functions/dup.texi --- a/doc/posix-functions/dup.texi +++ b/doc/posix-functions/dup.texi @@ -4,10 +4,13 @@ POSIX specification:@* @url{http://www.opengroup.org/onlinepubs/9699919799/functions/dup.html} -Gnulib module: --- +Gnulib module: dup Portability problems fixed by Gnulib: @itemize +@item +This function crashes when invoked with invalid arguments on some platforms: +MSVC 9. @end itemize Portability problems not fixed by Gnulib: diff --git a/lib/dup.c b/lib/dup.c new file mode 100644 --- /dev/null +++ b/lib/dup.c @@ -0,0 +1,61 @@ +/* Duplicate an open file descriptor. + + Copyright (C) 2011 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include + +/* Specification. */ +#include + +#include + +#include "msvc-inval.h" + +#undef dup + +#if HAVE_MSVC_INVALID_PARAMETER_HANDLER +static inline int +dup_nothrow (int fd) +{ + int result; + + TRY_MSVC_INVAL + { + result = dup (fd); + } + CATCH_MSVC_INVAL + { + result = -1; + errno = EBADF; + } + DONE_MSVC_INVAL; + + return result; +} +#else +# define dup_nothrow dup +#endif + +int +rpl_dup (int fd) +{ + int result = dup_nothrow (fd); +#if REPLACE_FCHDIR + if (result >= 0) + result = _gl_register_dup (fd, result); +#endif + return result; +} diff --git a/lib/fchdir.c b/lib/fchdir.c --- a/lib/fchdir.c +++ b/lib/fchdir.c @@ -211,19 +211,6 @@ } #endif -/* Override dup(), to keep track of open file descriptors. */ - -int -rpl_dup (int oldfd) -#undef dup -{ - int newfd = dup (oldfd); - - if (0 <= newfd) - newfd = _gl_register_dup (oldfd, newfd); - return newfd; -} - /* Implement fchdir() in terms of chdir(). */ diff --git a/lib/unistd.in.h b/lib/unistd.in.h --- a/lib/unistd.in.h +++ b/lib/unistd.in.h @@ -301,16 +301,24 @@ #endif -#if @REPLACE_DUP@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define dup rpl_dup -# endif +#if @GNULIB_DUP@ +# if @REPLACE_DUP@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define dup rpl_dup +# endif _GL_FUNCDECL_RPL (dup, int, (int oldfd)); _GL_CXXALIAS_RPL (dup, int, (int oldfd)); -#else +# else _GL_CXXALIAS_SYS (dup, int, (int oldfd)); +# endif +_GL_CXXALIASWARN (dup); +#elif defined GNULIB_POSIXCHECK +# undef dup +# if HAVE_RAW_DECL_DUP +_GL_WARN_ON_USE (dup, "dup is unportable - " + "use gnulib module dup for portability"); +# endif #endif -_GL_CXXALIASWARN (dup); #if @GNULIB_DUP2@ diff --git a/m4/dup.m4 b/m4/dup.m4 new file mode 100644 --- /dev/null +++ b/m4/dup.m4 @@ -0,0 +1,52 @@ +# dup.m4 serial 1 +dnl Copyright (C) 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, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_DUP], +[ + AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_CHECK_HEADERS_ONCE([unistd.h]) + AC_CACHE_CHECK([whether dup supports bad arguments], [gl_cv_func_dup_works], + [AC_RUN_IFELSE( + [AC_LANG_PROGRAM([[ +#if HAVE_UNISTD_H +# include +#else +# include +#endif +#include +]], + [[if (dup (-1) != -1) + return 1; + if (errno != EBADF) + return 2; + return 0; + ]])], + [gl_cv_func_dup_works=yes], + [gl_cv_func_dup_works=no], + [case "$host_os" in + mingw*) gl_cv_func_dup_works="guessing no" ;; + *) gl_cv_func_dup_works="guessing yes" ;; + esac + ]) + ]) + case "$gl_cv_func_dup_works" in + *no) REPLACE_DUP=1 ;; + esac + dnl Replace dup() for supporting the gnulib-defined fchdir() function, + dnl to keep fchdir's bookkeeping up-to-date. + m4_ifdef([gl_FUNC_FCHDIR], [ + gl_TEST_FCHDIR + if test $HAVE_FCHDIR = 0; then + REPLACE_DUP=1 + fi + ]) +]) + +# Prerequisites of lib/dup.c. +AC_DEFUN([gl_PREREQ_DUP], [ + AC_REQUIRE([AC_C_INLINE]) +]) diff --git a/m4/fchdir.m4 b/m4/fchdir.m4 --- a/m4/fchdir.m4 +++ b/m4/fchdir.m4 @@ -1,4 +1,4 @@ -# fchdir.m4 serial 18 +# fchdir.m4 serial 19 dnl Copyright (C) 2006-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,7 +24,6 @@ dnl We must also replace anything that can manipulate a directory fd, dnl to keep our bookkeeping up-to-date. We don't have to replace dnl fstatat, since no platform has fstatat but lacks fchdir. - REPLACE_DUP=1 AC_CACHE_CHECK([whether open can visit directories], [gl_cv_func_open_directory_works], [AC_RUN_IFELSE([AC_LANG_PROGRAM([[#include diff --git a/m4/unistd_h.m4 b/m4/unistd_h.m4 --- a/m4/unistd_h.m4 +++ b/m4/unistd_h.m4 @@ -1,4 +1,4 @@ -# unistd_h.m4 serial 60 +# unistd_h.m4 serial 61 dnl Copyright (C) 2006-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, @@ -39,7 +39,7 @@ # include # endif #endif - ]], [chdir chown dup2 dup3 environ euidaccess faccessat fchdir fchownat + ]], [chdir chown dup dup2 dup3 environ euidaccess faccessat fchdir fchownat fdatasync fsync ftruncate getcwd getdomainname getdtablesize getgroups gethostname getlogin getlogin_r getpagesize getusershell setusershell endusershell group_member lchown link linkat lseek pipe pipe2 pread pwrite @@ -61,6 +61,7 @@ GNULIB_CHDIR=0; AC_SUBST([GNULIB_CHDIR]) GNULIB_CHOWN=0; AC_SUBST([GNULIB_CHOWN]) GNULIB_CLOSE=0; AC_SUBST([GNULIB_CLOSE]) + GNULIB_DUP=0; AC_SUBST([GNULIB_DUP]) GNULIB_DUP2=0; AC_SUBST([GNULIB_DUP2]) GNULIB_DUP3=0; AC_SUBST([GNULIB_DUP3]) GNULIB_ENVIRON=0; AC_SUBST([GNULIB_ENVIRON]) diff --git a/modules/dup b/modules/dup new file mode 100644 --- /dev/null +++ b/modules/dup @@ -0,0 +1,29 @@ +Description: +dup() function: duplicate an open file descriptor. + +Files: +lib/dup.c +m4/dup.m4 + +Depends-on: +unistd +msvc-inval [test $REPLACE_DUP = 1] + +configure.ac: +gl_FUNC_DUP +if test $REPLACE_DUP = 1; then + AC_LIBOBJ([dup]) + gl_PREREQ_DUP +fi +gl_UNISTD_MODULE_INDICATOR([dup]) + +Makefile.am: + +Include: + + +License: +LGPLv2+ + +Maintainer: +Bruno Haible diff --git a/modules/fdopendir b/modules/fdopendir --- a/modules/fdopendir +++ b/modules/fdopendir @@ -10,6 +10,7 @@ Depends-on: dirent extensions +dup [test $HAVE_FDOPENDIR = 0] errno [test $HAVE_FDOPENDIR = 0] fchdir [test $HAVE_FDOPENDIR = 0] openat-die [test $HAVE_FDOPENDIR = 0] diff --git a/modules/fdutimensat-tests b/modules/fdutimensat-tests --- a/modules/fdutimensat-tests +++ b/modules/fdutimensat-tests @@ -10,6 +10,7 @@ Depends-on: ignore-value timespec +dup usleep utimecmp diff --git a/modules/fts b/modules/fts --- a/modules/fts +++ b/modules/fts @@ -14,6 +14,7 @@ d-ino d-type dirent-safer +dup fchdir fcntl-h fcntl-safer diff --git a/modules/futimens-tests b/modules/futimens-tests --- a/modules/futimens-tests +++ b/modules/futimens-tests @@ -9,6 +9,7 @@ Depends-on: ignore-value timespec +dup usleep utimecmp diff --git a/modules/posix_spawnp-tests b/modules/posix_spawnp-tests --- a/modules/posix_spawnp-tests +++ b/modules/posix_spawnp-tests @@ -19,6 +19,7 @@ stdbool unistd sys_wait +dup configure.ac: AC_EGREP_CPP([notposix], [[ diff --git a/modules/unistd b/modules/unistd --- a/modules/unistd +++ b/modules/unistd @@ -33,6 +33,7 @@ -e 's/@''GNULIB_CHDIR''@/$(GNULIB_CHDIR)/g' \ -e 's/@''GNULIB_CHOWN''@/$(GNULIB_CHOWN)/g' \ -e 's/@''GNULIB_CLOSE''@/$(GNULIB_CLOSE)/g' \ + -e 's/@''GNULIB_DUP''@/$(GNULIB_DUP)/g' \ -e 's/@''GNULIB_DUP2''@/$(GNULIB_DUP2)/g' \ -e 's/@''GNULIB_DUP3''@/$(GNULIB_DUP3)/g' \ -e 's/@''GNULIB_ENVIRON''@/$(GNULIB_ENVIRON)/g' \ diff --git a/modules/unistd-safer-tests b/modules/unistd-safer-tests --- a/modules/unistd-safer-tests +++ b/modules/unistd-safer-tests @@ -5,6 +5,7 @@ Depends-on: binary-io cloexec +dup fd-safer-flag msvc-nothrow stdbool diff --git a/modules/utimens-tests b/modules/utimens-tests --- a/modules/utimens-tests +++ b/modules/utimens-tests @@ -8,6 +8,7 @@ tests/macros.h Depends-on: +dup ignore-value symlink timespec diff --git a/tests/test-unistd-c++.cc b/tests/test-unistd-c++.cc --- a/tests/test-unistd-c++.cc +++ b/tests/test-unistd-c++.cc @@ -36,7 +36,9 @@ SIGNATURE_CHECK (GNULIB_NAMESPACE::close, int, (int)); #endif +#if GNULIB_TEST_DUP SIGNATURE_CHECK (GNULIB_NAMESPACE::dup, int, (int)); +#endif #if GNULIB_TEST_DUP2 SIGNATURE_CHECK (GNULIB_NAMESPACE::dup2, int, (int, int));