diff options
author | Joel E. Denny <jdenny@clemson.edu> | 2010-02-22 18:09:19 -0500 |
---|---|---|
committer | Joel E. Denny <jdenny@clemson.edu> | 2010-02-22 18:32:47 -0500 |
commit | 47fa574761319b0a422691223c9b8a9a72f36aa2 (patch) | |
tree | 293bebddb72a6e8ca06acc6da36d6d5a9e60f767 /lib | |
parent | d67e37a74bc91e2fe254e5b7a28c62537a20e206 (diff) | |
download | bison-47fa574761319b0a422691223c9b8a9a72f36aa2.tar.gz |
portability: fix several issues with M4 subprocess.
M4's output pipe was not being drained upon fatal errors during
scan_skel. As a result, broken-pipe messages from M4 were seen
on at least AIX, HP-UX, Solaris, and RHEL4, and this caused a
failure in the test suite. The problem was that, on platforms
where the default disposition for SIGPIPE is ignore instead of
terminate, M4 sometimes saw fwrite fail with errno=EPIPE and
then reported it. However, there's some sort of race condition,
because the new test group occasionally succeeded.
Reported by Albert Chin at
<http://lists.gnu.org/archive/html/bug-bison/2010-02/msg00004.html>.
There were also problems with the test suite livelocking on
Tru64 5.1b. Reported by Didier Godefroy at
<http://lists.gnu.org/archive/html/bug-bison/2009-05/msg00005.html>.
Switching to create_pipe_bidi suggested by Akim Demaille.
To attempt to solve both of these problems, switch to gnulib's
create_pipe_bidi and register M4 process as a slave. Along the
way, clean up file name conflict handling, which was affected by
the broken-pipe problem before the switch.
* NEWS (2.4.2): Document.
* THANKS (Didier Godefroy): Add.
* bootstrap.conf (gnulib_modules): Add pipe.
* gnulib: Update to latest to make sure we have all the latest
fixes.
* lib/Makefile.am (libbison_a_SOURCES): Remove subpipe.h and
subpipe.c.
* po/POTFILES.in (lib/subpipe.c): Remove.
* src/files.c (compute_output_file_names): Update invocations
of output_file_name_check.
(output_file_name_check): In the case that the grammar file
would be overwritten, use complain instead of fatal, but replace
the output file name with /dev/null. Use the /dev/null solution
for the case of two conflicting output files as well because it
seems safer in case Bison one day tries to open both files at
the same time.
* src/files.h (output_file_name_check): Update prototype.
* src/output.c (output_skeleton): Use create_pipe_bidi and
wait_subprocess. Assert that scan_skel completely drains the
pipe.
* src/scan-skel.l (at_directive_perform): Update
output_file_name_check invocation.
* tests/output.at (AT_CHECK_CONFLICTING_OUTPUT): Check that the
grammar file actually isn't overwritten.
(Conflicting output files: -o foo.y): Update expected output.
* tests/skeletons.at (Fatal errors but M4 continues producing
output): New test group.
(cherry picked from commit 22cc8d813ee57c9631e527a31010ab138f9b7e06)
Conflicts:
NEWS
bootstrap.conf
lib/.cvsignore
lib/.gitignore
m4/.cvsignore
m4/.gitignore
src/output.c
Diffstat (limited to 'lib')
-rw-r--r-- | lib/.cvsignore | 49 | ||||
-rw-r--r-- | lib/.gitignore | 49 | ||||
-rw-r--r-- | lib/Makefile.am | 1 | ||||
-rw-r--r-- | lib/subpipe.c | 177 | ||||
-rw-r--r-- | lib/subpipe.h | 28 |
5 files changed, 98 insertions, 206 deletions
diff --git a/lib/.cvsignore b/lib/.cvsignore index 01087fd4..d3c20e87 100644 --- a/lib/.cvsignore +++ b/lib/.cvsignore @@ -8,6 +8,7 @@ argmatch.h asnprintf.c basename-lgpl.c basename.c +binary-io.h bitrotate.h c-ctype.c c-ctype.h @@ -15,6 +16,8 @@ c-strcase.h c-strcasecmp.c c-strncasecmp.c charset.alias +cloexec.c +cloexec.h config.charset config.h config.hin @@ -22,6 +25,7 @@ configmake.h dirname-lgpl.c dirname.c dirname.h +dup-safer-flag.c dup-safer.c dup2.c errno.h @@ -30,9 +34,12 @@ error.c error.h exitfail.c exitfail.h +fatal-signal.c +fatal-signal.h fcntl.c fcntl.h fcntl.in.h +fd-safer-flag.c fd-safer.c float+.h float.h @@ -45,6 +52,7 @@ frexp.c frexpl.c fseterr.c fseterr.h +getdtablesize.c getopt.c getopt.h getopt.in.h @@ -80,7 +88,12 @@ memchr.c memchr.valgrind obstack.c obstack.h +open.c pipe-safer.c +pipe.c +pipe.h +pipe2-safer.c +pipe2.c printf-args.c printf-args.h printf-frexp.c @@ -94,18 +107,42 @@ quote.c quote.h quotearg.c quotearg.h +rawmemchr.c +rawmemchr.valgrind realloc.c ref-add.sed ref-add.sin ref-del.sed ref-del.sin +sched.h +sched.in.h +sig-handler.h +sigaction.c +signal.h +signal.in.h signbitd.c signbitf.c signbitl.c +sigprocmask.c size_max.h snprintf.c +spawn.h +spawn.in.h +spawn_faction_addclose.c +spawn_faction_adddup2.c +spawn_faction_addopen.c +spawn_faction_destroy.c +spawn_faction_init.c +spawn_int.h +spawnattr_destroy.c +spawnattr_init.c +spawnattr_setflags.c +spawnattr_setsigmask.c +spawni.c +spawnp.c sprintf.c stamp-h1 +stat.c stdbool.h stdbool.in.h stdbool_.h @@ -124,6 +161,8 @@ stdlib.h stdlib.in.h stdlib_.h stpcpy.c +strchrnul.c +strchrnul.valgrind streq.h strerror.c string.h @@ -136,6 +175,13 @@ strtol.c strtoul.c strverscmp.c strverscmp.h +sys +sys_stat.h +sys_stat.in.h +sys_wait.h +sys_wait.in.h +time.h +time.in.h unistd--.h unistd-safer.h unistd.h @@ -152,6 +198,9 @@ verify.h vfprintf.c vsnprintf.c vsprintf.c +w32spawn.h +wait-process.c +wait-process.h wchar.h wchar.in.h wchar_.h diff --git a/lib/.gitignore b/lib/.gitignore index 44d4102b..b2890169 100644 --- a/lib/.gitignore +++ b/lib/.gitignore @@ -11,6 +11,7 @@ /asnprintf.c /basename-lgpl.c /basename.c +/binary-io.h /bitrotate.h /c-ctype.c /c-ctype.h @@ -18,6 +19,8 @@ /c-strcasecmp.c /c-strncasecmp.c /charset.alias +/cloexec.c +/cloexec.h /config.charset /config.h /config.hin @@ -25,6 +28,7 @@ /dirname-lgpl.c /dirname.c /dirname.h +/dup-safer-flag.c /dup-safer.c /dup2.c /errno.h @@ -33,9 +37,12 @@ /error.h /exitfail.c /exitfail.h +/fatal-signal.c +/fatal-signal.h /fcntl.c /fcntl.h /fcntl.in.h +/fd-safer-flag.c /fd-safer.c /float+.h /float.h @@ -48,6 +55,7 @@ /frexpl.c /fseterr.c /fseterr.h +/getdtablesize.c /getopt.c /getopt.h /getopt.in.h @@ -83,7 +91,12 @@ /memchr.valgrind /obstack.c /obstack.h +/open.c /pipe-safer.c +/pipe.c +/pipe.h +/pipe2-safer.c +/pipe2.c /printf-args.c /printf-args.h /printf-frexp.c @@ -97,18 +110,42 @@ /quote.h /quotearg.c /quotearg.h +/rawmemchr.c +/rawmemchr.valgrind /realloc.c /ref-add.sed /ref-add.sin /ref-del.sed /ref-del.sin +/sched.h +/sched.in.h +/sig-handler.h +/sigaction.c +/signal.h +/signal.in.h /signbitd.c /signbitf.c /signbitl.c +/sigprocmask.c /size_max.h /snprintf.c +/spawn.h +/spawn.in.h +/spawn_faction_addclose.c +/spawn_faction_adddup2.c +/spawn_faction_addopen.c +/spawn_faction_destroy.c +/spawn_faction_init.c +/spawn_int.h +/spawnattr_destroy.c +/spawnattr_init.c +/spawnattr_setflags.c +/spawnattr_setsigmask.c +/spawni.c +/spawnp.c /sprintf.c /stamp-h1 +/stat.c /stdbool.h /stdbool.in.h /stdbool_.h @@ -127,6 +164,8 @@ /stdlib.in.h /stdlib_.h /stpcpy.c +/strchrnul.c +/strchrnul.valgrind /streq.h /strerror.c /string.h @@ -139,6 +178,13 @@ /strtoul.c /strverscmp.c /strverscmp.h +/sys +/sys_stat.h +/sys_stat.in.h +/sys_wait.h +/sys_wait.in.h +/time.h +/time.in.h /unistd--.h /unistd-safer.h /unistd.h @@ -155,6 +201,9 @@ /vfprintf.c /vsnprintf.c /vsprintf.c +/w32spawn.h +/wait-process.c +/wait-process.h /wchar.h /wchar.in.h /wchar_.h diff --git a/lib/Makefile.am b/lib/Makefile.am index 77ca6646..c2b4ec27 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -37,7 +37,6 @@ timevars_sources = \ # Non-gnulib sources in Bison's internal library. libbison_a_SOURCES += \ get-errno.h get-errno.c \ - subpipe.h subpipe.c \ $(bitsets_sources) $(additional_bitsets_sources) $(timevars_sources) # The Yacc compatibility library. diff --git a/lib/subpipe.c b/lib/subpipe.c deleted file mode 100644 index 1b7c36d8..00000000 --- a/lib/subpipe.c +++ /dev/null @@ -1,177 +0,0 @@ -/* Subprocesses with pipes. - - Copyright (C) 2002, 2004-2006, 2009-2010 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/>. */ - -/* Written by Paul Eggert <eggert@twinsun.com> - and Florian Krohm <florian@edamail.fishkill.ibm.com>. */ - -#include <config.h> - -#include "subpipe.h" - -#include <errno.h> - -#include <signal.h> -#if ! defined SIGCHLD && defined SIGCLD -# define SIGCHLD SIGCLD -#endif - -#include <stdlib.h> - -#include <unistd.h> -#ifndef STDIN_FILENO -# define STDIN_FILENO 0 -#endif -#ifndef STDOUT_FILENO -# define STDOUT_FILENO 1 -#endif -#if ! HAVE_DUP2 && ! defined dup2 -# include <fcntl.h> -# define dup2(f, t) (close (t), fcntl (f, F_DUPFD, t)) -#endif - -#if HAVE_SYS_WAIT_H -# include <sys/wait.h> -#endif -#ifndef WEXITSTATUS -# define WEXITSTATUS(stat_val) ((unsigned int) (stat_val) >> 8) -#endif -#ifndef WIFEXITED -# define WIFEXITED(stat_val) (((stat_val) & 255) == 0) -#endif - -#if HAVE_VFORK_H -# include <vfork.h> -#endif -#if ! HAVE_WORKING_VFORK -# define vfork fork -#endif - -#include "error.h" -#include "unistd-safer.h" - -#include "gettext.h" -#define _(Msgid) gettext (Msgid) - -#ifndef __attribute__ -/* This feature is available in gcc versions 2.5 and later. */ -# if ! defined __GNUC__ || __GNUC__ < 2 || \ -(__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__ -# define __attribute__(Spec) /* empty */ -# endif -#endif - -#ifndef ATTRIBUTE_UNUSED -# define ATTRIBUTE_UNUSED __attribute__ ((__unused__)) -#endif - - -/* Initialize this module. */ - -void -init_subpipe (void) -{ -#ifdef SIGCHLD - /* System V fork+wait does not work if SIGCHLD is ignored. */ - signal (SIGCHLD, SIG_DFL); -#endif -} - - -/* Create a subprocess that is run as a filter. ARGV is the - NULL-terminated argument vector for the subprocess. Store read and - write file descriptors for communication with the subprocess into - FD[0] and FD[1]: input meant for the process can be written into - FD[0], and output from the process can be read from FD[1]. Return - the subprocess id. - - To avoid deadlock, the invoker must not let incoming data pile up - in FD[1] while writing data to FD[0]. */ - -pid_t -create_subpipe (char const * const *argv, int fd[2]) -{ - int pipe_fd[2]; - int child_fd[2]; - pid_t pid; - - if (pipe_safer (child_fd) != 0 || pipe_safer (pipe_fd) != 0) - error (EXIT_FAILURE, errno, "pipe"); - fd[0] = child_fd[1]; - fd[1] = pipe_fd[0]; - child_fd[1] = pipe_fd[1]; - - pid = vfork (); - if (pid < 0) - error (EXIT_FAILURE, errno, "fork"); - - if (! pid) - { - /* Child. */ - close (fd[0]); - close (fd[1]); - dup2 (child_fd[0], STDIN_FILENO); - close (child_fd[0]); - dup2 (child_fd[1], STDOUT_FILENO); - close (child_fd[1]); - - /* The cast to (char **) rather than (char * const *) is needed - for portability to older hosts with a nonstandard prototype - for execvp. */ - execvp (argv[0], (char **) argv); - - _exit (errno == ENOENT ? 127 : 126); - } - - /* Parent. */ - close (child_fd[0]); - close (child_fd[1]); - return pid; -} - - -/* Wait for the subprocess to exit. */ - -void -reap_subpipe (pid_t pid, char const *program) -{ -#if HAVE_WAITPID || defined waitpid - int wstatus; - if (waitpid (pid, &wstatus, 0) < 0) - error (EXIT_FAILURE, errno, "waitpid"); - else - { - int status = WIFEXITED (wstatus) ? WEXITSTATUS (wstatus) : -1; - if (status) - error (EXIT_FAILURE, 0, - _(status == 126 - ? "subsidiary program `%s' could not be invoked" - : status == 127 - ? "subsidiary program `%s' not found" - : status < 0 - ? "subsidiary program `%s' failed" - : "subsidiary program `%s' failed (exit status %d)"), - program, status); - } -#endif -} - -void -end_of_output_subpipe (pid_t pid ATTRIBUTE_UNUSED, - int fd[2] ATTRIBUTE_UNUSED) -{ -} diff --git a/lib/subpipe.h b/lib/subpipe.h deleted file mode 100644 index ff791a81..00000000 --- a/lib/subpipe.h +++ /dev/null @@ -1,28 +0,0 @@ -/* Subprocesses with pipes. - Copyright (C) 2002, 2004-2005, 2009-2010 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/>. */ - -/* Written by Paul Eggert <eggert@twinsun.com> - and Florian Krohm <florian@edamail.fishkill.ibm.com>. */ - -#if HAVE_SYS_TYPES_H -# include <sys/types.h> -#endif - -void init_subpipe (void); -pid_t create_subpipe (char const * const *, int[2]); -void end_of_output_subpipe (pid_t, int[2]); -void reap_subpipe (pid_t, char const *); |