summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog25
-rw-r--r--doc/posix-functions/dup.texi5
-rw-r--r--lib/dup.c61
-rw-r--r--lib/fchdir.c13
-rw-r--r--lib/unistd.in.h20
-rw-r--r--m4/dup.m452
-rw-r--r--m4/fchdir.m43
-rw-r--r--m4/unistd_h.m45
-rw-r--r--modules/dup29
-rw-r--r--modules/fdopendir1
-rw-r--r--modules/fdutimensat-tests1
-rw-r--r--modules/fts1
-rw-r--r--modules/futimens-tests1
-rw-r--r--modules/posix_spawnp-tests1
-rw-r--r--modules/unistd1
-rw-r--r--modules/unistd-safer-tests1
-rw-r--r--modules/utimens-tests1
-rw-r--r--tests/test-unistd-c++.cc2
18 files changed, 199 insertions, 24 deletions
diff --git a/ChangeLog b/ChangeLog
index ae72da7167..a81731ea50 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,30 @@
2011-09-23 Bruno Haible <bruno@clisp.org>
+ 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 <bruno@clisp.org>
+
getdtablesize: Support for MSVC 9.
* lib/getdtablesize.c: Include msvc-inval.h.
(_setmaxstdio_nothrow): New function.
diff --git a/doc/posix-functions/dup.texi b/doc/posix-functions/dup.texi
index b67fc1f543..3b4c63f22f 100644
--- 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
index 0000000000..4a75a0cf6a
--- /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 <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+/* Specification. */
+#include <unistd.h>
+
+#include <errno.h>
+
+#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
index e13ba2249d..63c287b207 100644
--- a/lib/fchdir.c
+++ b/lib/fchdir.c
@@ -211,19 +211,6 @@ rpl_fstat (int fd, struct stat *statbuf)
}
#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
index bb514dbff0..60a7530b4a 100644
--- a/lib/unistd.in.h
+++ b/lib/unistd.in.h
@@ -301,16 +301,24 @@ _GL_WARN_ON_USE (close, "close does not portably work on sockets - "
#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
+# 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
#if @GNULIB_DUP2@
diff --git a/m4/dup.m4 b/m4/dup.m4
new file mode 100644
index 0000000000..8f2ec8f7b0
--- /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 <unistd.h>
+#else
+# include <io.h>
+#endif
+#include <errno.h>
+]],
+ [[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
index e742a0732a..602aad9250 100644
--- 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 @@ AC_DEFUN([gl_FUNC_FCHDIR],
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 <fcntl.h>
diff --git a/m4/unistd_h.m4 b/m4/unistd_h.m4
index 79ae9e9662..57c8094e42 100644
--- 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 @@ AC_DEFUN([gl_UNISTD_H],
# include <io.h>
# 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 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS],
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
index 0000000000..85f295dd9d
--- /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:
+<unistd.h>
+
+License:
+LGPLv2+
+
+Maintainer:
+Bruno Haible
diff --git a/modules/fdopendir b/modules/fdopendir
index 41695b99a3..94168faa09 100644
--- a/modules/fdopendir
+++ b/modules/fdopendir
@@ -10,6 +10,7 @@ m4/fdopendir.m4
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
index 446762bc14..8c1dc39093 100644
--- a/modules/fdutimensat-tests
+++ b/modules/fdutimensat-tests
@@ -10,6 +10,7 @@ tests/macros.h
Depends-on:
ignore-value
timespec
+dup
usleep
utimecmp
diff --git a/modules/fts b/modules/fts
index 9869c941df..8aae6d89f9 100644
--- a/modules/fts
+++ b/modules/fts
@@ -14,6 +14,7 @@ cycle-check
d-ino
d-type
dirent-safer
+dup
fchdir
fcntl-h
fcntl-safer
diff --git a/modules/futimens-tests b/modules/futimens-tests
index 356f67e2dd..bfd65f6b96 100644
--- a/modules/futimens-tests
+++ b/modules/futimens-tests
@@ -9,6 +9,7 @@ tests/macros.h
Depends-on:
ignore-value
timespec
+dup
usleep
utimecmp
diff --git a/modules/posix_spawnp-tests b/modules/posix_spawnp-tests
index 49465d856c..6363585d23 100644
--- a/modules/posix_spawnp-tests
+++ b/modules/posix_spawnp-tests
@@ -19,6 +19,7 @@ sigprocmask
stdbool
unistd
sys_wait
+dup
configure.ac:
AC_EGREP_CPP([notposix], [[
diff --git a/modules/unistd b/modules/unistd
index 3d31734507..633ba31982 100644
--- a/modules/unistd
+++ b/modules/unistd
@@ -33,6 +33,7 @@ unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
-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
index d8519a6562..03e753c456 100644
--- a/modules/unistd-safer-tests
+++ b/modules/unistd-safer-tests
@@ -5,6 +5,7 @@ tests/macros.h
Depends-on:
binary-io
cloexec
+dup
fd-safer-flag
msvc-nothrow
stdbool
diff --git a/modules/utimens-tests b/modules/utimens-tests
index 7335c5df52..4d5d1f576a 100644
--- a/modules/utimens-tests
+++ b/modules/utimens-tests
@@ -8,6 +8,7 @@ tests/test-utimens.c
tests/macros.h
Depends-on:
+dup
ignore-value
symlink
timespec
diff --git a/tests/test-unistd-c++.cc b/tests/test-unistd-c++.cc
index b82b0e81d1..e9244b32ef 100644
--- a/tests/test-unistd-c++.cc
+++ b/tests/test-unistd-c++.cc
@@ -36,7 +36,9 @@ SIGNATURE_CHECK (GNULIB_NAMESPACE::chown, int, (const char *, uid_t, gid_t));
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));