mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 04:13:03 +00:00
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 22cc8d813e)
Conflicts:
NEWS
bootstrap.conf
lib/.cvsignore
lib/.gitignore
m4/.cvsignore
m4/.gitignore
src/output.c
This commit is contained in:
52
ChangeLog
52
ChangeLog
@@ -1,3 +1,55 @@
|
|||||||
|
2010-02-22 Joel E. Denny <jdenny@ces.clemson.edu>
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
2010-02-04 Joel E. Denny <jdenny@ces.clemson.edu>
|
2010-02-04 Joel E. Denny <jdenny@ces.clemson.edu>
|
||||||
|
|
||||||
Update POTFILES.
|
Update POTFILES.
|
||||||
|
|||||||
6
NEWS
6
NEWS
@@ -188,6 +188,12 @@ Bison News
|
|||||||
|
|
||||||
* Changes in version 2.4.2 (????-??-??):
|
* Changes in version 2.4.2 (????-??-??):
|
||||||
|
|
||||||
|
** Some portability problems that resulted in failures and livelocks
|
||||||
|
in the test suite on some versions of at least Solaris, AIX, HP-UX,
|
||||||
|
RHEL4, and Tru64 have been fixed. As part of those fixes, fatal
|
||||||
|
Bison errors no longer cause M4 to report a broken pipe on the
|
||||||
|
affected platforms.
|
||||||
|
|
||||||
** `%prec IDENTIFIER' requires IDENTIFIER to be defined separately.
|
** `%prec IDENTIFIER' requires IDENTIFIER to be defined separately.
|
||||||
|
|
||||||
POSIX specifies that an error be reported for any identifier that does
|
POSIX specifies that an error be reported for any identifier that does
|
||||||
|
|||||||
1
THANKS
1
THANKS
@@ -29,6 +29,7 @@ David J. MacKenzie djm@gnu.org
|
|||||||
Derek M. Jones derek@knosof.co.uk
|
Derek M. Jones derek@knosof.co.uk
|
||||||
Di-an Jan dianj@freeshell.org
|
Di-an Jan dianj@freeshell.org
|
||||||
Dick Streefland dick.streefland@altium.nl
|
Dick Streefland dick.streefland@altium.nl
|
||||||
|
Didier Godefroy dg@ulysium.net
|
||||||
Enrico Scholz enrico.scholz@informatik.tu-chemnitz.de
|
Enrico Scholz enrico.scholz@informatik.tu-chemnitz.de
|
||||||
Eric Blake ebb9@byu.net
|
Eric Blake ebb9@byu.net
|
||||||
Evgeny Stambulchik fnevgeny@plasma-gate.weizmann.ac.il
|
Evgeny Stambulchik fnevgeny@plasma-gate.weizmann.ac.il
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ gnulib_modules='
|
|||||||
announce-gen argmatch assert config-h c-strcase configmake dirname
|
announce-gen argmatch assert config-h c-strcase configmake dirname
|
||||||
error extensions fopen-safer gendocs getopt-gnu gettext
|
error extensions fopen-safer gendocs getopt-gnu gettext
|
||||||
git-version-gen hash inttypes javacomp-script javaexec-script
|
git-version-gen hash inttypes javacomp-script javaexec-script
|
||||||
maintainer-makefile malloc mbswidth obstack quote quotearg
|
maintainer-makefile malloc mbswidth obstack pipe quote quotearg
|
||||||
realloc-posix stdbool stpcpy strerror strtoul strverscmp unistd
|
realloc-posix stdbool stpcpy strerror strtoul strverscmp unistd
|
||||||
unistd-safer unlocked-io update-copyright unsetenv verify warnings
|
unistd-safer unlocked-io update-copyright unsetenv verify warnings
|
||||||
xalloc xalloc-die xstrndup
|
xalloc xalloc-die xstrndup
|
||||||
|
|||||||
2
gnulib
2
gnulib
Submodule gnulib updated: 102c411be0...9d0ad652de
@@ -8,6 +8,7 @@ argmatch.h
|
|||||||
asnprintf.c
|
asnprintf.c
|
||||||
basename-lgpl.c
|
basename-lgpl.c
|
||||||
basename.c
|
basename.c
|
||||||
|
binary-io.h
|
||||||
bitrotate.h
|
bitrotate.h
|
||||||
c-ctype.c
|
c-ctype.c
|
||||||
c-ctype.h
|
c-ctype.h
|
||||||
@@ -15,6 +16,8 @@ c-strcase.h
|
|||||||
c-strcasecmp.c
|
c-strcasecmp.c
|
||||||
c-strncasecmp.c
|
c-strncasecmp.c
|
||||||
charset.alias
|
charset.alias
|
||||||
|
cloexec.c
|
||||||
|
cloexec.h
|
||||||
config.charset
|
config.charset
|
||||||
config.h
|
config.h
|
||||||
config.hin
|
config.hin
|
||||||
@@ -22,6 +25,7 @@ configmake.h
|
|||||||
dirname-lgpl.c
|
dirname-lgpl.c
|
||||||
dirname.c
|
dirname.c
|
||||||
dirname.h
|
dirname.h
|
||||||
|
dup-safer-flag.c
|
||||||
dup-safer.c
|
dup-safer.c
|
||||||
dup2.c
|
dup2.c
|
||||||
errno.h
|
errno.h
|
||||||
@@ -30,9 +34,12 @@ error.c
|
|||||||
error.h
|
error.h
|
||||||
exitfail.c
|
exitfail.c
|
||||||
exitfail.h
|
exitfail.h
|
||||||
|
fatal-signal.c
|
||||||
|
fatal-signal.h
|
||||||
fcntl.c
|
fcntl.c
|
||||||
fcntl.h
|
fcntl.h
|
||||||
fcntl.in.h
|
fcntl.in.h
|
||||||
|
fd-safer-flag.c
|
||||||
fd-safer.c
|
fd-safer.c
|
||||||
float+.h
|
float+.h
|
||||||
float.h
|
float.h
|
||||||
@@ -45,6 +52,7 @@ frexp.c
|
|||||||
frexpl.c
|
frexpl.c
|
||||||
fseterr.c
|
fseterr.c
|
||||||
fseterr.h
|
fseterr.h
|
||||||
|
getdtablesize.c
|
||||||
getopt.c
|
getopt.c
|
||||||
getopt.h
|
getopt.h
|
||||||
getopt.in.h
|
getopt.in.h
|
||||||
@@ -80,7 +88,12 @@ memchr.c
|
|||||||
memchr.valgrind
|
memchr.valgrind
|
||||||
obstack.c
|
obstack.c
|
||||||
obstack.h
|
obstack.h
|
||||||
|
open.c
|
||||||
pipe-safer.c
|
pipe-safer.c
|
||||||
|
pipe.c
|
||||||
|
pipe.h
|
||||||
|
pipe2-safer.c
|
||||||
|
pipe2.c
|
||||||
printf-args.c
|
printf-args.c
|
||||||
printf-args.h
|
printf-args.h
|
||||||
printf-frexp.c
|
printf-frexp.c
|
||||||
@@ -94,18 +107,42 @@ quote.c
|
|||||||
quote.h
|
quote.h
|
||||||
quotearg.c
|
quotearg.c
|
||||||
quotearg.h
|
quotearg.h
|
||||||
|
rawmemchr.c
|
||||||
|
rawmemchr.valgrind
|
||||||
realloc.c
|
realloc.c
|
||||||
ref-add.sed
|
ref-add.sed
|
||||||
ref-add.sin
|
ref-add.sin
|
||||||
ref-del.sed
|
ref-del.sed
|
||||||
ref-del.sin
|
ref-del.sin
|
||||||
|
sched.h
|
||||||
|
sched.in.h
|
||||||
|
sig-handler.h
|
||||||
|
sigaction.c
|
||||||
|
signal.h
|
||||||
|
signal.in.h
|
||||||
signbitd.c
|
signbitd.c
|
||||||
signbitf.c
|
signbitf.c
|
||||||
signbitl.c
|
signbitl.c
|
||||||
|
sigprocmask.c
|
||||||
size_max.h
|
size_max.h
|
||||||
snprintf.c
|
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
|
sprintf.c
|
||||||
stamp-h1
|
stamp-h1
|
||||||
|
stat.c
|
||||||
stdbool.h
|
stdbool.h
|
||||||
stdbool.in.h
|
stdbool.in.h
|
||||||
stdbool_.h
|
stdbool_.h
|
||||||
@@ -124,6 +161,8 @@ stdlib.h
|
|||||||
stdlib.in.h
|
stdlib.in.h
|
||||||
stdlib_.h
|
stdlib_.h
|
||||||
stpcpy.c
|
stpcpy.c
|
||||||
|
strchrnul.c
|
||||||
|
strchrnul.valgrind
|
||||||
streq.h
|
streq.h
|
||||||
strerror.c
|
strerror.c
|
||||||
string.h
|
string.h
|
||||||
@@ -136,6 +175,13 @@ strtol.c
|
|||||||
strtoul.c
|
strtoul.c
|
||||||
strverscmp.c
|
strverscmp.c
|
||||||
strverscmp.h
|
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--.h
|
||||||
unistd-safer.h
|
unistd-safer.h
|
||||||
unistd.h
|
unistd.h
|
||||||
@@ -152,6 +198,9 @@ verify.h
|
|||||||
vfprintf.c
|
vfprintf.c
|
||||||
vsnprintf.c
|
vsnprintf.c
|
||||||
vsprintf.c
|
vsprintf.c
|
||||||
|
w32spawn.h
|
||||||
|
wait-process.c
|
||||||
|
wait-process.h
|
||||||
wchar.h
|
wchar.h
|
||||||
wchar.in.h
|
wchar.in.h
|
||||||
wchar_.h
|
wchar_.h
|
||||||
|
|||||||
49
lib/.gitignore
vendored
49
lib/.gitignore
vendored
@@ -11,6 +11,7 @@
|
|||||||
/asnprintf.c
|
/asnprintf.c
|
||||||
/basename-lgpl.c
|
/basename-lgpl.c
|
||||||
/basename.c
|
/basename.c
|
||||||
|
/binary-io.h
|
||||||
/bitrotate.h
|
/bitrotate.h
|
||||||
/c-ctype.c
|
/c-ctype.c
|
||||||
/c-ctype.h
|
/c-ctype.h
|
||||||
@@ -18,6 +19,8 @@
|
|||||||
/c-strcasecmp.c
|
/c-strcasecmp.c
|
||||||
/c-strncasecmp.c
|
/c-strncasecmp.c
|
||||||
/charset.alias
|
/charset.alias
|
||||||
|
/cloexec.c
|
||||||
|
/cloexec.h
|
||||||
/config.charset
|
/config.charset
|
||||||
/config.h
|
/config.h
|
||||||
/config.hin
|
/config.hin
|
||||||
@@ -25,6 +28,7 @@
|
|||||||
/dirname-lgpl.c
|
/dirname-lgpl.c
|
||||||
/dirname.c
|
/dirname.c
|
||||||
/dirname.h
|
/dirname.h
|
||||||
|
/dup-safer-flag.c
|
||||||
/dup-safer.c
|
/dup-safer.c
|
||||||
/dup2.c
|
/dup2.c
|
||||||
/errno.h
|
/errno.h
|
||||||
@@ -33,9 +37,12 @@
|
|||||||
/error.h
|
/error.h
|
||||||
/exitfail.c
|
/exitfail.c
|
||||||
/exitfail.h
|
/exitfail.h
|
||||||
|
/fatal-signal.c
|
||||||
|
/fatal-signal.h
|
||||||
/fcntl.c
|
/fcntl.c
|
||||||
/fcntl.h
|
/fcntl.h
|
||||||
/fcntl.in.h
|
/fcntl.in.h
|
||||||
|
/fd-safer-flag.c
|
||||||
/fd-safer.c
|
/fd-safer.c
|
||||||
/float+.h
|
/float+.h
|
||||||
/float.h
|
/float.h
|
||||||
@@ -48,6 +55,7 @@
|
|||||||
/frexpl.c
|
/frexpl.c
|
||||||
/fseterr.c
|
/fseterr.c
|
||||||
/fseterr.h
|
/fseterr.h
|
||||||
|
/getdtablesize.c
|
||||||
/getopt.c
|
/getopt.c
|
||||||
/getopt.h
|
/getopt.h
|
||||||
/getopt.in.h
|
/getopt.in.h
|
||||||
@@ -83,7 +91,12 @@
|
|||||||
/memchr.valgrind
|
/memchr.valgrind
|
||||||
/obstack.c
|
/obstack.c
|
||||||
/obstack.h
|
/obstack.h
|
||||||
|
/open.c
|
||||||
/pipe-safer.c
|
/pipe-safer.c
|
||||||
|
/pipe.c
|
||||||
|
/pipe.h
|
||||||
|
/pipe2-safer.c
|
||||||
|
/pipe2.c
|
||||||
/printf-args.c
|
/printf-args.c
|
||||||
/printf-args.h
|
/printf-args.h
|
||||||
/printf-frexp.c
|
/printf-frexp.c
|
||||||
@@ -97,18 +110,42 @@
|
|||||||
/quote.h
|
/quote.h
|
||||||
/quotearg.c
|
/quotearg.c
|
||||||
/quotearg.h
|
/quotearg.h
|
||||||
|
/rawmemchr.c
|
||||||
|
/rawmemchr.valgrind
|
||||||
/realloc.c
|
/realloc.c
|
||||||
/ref-add.sed
|
/ref-add.sed
|
||||||
/ref-add.sin
|
/ref-add.sin
|
||||||
/ref-del.sed
|
/ref-del.sed
|
||||||
/ref-del.sin
|
/ref-del.sin
|
||||||
|
/sched.h
|
||||||
|
/sched.in.h
|
||||||
|
/sig-handler.h
|
||||||
|
/sigaction.c
|
||||||
|
/signal.h
|
||||||
|
/signal.in.h
|
||||||
/signbitd.c
|
/signbitd.c
|
||||||
/signbitf.c
|
/signbitf.c
|
||||||
/signbitl.c
|
/signbitl.c
|
||||||
|
/sigprocmask.c
|
||||||
/size_max.h
|
/size_max.h
|
||||||
/snprintf.c
|
/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
|
/sprintf.c
|
||||||
/stamp-h1
|
/stamp-h1
|
||||||
|
/stat.c
|
||||||
/stdbool.h
|
/stdbool.h
|
||||||
/stdbool.in.h
|
/stdbool.in.h
|
||||||
/stdbool_.h
|
/stdbool_.h
|
||||||
@@ -127,6 +164,8 @@
|
|||||||
/stdlib.in.h
|
/stdlib.in.h
|
||||||
/stdlib_.h
|
/stdlib_.h
|
||||||
/stpcpy.c
|
/stpcpy.c
|
||||||
|
/strchrnul.c
|
||||||
|
/strchrnul.valgrind
|
||||||
/streq.h
|
/streq.h
|
||||||
/strerror.c
|
/strerror.c
|
||||||
/string.h
|
/string.h
|
||||||
@@ -139,6 +178,13 @@
|
|||||||
/strtoul.c
|
/strtoul.c
|
||||||
/strverscmp.c
|
/strverscmp.c
|
||||||
/strverscmp.h
|
/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--.h
|
||||||
/unistd-safer.h
|
/unistd-safer.h
|
||||||
/unistd.h
|
/unistd.h
|
||||||
@@ -155,6 +201,9 @@
|
|||||||
/vfprintf.c
|
/vfprintf.c
|
||||||
/vsnprintf.c
|
/vsnprintf.c
|
||||||
/vsprintf.c
|
/vsprintf.c
|
||||||
|
/w32spawn.h
|
||||||
|
/wait-process.c
|
||||||
|
/wait-process.h
|
||||||
/wchar.h
|
/wchar.h
|
||||||
/wchar.in.h
|
/wchar.in.h
|
||||||
/wchar_.h
|
/wchar_.h
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ timevars_sources = \
|
|||||||
# Non-gnulib sources in Bison's internal library.
|
# Non-gnulib sources in Bison's internal library.
|
||||||
libbison_a_SOURCES += \
|
libbison_a_SOURCES += \
|
||||||
get-errno.h get-errno.c \
|
get-errno.h get-errno.c \
|
||||||
subpipe.h subpipe.c \
|
|
||||||
$(bitsets_sources) $(additional_bitsets_sources) $(timevars_sources)
|
$(bitsets_sources) $(additional_bitsets_sources) $(timevars_sources)
|
||||||
|
|
||||||
# The Yacc compatibility library.
|
# The Yacc compatibility library.
|
||||||
|
|||||||
177
lib/subpipe.c
177
lib/subpipe.c
@@ -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)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
@@ -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 *);
|
|
||||||
@@ -3,6 +3,7 @@ absolute-header.m4
|
|||||||
alloca.m4
|
alloca.m4
|
||||||
argmatch.m4
|
argmatch.m4
|
||||||
assert.m4
|
assert.m4
|
||||||
|
cloexec.m4
|
||||||
config-h.m4
|
config-h.m4
|
||||||
dirname.m4
|
dirname.m4
|
||||||
dos.m4
|
dos.m4
|
||||||
@@ -16,6 +17,7 @@ exponentd.m4
|
|||||||
exponentf.m4
|
exponentf.m4
|
||||||
exponentl.m4
|
exponentl.m4
|
||||||
extensions.m4
|
extensions.m4
|
||||||
|
fatal-signal.m4
|
||||||
fcntl-o.m4
|
fcntl-o.m4
|
||||||
fcntl.m4
|
fcntl.m4
|
||||||
fcntl_h.m4
|
fcntl_h.m4
|
||||||
@@ -25,6 +27,7 @@ fpieee.m4
|
|||||||
fprintf-posix.m4
|
fprintf-posix.m4
|
||||||
frexp.m4
|
frexp.m4
|
||||||
frexpl.m4
|
frexpl.m4
|
||||||
|
getdtablesize.m4
|
||||||
getopt.m4
|
getopt.m4
|
||||||
getpagesize.m4
|
getpagesize.m4
|
||||||
gettext.m4
|
gettext.m4
|
||||||
@@ -63,10 +66,15 @@ mbstate_t.m4
|
|||||||
mbswidth.m4
|
mbswidth.m4
|
||||||
memchr.m4
|
memchr.m4
|
||||||
mmap-anon.m4
|
mmap-anon.m4
|
||||||
|
mode_t.m4
|
||||||
multiarch.m4
|
multiarch.m4
|
||||||
nls.m4
|
nls.m4
|
||||||
nocrash.m4
|
nocrash.m4
|
||||||
|
open.m4
|
||||||
|
pipe.m4
|
||||||
|
pipe2.m4
|
||||||
po.m4
|
po.m4
|
||||||
|
posix_spawn.m4
|
||||||
printf-frexp.m4
|
printf-frexp.m4
|
||||||
printf-frexpl.m4
|
printf-frexpl.m4
|
||||||
printf-posix-rpl.m4
|
printf-posix-rpl.m4
|
||||||
@@ -75,12 +83,20 @@ printf.m4
|
|||||||
progtest.m4
|
progtest.m4
|
||||||
quote.m4
|
quote.m4
|
||||||
quotearg.m4
|
quotearg.m4
|
||||||
|
rawmemchr.m4
|
||||||
realloc.m4
|
realloc.m4
|
||||||
|
sched_h.m4
|
||||||
setenv.m4
|
setenv.m4
|
||||||
|
sig_atomic_t.m4
|
||||||
|
sigaction.m4
|
||||||
|
signal_h.m4
|
||||||
|
signalblocking.m4
|
||||||
signbit.m4
|
signbit.m4
|
||||||
snprintf-posix.m4
|
snprintf-posix.m4
|
||||||
snprintf.m4
|
snprintf.m4
|
||||||
|
spawn_h.m4
|
||||||
sprintf-posix.m4
|
sprintf-posix.m4
|
||||||
|
stat.m4
|
||||||
stdbool.m4
|
stdbool.m4
|
||||||
stddef_h.m4
|
stddef_h.m4
|
||||||
stdint.m4
|
stdint.m4
|
||||||
@@ -89,6 +105,7 @@ stdio-safer.m4
|
|||||||
stdio_h.m4
|
stdio_h.m4
|
||||||
stdlib_h.m4
|
stdlib_h.m4
|
||||||
stpcpy.m4
|
stpcpy.m4
|
||||||
|
strchrnul.m4
|
||||||
strerror.m4
|
strerror.m4
|
||||||
string_h.m4
|
string_h.m4
|
||||||
strndup.m4
|
strndup.m4
|
||||||
@@ -96,7 +113,10 @@ strnlen.m4
|
|||||||
strtol.m4
|
strtol.m4
|
||||||
strtoul.m4
|
strtoul.m4
|
||||||
strverscmp.m4
|
strverscmp.m4
|
||||||
|
sys_stat_h.m4
|
||||||
|
sys_wait_h.m4
|
||||||
threadlib.m4
|
threadlib.m4
|
||||||
|
time_h.m4
|
||||||
unistd-safer.m4
|
unistd-safer.m4
|
||||||
unistd_h.m4
|
unistd_h.m4
|
||||||
unlocked-io.m4
|
unlocked-io.m4
|
||||||
@@ -105,6 +125,7 @@ vfprintf-posix.m4
|
|||||||
vsnprintf-posix.m4
|
vsnprintf-posix.m4
|
||||||
vsnprintf.m4
|
vsnprintf.m4
|
||||||
vsprintf-posix.m4
|
vsprintf-posix.m4
|
||||||
|
wait-process.m4
|
||||||
warn-on-use.m4
|
warn-on-use.m4
|
||||||
warning.m4
|
warning.m4
|
||||||
warnings.m4
|
warnings.m4
|
||||||
|
|||||||
21
m4/.gitignore
vendored
21
m4/.gitignore
vendored
@@ -3,6 +3,7 @@
|
|||||||
/alloca.m4
|
/alloca.m4
|
||||||
/argmatch.m4
|
/argmatch.m4
|
||||||
/assert.m4
|
/assert.m4
|
||||||
|
/cloexec.m4
|
||||||
/config-h.m4
|
/config-h.m4
|
||||||
/dirname.m4
|
/dirname.m4
|
||||||
/dos.m4
|
/dos.m4
|
||||||
@@ -16,6 +17,7 @@
|
|||||||
/exponentf.m4
|
/exponentf.m4
|
||||||
/exponentl.m4
|
/exponentl.m4
|
||||||
/extensions.m4
|
/extensions.m4
|
||||||
|
/fatal-signal.m4
|
||||||
/fcntl-o.m4
|
/fcntl-o.m4
|
||||||
/fcntl.m4
|
/fcntl.m4
|
||||||
/fcntl_h.m4
|
/fcntl_h.m4
|
||||||
@@ -25,6 +27,7 @@
|
|||||||
/fprintf-posix.m4
|
/fprintf-posix.m4
|
||||||
/frexp.m4
|
/frexp.m4
|
||||||
/frexpl.m4
|
/frexpl.m4
|
||||||
|
/getdtablesize.m4
|
||||||
/getopt.m4
|
/getopt.m4
|
||||||
/getpagesize.m4
|
/getpagesize.m4
|
||||||
/gettext.m4
|
/gettext.m4
|
||||||
@@ -63,10 +66,15 @@
|
|||||||
/mbswidth.m4
|
/mbswidth.m4
|
||||||
/memchr.m4
|
/memchr.m4
|
||||||
/mmap-anon.m4
|
/mmap-anon.m4
|
||||||
|
/mode_t.m4
|
||||||
/multiarch.m4
|
/multiarch.m4
|
||||||
/nls.m4
|
/nls.m4
|
||||||
/nocrash.m4
|
/nocrash.m4
|
||||||
|
/open.m4
|
||||||
|
/pipe.m4
|
||||||
|
/pipe2.m4
|
||||||
/po.m4
|
/po.m4
|
||||||
|
/posix_spawn.m4
|
||||||
/printf-frexp.m4
|
/printf-frexp.m4
|
||||||
/printf-frexpl.m4
|
/printf-frexpl.m4
|
||||||
/printf-posix-rpl.m4
|
/printf-posix-rpl.m4
|
||||||
@@ -75,12 +83,20 @@
|
|||||||
/progtest.m4
|
/progtest.m4
|
||||||
/quote.m4
|
/quote.m4
|
||||||
/quotearg.m4
|
/quotearg.m4
|
||||||
|
/rawmemchr.m4
|
||||||
/realloc.m4
|
/realloc.m4
|
||||||
|
/sched_h.m4
|
||||||
/setenv.m4
|
/setenv.m4
|
||||||
|
/sig_atomic_t.m4
|
||||||
|
/sigaction.m4
|
||||||
|
/signal_h.m4
|
||||||
|
/signalblocking.m4
|
||||||
/signbit.m4
|
/signbit.m4
|
||||||
/snprintf-posix.m4
|
/snprintf-posix.m4
|
||||||
/snprintf.m4
|
/snprintf.m4
|
||||||
|
/spawn_h.m4
|
||||||
/sprintf-posix.m4
|
/sprintf-posix.m4
|
||||||
|
/stat.m4
|
||||||
/stdbool.m4
|
/stdbool.m4
|
||||||
/stddef_h.m4
|
/stddef_h.m4
|
||||||
/stdint.m4
|
/stdint.m4
|
||||||
@@ -89,6 +105,7 @@
|
|||||||
/stdio_h.m4
|
/stdio_h.m4
|
||||||
/stdlib_h.m4
|
/stdlib_h.m4
|
||||||
/stpcpy.m4
|
/stpcpy.m4
|
||||||
|
/strchrnul.m4
|
||||||
/strerror.m4
|
/strerror.m4
|
||||||
/string_h.m4
|
/string_h.m4
|
||||||
/strndup.m4
|
/strndup.m4
|
||||||
@@ -96,7 +113,10 @@
|
|||||||
/strtol.m4
|
/strtol.m4
|
||||||
/strtoul.m4
|
/strtoul.m4
|
||||||
/strverscmp.m4
|
/strverscmp.m4
|
||||||
|
/sys_stat_h.m4
|
||||||
|
/sys_wait_h.m4
|
||||||
/threadlib.m4
|
/threadlib.m4
|
||||||
|
/time_h.m4
|
||||||
/unistd-safer.m4
|
/unistd-safer.m4
|
||||||
/unistd_h.m4
|
/unistd_h.m4
|
||||||
/unlocked-io.m4
|
/unlocked-io.m4
|
||||||
@@ -105,6 +125,7 @@
|
|||||||
/vsnprintf-posix.m4
|
/vsnprintf-posix.m4
|
||||||
/vsnprintf.m4
|
/vsnprintf.m4
|
||||||
/vsprintf-posix.m4
|
/vsprintf-posix.m4
|
||||||
|
/wait-process.m4
|
||||||
/warn-on-use.m4
|
/warn-on-use.m4
|
||||||
/warning.m4
|
/warning.m4
|
||||||
/warnings.m4
|
/warnings.m4
|
||||||
|
|||||||
@@ -22,6 +22,5 @@ lib/error.c
|
|||||||
lib/getopt.c
|
lib/getopt.c
|
||||||
lib/obstack.c
|
lib/obstack.c
|
||||||
lib/quotearg.c
|
lib/quotearg.c
|
||||||
lib/subpipe.c
|
|
||||||
lib/timevar.c
|
lib/timevar.c
|
||||||
lib/xalloc-die.c
|
lib/xalloc-die.c
|
||||||
|
|||||||
39
src/files.c
39
src/files.c
@@ -319,21 +319,21 @@ compute_output_file_names (void)
|
|||||||
{
|
{
|
||||||
if (! spec_graph_file)
|
if (! spec_graph_file)
|
||||||
spec_graph_file = concat2 (all_but_tab_ext, ".dot");
|
spec_graph_file = concat2 (all_but_tab_ext, ".dot");
|
||||||
output_file_name_check (spec_graph_file);
|
output_file_name_check (&spec_graph_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xml_flag)
|
if (xml_flag)
|
||||||
{
|
{
|
||||||
if (! spec_xml_file)
|
if (! spec_xml_file)
|
||||||
spec_xml_file = concat2 (all_but_tab_ext, ".xml");
|
spec_xml_file = concat2 (all_but_tab_ext, ".xml");
|
||||||
output_file_name_check (spec_xml_file);
|
output_file_name_check (&spec_xml_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (report_flag)
|
if (report_flag)
|
||||||
{
|
{
|
||||||
if (!spec_verbose_file)
|
if (!spec_verbose_file)
|
||||||
spec_verbose_file = concat2 (all_but_tab_ext, OUTPUT_EXT);
|
spec_verbose_file = concat2 (all_but_tab_ext, OUTPUT_EXT);
|
||||||
output_file_name_check (spec_verbose_file);
|
output_file_name_check (&spec_verbose_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
free (all_but_tab_ext);
|
free (all_but_tab_ext);
|
||||||
@@ -342,18 +342,37 @@ compute_output_file_names (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
output_file_name_check (char const *file_name)
|
output_file_name_check (char **file_name)
|
||||||
{
|
{
|
||||||
if (0 == strcmp (file_name, grammar_file))
|
bool conflict = false;
|
||||||
fatal (_("refusing to overwrite the input file %s"), quote (file_name));
|
if (0 == strcmp (*file_name, grammar_file))
|
||||||
|
{
|
||||||
|
complain (_("refusing to overwrite the input file %s"),
|
||||||
|
quote (*file_name));
|
||||||
|
conflict = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < file_names_count; i++)
|
for (i = 0; i < file_names_count; i++)
|
||||||
if (0 == strcmp (file_names[i], file_name))
|
if (0 == strcmp (file_names[i], *file_name))
|
||||||
warn (_("conflicting outputs to file %s"), quote (file_name));
|
{
|
||||||
|
warn (_("conflicting outputs to file %s"),
|
||||||
|
quote (*file_name));
|
||||||
|
conflict = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (conflict)
|
||||||
|
{
|
||||||
|
free (*file_name);
|
||||||
|
*file_name = strdup ("/dev/null");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
file_names = xnrealloc (file_names, ++file_names_count,
|
||||||
|
sizeof *file_names);
|
||||||
|
file_names[file_names_count-1] = xstrdup (*file_name);
|
||||||
}
|
}
|
||||||
file_names = xnrealloc (file_names, ++file_names_count, sizeof *file_names);
|
|
||||||
file_names[file_names_count-1] = xstrdup (file_name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ extern char *all_but_ext;
|
|||||||
|
|
||||||
void compute_output_file_names (void);
|
void compute_output_file_names (void);
|
||||||
void output_file_names_free (void);
|
void output_file_names_free (void);
|
||||||
void output_file_name_check (char const *file_name);
|
void output_file_name_check (char **file_name);
|
||||||
|
|
||||||
FILE *xfopen (const char *name, const char *mode);
|
FILE *xfopen (const char *name, const char *mode);
|
||||||
void xfclose (FILE *ptr);
|
void xfclose (FILE *ptr);
|
||||||
|
|||||||
20
src/output.c
20
src/output.c
@@ -24,9 +24,10 @@
|
|||||||
#include <configmake.h>
|
#include <configmake.h>
|
||||||
#include <error.h>
|
#include <error.h>
|
||||||
#include <get-errno.h>
|
#include <get-errno.h>
|
||||||
|
#include <pipe.h>
|
||||||
#include <quotearg.h>
|
#include <quotearg.h>
|
||||||
#include <subpipe.h>
|
|
||||||
#include <timevar.h>
|
#include <timevar.h>
|
||||||
|
#include <wait-process.h>
|
||||||
|
|
||||||
#include "complain.h"
|
#include "complain.h"
|
||||||
#include "files.h"
|
#include "files.h"
|
||||||
@@ -568,17 +569,17 @@ output_skeleton (void)
|
|||||||
aver (i <= ARRAY_CARDINALITY (argv));
|
aver (i <= ARRAY_CARDINALITY (argv));
|
||||||
}
|
}
|
||||||
|
|
||||||
init_subpipe ();
|
/* The ugly cast is because gnulib gets the const-ness wrong. */
|
||||||
pid = create_subpipe (argv, filter_fd);
|
pid = create_pipe_bidi ("m4", m4, (char **)(void*)argv, false, true,
|
||||||
|
true, filter_fd);
|
||||||
free (full_m4sugar);
|
free (full_m4sugar);
|
||||||
free (full_m4bison);
|
free (full_m4bison);
|
||||||
free (full_skeleton);
|
free (full_skeleton);
|
||||||
|
|
||||||
|
|
||||||
if (trace_flag & trace_muscles)
|
if (trace_flag & trace_muscles)
|
||||||
muscles_output (stderr);
|
muscles_output (stderr);
|
||||||
{
|
{
|
||||||
FILE *out = fdopen (filter_fd[0], "w");
|
FILE *out = fdopen (filter_fd[1], "w");
|
||||||
if (! out)
|
if (! out)
|
||||||
error (EXIT_FAILURE, get_errno (),
|
error (EXIT_FAILURE, get_errno (),
|
||||||
"fdopen");
|
"fdopen");
|
||||||
@@ -588,14 +589,17 @@ output_skeleton (void)
|
|||||||
|
|
||||||
/* Read and process m4's output. */
|
/* Read and process m4's output. */
|
||||||
timevar_push (TV_M4);
|
timevar_push (TV_M4);
|
||||||
end_of_output_subpipe (pid, filter_fd);
|
in = fdopen (filter_fd[0], "r");
|
||||||
in = fdopen (filter_fd[1], "r");
|
|
||||||
if (! in)
|
if (! in)
|
||||||
error (EXIT_FAILURE, get_errno (),
|
error (EXIT_FAILURE, get_errno (),
|
||||||
"fdopen");
|
"fdopen");
|
||||||
scan_skel (in);
|
scan_skel (in);
|
||||||
|
/* scan_skel should have read all of M4's output. Otherwise, when we
|
||||||
|
close the pipe, we risk letting M4 report a broken-pipe to the
|
||||||
|
Bison user. */
|
||||||
|
aver (feof (in));
|
||||||
xfclose (in);
|
xfclose (in);
|
||||||
reap_subpipe (pid, m4);
|
wait_subprocess (pid, "m4", false, false, true, true, NULL);
|
||||||
timevar_pop (TV_M4);
|
timevar_pop (TV_M4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ static void fail_for_invalid_at (char const *at);
|
|||||||
"@@" { obstack_1grow (&obstack_for_string, '@'); }
|
"@@" { obstack_1grow (&obstack_for_string, '@'); }
|
||||||
"@{" { obstack_1grow (&obstack_for_string, '['); }
|
"@{" { obstack_1grow (&obstack_for_string, '['); }
|
||||||
"@}" { obstack_1grow (&obstack_for_string, ']'); }
|
"@}" { obstack_1grow (&obstack_for_string, ']'); }
|
||||||
"@`" /* Emtpy. Useful for starting an argument
|
"@`" /* Empty. Useful for starting an argument
|
||||||
that begins with whitespace. */
|
that begins with whitespace. */
|
||||||
@\n /* Empty. */
|
@\n /* Empty. */
|
||||||
|
|
||||||
@@ -174,8 +174,8 @@ skel_scanner_free (void)
|
|||||||
yylex_destroy ();
|
yylex_destroy ();
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static void
|
||||||
void at_directive_perform (int at_directive_argc,
|
at_directive_perform (int at_directive_argc,
|
||||||
char *at_directive_argv[],
|
char *at_directive_argv[],
|
||||||
char **outnamep, int *out_linenop)
|
char **outnamep, int *out_linenop)
|
||||||
{
|
{
|
||||||
@@ -276,7 +276,7 @@ void at_directive_perform (int at_directive_argc,
|
|||||||
xfclose (yyout);
|
xfclose (yyout);
|
||||||
}
|
}
|
||||||
*outnamep = xstrdup (at_directive_argv[1]);
|
*outnamep = xstrdup (at_directive_argv[1]);
|
||||||
output_file_name_check (*outnamep);
|
output_file_name_check (outnamep);
|
||||||
yyout = xfopen (*outnamep, "w");
|
yyout = xfopen (*outnamep, "w");
|
||||||
*out_linenop = 1;
|
*out_linenop = 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -137,7 +137,9 @@ AT_DATA([$1],
|
|||||||
foo: {};
|
foo: {};
|
||||||
]])
|
]])
|
||||||
|
|
||||||
|
[cp ]$1[ expout]
|
||||||
AT_BISON_CHECK([$3 $1], $5, [], [$4])
|
AT_BISON_CHECK([$3 $1], $5, [], [$4])
|
||||||
|
AT_CHECK([[cat $1]], [[0]], [expout])
|
||||||
AT_CLEANUP
|
AT_CLEANUP
|
||||||
])
|
])
|
||||||
|
|
||||||
@@ -157,7 +159,7 @@ AT_CHECK_CONFLICTING_OUTPUT([foo.y],
|
|||||||
])
|
])
|
||||||
|
|
||||||
AT_CHECK_CONFLICTING_OUTPUT([foo.y], [], [-o foo.y],
|
AT_CHECK_CONFLICTING_OUTPUT([foo.y], [], [-o foo.y],
|
||||||
[foo.y: fatal error: refusing to overwrite the input file `foo.y'
|
[foo.y: refusing to overwrite the input file `foo.y'
|
||||||
], 1)
|
], 1)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -288,3 +288,45 @@ foo.y:1.5-6: fatal error: M4 should exit immediately here
|
|||||||
]])
|
]])
|
||||||
|
|
||||||
AT_CLEANUP
|
AT_CLEANUP
|
||||||
|
|
||||||
|
|
||||||
|
## ------------------------------------------------ ##
|
||||||
|
## Fatal errors but M4 continues producing output. ##
|
||||||
|
## ------------------------------------------------ ##
|
||||||
|
|
||||||
|
# At one time, if Bison encountered a fatal error during M4 processing,
|
||||||
|
# Bison failed to drain M4's output pipe. The result was a SIGPIPE.
|
||||||
|
# On some platforms, the default disposition for SIGPIPE is terminate,
|
||||||
|
# which was fine. On others, it's ignore, which caused M4 to report
|
||||||
|
# the broken pipe to the user, but we don't want to bother the user with
|
||||||
|
# that.
|
||||||
|
|
||||||
|
# There is a race condition somewhere. That is, before the associated
|
||||||
|
# fix, running this test group many times in a row would occasionally
|
||||||
|
# produce a pass among all the failures.
|
||||||
|
|
||||||
|
AT_SETUP([[Fatal errors but M4 continues producing output]])
|
||||||
|
|
||||||
|
AT_DATA([[gen-skel.pl]],
|
||||||
|
[[use warnings;
|
||||||
|
use strict;
|
||||||
|
my $M4 = "m4";
|
||||||
|
my $DNL = "d"."nl";
|
||||||
|
print "${M4}_divert_push(0)$DNL\n";
|
||||||
|
print '@output(@,@)', "\n";
|
||||||
|
(print "garbage"x10, "\n") for (1..1000);
|
||||||
|
print "${M4}_divert_pop(0)\n";
|
||||||
|
]])
|
||||||
|
AT_CHECK([[perl gen-skel.pl > skel.c || exit 77]])
|
||||||
|
|
||||||
|
AT_DATA([[input.y]],
|
||||||
|
[[%skeleton "./skel.c"
|
||||||
|
%%
|
||||||
|
start: ;
|
||||||
|
]])
|
||||||
|
|
||||||
|
AT_BISON_CHECK([[input.y]], [[1]], [[]],
|
||||||
|
[[input.y: fatal error: too many arguments for @output directive in skeleton
|
||||||
|
]])
|
||||||
|
|
||||||
|
AT_CLEANUP
|
||||||
|
|||||||
Reference in New Issue
Block a user