* m4/dup2.m4 (gl_FUNC_DUP2): Detect mingw bug.
* m4/unistd_h.m4 (gl_UNISTD_H_DEFAULTS): Add witness.
* modules/unistd (Makefile.am): Substitute it.
* lib/unistd.in.h (dup2): Declare the replacement.
* lib/dup2.c (dup2) [REPLACE_DUP2]: Implement it.
* doc/posix-functions/dup2.texi (dup2): Document the bugs.
* lib/fchdir.c (rpl_dup2): Don't collide with mingw replacement.
* modules/execute (Depends-on): Add dup2.
* modules/fseterr (Depends-on): Likewise.
* modules/pipe (Depends-on): Likewise.
* modules/posix_spawn-internal (Depends-on): Likewise.
Signed-off-by: Eric Blake <ebb9@byu.net>
+2009-07-21 Eric Blake <ebb9@byu.net>
+
+ dup2: work around mingw and cygwin 1.5 bug
+ * m4/dup2.m4 (gl_FUNC_DUP2): Detect mingw bug.
+ * m4/unistd_h.m4 (gl_UNISTD_H_DEFAULTS): Add witness.
+ * modules/unistd (Makefile.am): Substitute it.
+ * lib/unistd.in.h (dup2): Declare the replacement.
+ * lib/dup2.c (dup2) [REPLACE_DUP2]: Implement it.
+ * doc/posix-functions/dup2.texi (dup2): Document the bugs.
+ * lib/fchdir.c (rpl_dup2): Don't collide with mingw replacement.
+ * modules/execute (Depends-on): Add dup2.
+ * modules/fseterr (Depends-on): Likewise.
+ * modules/pipe (Depends-on): Likewise.
+ * modules/posix_spawn-internal (Depends-on): Likewise.
+
2009-07-21 Bruno Haible <bruno@clisp.org>
* modules/.gitattributes: New file.
Portability problems fixed by Gnulib:
@itemize
+@item
+This function always returns 0 for success on some platforms:
+mingw.
+
+@item
+This function returns 0 for dup2 (1, 1) on some platforms:
+Cygwin 1.5.x.
+
@item
This function is missing on some older platforms.
@end itemize
/* Duplicate an open file descriptor to a specified file descriptor.
- Copyright (C) 1999, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2004, 2005, 2006, 2007, 2009 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
#include <errno.h>
#include <fcntl.h>
-#ifndef F_DUPFD
+#if REPLACE_DUP2
+/* On mingw, dup2 exists, but always returns 0 for success. */
+int
+dup2 (int fd, int desired_fd)
+#undef dup2
+{
+ int result = dup2 (fd, desired_fd);
+ if (result == 0)
+ result = desired_fd;
+ return result;
+}
+
+#else /* !REPLACE_DUP2 */
+/* On older platforms, dup2 did not exist. */
+
+# ifndef F_DUPFD
static int
dupfd (int fd, int desired_fd)
{
return r;
}
}
-#endif
+# endif
int
dup2 (int fd, int desired_fd)
if (fd == desired_fd)
return fd;
close (desired_fd);
-#ifdef F_DUPFD
+# ifdef F_DUPFD
return fcntl (fd, F_DUPFD, desired_fd);
-#else
+# else
return dupfd (fd, desired_fd);
-#endif
+# endif
}
+#endif /* !REPLACE_DUP2 */
/* fchdir replacement.
- Copyright (C) 2006-2008 Free Software Foundation, Inc.
+ Copyright (C) 2006-2009 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
#undef dup2
{
int retval = dup2 (oldfd, newfd);
+#if REPLACE_DUP2
+ /* Inline mingw replacement from dup2.c. */
+ if (retval == 0)
+ retval = newfd;
+#endif
if (retval >= 0 && oldfd >= 0 && newfd >= 0 && newfd != oldfd)
{
#if @GNULIB_DUP2@
-# if !@HAVE_DUP2@
+# if @REPLACE_DUP2@
+# define dup2 rpl_dup2
+# endif
+# if !@HAVE_DUP2@ || @REPLACE_DUP2@
/* Copy the file descriptor OLDFD into file descriptor NEWFD. Do nothing if
NEWFD = OLDFD, otherwise close NEWFD first if it is open.
- Return 0 if successful, otherwise -1 and errno set.
+ Return newfd if successful, otherwise -1 and errno set.
See the POSIX:2001 specification
<http://www.opengroup.org/susv3xsh/dup2.html>. */
extern int dup2 (int oldfd, int newfd);
# define dup rpl_dup
extern int dup (int);
-# define dup2 rpl_dup2
+# if !@REPLACE_DUP2@
+# define dup2 rpl_dup2
extern int dup2 (int, int);
+# endif
# endif
#elif defined GNULIB_POSIXCHECK
-#serial 5
-dnl Copyright (C) 2002, 2005, 2007 Free Software Foundation, Inc.
+#serial 6
+dnl Copyright (C) 2002, 2005, 2007, 2009 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_DUP2],
[
AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
+ AC_REQUIRE([AC_CANONICAL_HOST])
AC_CHECK_FUNCS_ONCE([dup2])
if test $ac_cv_func_dup2 = no; then
HAVE_DUP2=0
AC_LIBOBJ([dup2])
+ else
+ AC_CACHE_CHECK([whether dup2 works], [gl_cv_func_dup2_works],
+ [AC_RUN_IFELSE([AC_LANG_PROGRAM([[
+#include <unistd.h>
+]], [return 1 - dup2 (1, 1);])],
+ [gl_cv_func_dup2_works=yes], [gl_cv_func_dup2_works=no],
+ [case "$host_os" in
+ mingw*) # on this platform, dup2 always returns 0 for success
+ gl_cv_func_dup2_works=no;;
+ cygwin*) # on cygwin 1.5.x, dup2(1,1) returns 0
+ gl_cv_func_dup2_works=no;;
+ *) gl_cv_func_dup2_works=yes;;
+ esac])])
+ if test "$gl_cv_func_dup2_works" = no; then
+ REPLACE_DUP2=1
+ AC_LIBOBJ([dup2])
+ fi
fi
+ AC_DEFINE_UNQUOTED([REPLACE_DUP2], [$REPLACE_DUP2],
+ [Define to 1 if dup2 returns 0 instead of the target fd.])
])
-# unistd_h.m4 serial 17
+# unistd_h.m4 serial 18
dnl Copyright (C) 2006-2009 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
HAVE_SYS_PARAM_H=0; AC_SUBST([HAVE_SYS_PARAM_H])
REPLACE_CHOWN=0; AC_SUBST([REPLACE_CHOWN])
REPLACE_CLOSE=0; AC_SUBST([REPLACE_CLOSE])
+ REPLACE_DUP2=0; AC_SUBST([REPLACE_DUP2])
REPLACE_FCHDIR=0; AC_SUBST([REPLACE_FCHDIR])
REPLACE_GETCWD=0; AC_SUBST([REPLACE_GETCWD])
REPLACE_GETPAGESIZE=0; AC_SUBST([REPLACE_GETPAGESIZE])
m4/execute.m4
Depends-on:
+dup2
error
exit
fatal-signal
lib/stdio-impl.h
Depends-on:
+dup2
configure.ac:
m4/pipe.m4
Depends-on:
+dup2
environ
error
exit
Depends-on:
spawn
alloca-opt
+dup2
errno
open
strchrnul
-e 's|@''HAVE_SYS_PARAM_H''@|$(HAVE_SYS_PARAM_H)|g' \
-e 's|@''REPLACE_CHOWN''@|$(REPLACE_CHOWN)|g' \
-e 's|@''REPLACE_CLOSE''@|$(REPLACE_CLOSE)|g' \
+ -e 's|@''REPLACE_DUP2''@|$(REPLACE_DUP2)|g' \
-e 's|@''REPLACE_FCHDIR''@|$(REPLACE_FCHDIR)|g' \
-e 's|@''REPLACE_GETCWD''@|$(REPLACE_GETCWD)|g' \
-e 's|@''REPLACE_GETPAGESIZE''@|$(REPLACE_GETPAGESIZE)|g' \