From 3f89a5e2c8f6fc011f525980ff99936a4b0445d0 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Sun, 8 Jan 2012 22:18:30 +0100 Subject: [PATCH] posix_spawn_file_actions_adddup2: Work around Solaris 11 2011-11 bug. * m4/spawn_h.m4 (gl_SPAWN_H_DEFAULTS): Initialize REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2. * m4/posix_spawn.m4 (gl_FUNC_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2): New macro. * lib/spawn.in.h (posix_spawn_file_actions_adddup2): Test REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2, not REPLACE_POSIX_SPAWN. * lib/spawn_faction_adddup2.c: Add workaround implementation if HAVE_WORKING_POSIX_SPAWN. * modules/spawn (Makefile): Substitute REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2. * modules/posix_spawn_file_actions_adddup2 (configure.ac): Invoke gl_FUNC_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2. Test REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2, not REPLACE_POSIX_SPAWN. (Depends-on): Update conditions. * doc/posix-functions/posix_spawn_file_actions_adddup2.texi: Mention the Solaris 11 bug. --- ChangeLog | 20 +++++++++++ .../posix_spawn_file_actions_adddup2.texi | 3 ++ lib/spawn.in.h | 2 +- lib/spawn_faction_adddup2.c | 30 ++++++++++------ m4/posix_spawn.m4 | 41 ++++++++++++++++++++++ m4/spawn_h.m4 | 2 ++ modules/posix_spawn_file_actions_adddup2 | 8 ++--- modules/spawn | 1 + 8 files changed, 92 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index 14144d8be..39af8aa6b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,25 @@ 2012-01-08 Bruno Haible + posix_spawn_file_actions_adddup2: Work around Solaris 11 2011-11 bug. + * m4/spawn_h.m4 (gl_SPAWN_H_DEFAULTS): Initialize + REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2. + * m4/posix_spawn.m4 (gl_FUNC_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2): New + macro. + * lib/spawn.in.h (posix_spawn_file_actions_adddup2): Test + REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2, not REPLACE_POSIX_SPAWN. + * lib/spawn_faction_adddup2.c: Add workaround implementation if + HAVE_WORKING_POSIX_SPAWN. + * modules/spawn (Makefile): Substitute + REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2. + * modules/posix_spawn_file_actions_adddup2 (configure.ac): Invoke + gl_FUNC_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2. Test + REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2, not REPLACE_POSIX_SPAWN. + (Depends-on): Update conditions. + * doc/posix-functions/posix_spawn_file_actions_adddup2.texi: Mention + the Solaris 11 bug. + +2012-01-08 Bruno Haible + posix_spawn_file_actions_addclose: Work around Solaris 11 2011-11 bug. * m4/spawn_h.m4 (gl_SPAWN_H_DEFAULTS): Initialize REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE. diff --git a/doc/posix-functions/posix_spawn_file_actions_adddup2.texi b/doc/posix-functions/posix_spawn_file_actions_adddup2.texi index c061eb2fa..04a6062d6 100644 --- a/doc/posix-functions/posix_spawn_file_actions_adddup2.texi +++ b/doc/posix-functions/posix_spawn_file_actions_adddup2.texi @@ -11,6 +11,9 @@ Portability problems fixed by Gnulib: @item This function is missing on some platforms: MacOS X 10.4, FreeBSD 6.0, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 5.1, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 9, Cygwin, mingw, MSVC 9, Interix 3.5, BeOS. +@item +This function does not reject a too large file descriptor on some platforms: +Solaris 11 2011-11. @end itemize Portability problems not fixed by Gnulib: diff --git a/lib/spawn.in.h b/lib/spawn.in.h index de1b07639..aa5aaf3f0 100644 --- a/lib/spawn.in.h +++ b/lib/spawn.in.h @@ -844,7 +844,7 @@ _GL_WARN_ON_USE (posix_spawn_file_actions_addclose, #if @GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2@ /* Add an action to FILE-ACTIONS which tells the implementation to call 'dup2' for the given file descriptors during the 'spawn' call. */ -# if @REPLACE_POSIX_SPAWN@ +# if @REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2@ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # define posix_spawn_file_actions_adddup2 rpl_posix_spawn_file_actions_adddup2 # endif diff --git a/lib/spawn_faction_adddup2.c b/lib/spawn_faction_adddup2.c index 692c167d3..08daa52db 100644 --- a/lib/spawn_faction_adddup2.c +++ b/lib/spawn_faction_adddup2.c @@ -26,35 +26,45 @@ # define __sysconf(open_max) getdtablesize () #endif -#include "spawn_int.h" +#if !HAVE_WORKING_POSIX_SPAWN +# include "spawn_int.h" +#endif /* Add an action to FILE-ACTIONS which tells the implementation to call 'dup2' for the given file descriptors during the 'spawn' call. */ int posix_spawn_file_actions_adddup2 (posix_spawn_file_actions_t *file_actions, int fd, int newfd) +#undef posix_spawn_file_actions_adddup2 { int maxfd = __sysconf (_SC_OPEN_MAX); - struct __spawn_action *rec; /* Test for the validity of the file descriptor. */ if (fd < 0 || newfd < 0 || fd >= maxfd || newfd >= maxfd) return EBADF; +#if HAVE_WORKING_POSIX_SPAWN + return posix_spawn_file_actions_adddup2 (file_actions, fd, newfd); +#else /* Allocate more memory if needed. */ if (file_actions->_used == file_actions->_allocated && __posix_spawn_file_actions_realloc (file_actions) != 0) /* This can only mean we ran out of memory. */ return ENOMEM; - /* Add the new value. */ - rec = &file_actions->_actions[file_actions->_used]; - rec->tag = spawn_do_dup2; - rec->action.dup2_action.fd = fd; - rec->action.dup2_action.newfd = newfd; + { + struct __spawn_action *rec; + + /* Add the new value. */ + rec = &file_actions->_actions[file_actions->_used]; + rec->tag = spawn_do_dup2; + rec->action.dup2_action.fd = fd; + rec->action.dup2_action.newfd = newfd; - /* Account for the new entry. */ - ++file_actions->_used; + /* Account for the new entry. */ + ++file_actions->_used; - return 0; + return 0; + } +#endif } diff --git a/m4/posix_spawn.m4 b/m4/posix_spawn.m4 index 378d6a53e..d0a734d09 100644 --- a/m4/posix_spawn.m4 +++ b/m4/posix_spawn.m4 @@ -441,3 +441,44 @@ int main () esac fi ]) + +AC_DEFUN([gl_FUNC_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2], +[ + AC_REQUIRE([gl_SPAWN_H_DEFAULTS]) + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + gl_POSIX_SPAWN + if test $REPLACE_POSIX_SPAWN = 1; then + REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2=1 + else + dnl On Solaris 11 2011-11, posix_spawn_file_actions_adddup2 succeeds even + dnl if the fd argument is out of range. + AC_CACHE_CHECK([whether posix_spawn_file_actions_adddup2 works], + [gl_cv_func_posix_spawn_file_actions_adddup2_works], + [AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +int main () +{ + posix_spawn_file_actions_t actions; + if (posix_spawn_file_actions_init (&actions) != 0) + return 1; + if (posix_spawn_file_actions_adddup2 (&actions, 10000000, 2) == 0) + return 2; + return 0; +}]])], + [gl_cv_func_posix_spawn_file_actions_adddup2_works=yes], + [gl_cv_func_posix_spawn_file_actions_adddup2_works=no], + [# Guess no on Solaris, yes otherwise. + case "$host_os" in + solaris*) gl_cv_func_posix_spawn_file_actions_adddup2_works="guessing no";; + *) gl_cv_func_posix_spawn_file_actions_adddup2_works="guessing yes";; + esac + ]) + ]) + case "$gl_cv_func_posix_spawn_file_actions_adddup2_works" in + *yes) ;; + *) REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2=1 ;; + esac + fi +]) diff --git a/m4/spawn_h.m4 b/m4/spawn_h.m4 index 9d898aa4e..ef56fb01f 100644 --- a/m4/spawn_h.m4 +++ b/m4/spawn_h.m4 @@ -110,4 +110,6 @@ AC_DEFUN([gl_SPAWN_H_DEFAULTS], REPLACE_POSIX_SPAWN=0; AC_SUBST([REPLACE_POSIX_SPAWN]) REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE=0; AC_SUBST([REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE]) + REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2=0; + AC_SUBST([REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2]) ]) diff --git a/modules/posix_spawn_file_actions_adddup2 b/modules/posix_spawn_file_actions_adddup2 index b7a6188ab..8251f249c 100644 --- a/modules/posix_spawn_file_actions_adddup2 +++ b/modules/posix_spawn_file_actions_adddup2 @@ -9,12 +9,12 @@ m4/posix_spawn.m4 Depends-on: spawn -getdtablesize [test $HAVE_POSIX_SPAWN = 0 || test $REPLACE_POSIX_SPAWN = 1] -posix_spawn_file_actions_init [test $HAVE_POSIX_SPAWN = 0 || test $REPLACE_POSIX_SPAWN = 1] +getdtablesize [test $HAVE_POSIX_SPAWN = 0 || test $REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2 = 1] +posix_spawn_file_actions_init [test $HAVE_POSIX_SPAWN = 0 || test $REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2 = 1] configure.ac: -gl_POSIX_SPAWN -if test $HAVE_POSIX_SPAWN = 0 || test $REPLACE_POSIX_SPAWN = 1; then +gl_FUNC_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2 +if test $HAVE_POSIX_SPAWN = 0 || test $REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2 = 1; then AC_LIBOBJ([spawn_faction_adddup2]) fi gl_SPAWN_MODULE_INDICATOR([posix_spawn_file_actions_adddup2]) diff --git a/modules/spawn b/modules/spawn index 1d7c7aa7e..866bdb104 100644 --- a/modules/spawn +++ b/modules/spawn @@ -55,6 +55,7 @@ spawn.h: spawn.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) -e 's|@''HAVE_POSIX_SPAWN_FILE_ACTIONS_T''@|$(HAVE_POSIX_SPAWN_FILE_ACTIONS_T)|g' \ -e 's|@''REPLACE_POSIX_SPAWN''@|$(REPLACE_POSIX_SPAWN)|g' \ -e 's|@''REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE''@|$(REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE)|g' \ + -e 's|@''REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2''@|$(REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2)|g' \ -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ -- 2.11.0