mirror of
https://github.com/mirror/make.git
synced 2025-02-05 09:10:12 +08:00
Fix Savannah bug # 1328: if stdout is redirected to a full filesystem, we
check for this and exit with an error. The closeout.c version from gnulib pulls in too much other stuff, and gnulib requires an ANSI C 89 compliant compiler, while GNU make (so far) still wants to work on K&R.
This commit is contained in:
parent
974d14ac4f
commit
467115baae
15
ChangeLog
15
ChangeLog
@ -1,7 +1,18 @@
|
|||||||
|
2005-06-12 Paul D. Smith <psmith@gnu.org>
|
||||||
|
|
||||||
|
Fix Savannah bug # 1328.
|
||||||
|
|
||||||
|
* configure.in: Check for atexit().
|
||||||
|
* misc.c (close_stdout): Test stdout to see if writes to it have
|
||||||
|
failed. If so, be sure to exit with a non-0 error code. Based on
|
||||||
|
code found in gnulib.
|
||||||
|
* make.h: Prototype.
|
||||||
|
* main.c (main): Install close_stdout() with atexit().
|
||||||
|
|
||||||
2005-06-10 Paul D. Smith <psmith@gnu.org>
|
2005-06-10 Paul D. Smith <psmith@gnu.org>
|
||||||
|
|
||||||
VMS build updates from Hartmut Becker <Hartmut.Becker@hp.com>:
|
VMS build updates from Hartmut Becker <Hartmut.Becker@hp.com>:
|
||||||
|
|
||||||
* vmsjobs.c [VMS]: Updates to compile on VMS: add some missing
|
* vmsjobs.c [VMS]: Updates to compile on VMS: add some missing
|
||||||
headers; make vmsWaitForChildren() static; extern vmsify().
|
headers; make vmsWaitForChildren() static; extern vmsify().
|
||||||
* job.c [VMS]: Move vmsWaitForChildren() prototype to be global.
|
* job.c [VMS]: Move vmsWaitForChildren() prototype to be global.
|
||||||
|
@ -137,7 +137,7 @@ AC_CHECK_FUNCS( memcpy memmove strchr strdup mkstemp mktemp fdopen \
|
|||||||
bsd_signal dup2 getcwd realpath sigsetmask sigaction \
|
bsd_signal dup2 getcwd realpath sigsetmask sigaction \
|
||||||
getgroups seteuid setegid setlinebuf setreuid setregid \
|
getgroups seteuid setegid setlinebuf setreuid setregid \
|
||||||
getrlimit setrlimit setvbuf pipe strerror strsignal \
|
getrlimit setrlimit setvbuf pipe strerror strsignal \
|
||||||
lstat readlink)
|
lstat readlink atexit)
|
||||||
|
|
||||||
AC_FUNC_SETVBUF_REVERSED
|
AC_FUNC_SETVBUF_REVERSED
|
||||||
|
|
||||||
|
@ -9385,7 +9385,7 @@ foolib(hack.o) : hack.o
|
|||||||
@end example
|
@end example
|
||||||
|
|
||||||
In fact, nearly all archive member targets are updated in just this way
|
In fact, nearly all archive member targets are updated in just this way
|
||||||
and there is an implicit rule to do it for you. @strong{Note:} The
|
and there is an implicit rule to do it for you. @strong{Please note:} The
|
||||||
@samp{c} flag to @code{ar} is required if the archive file does not
|
@samp{c} flag to @code{ar} is required if the archive file does not
|
||||||
already exist.
|
already exist.
|
||||||
|
|
||||||
|
5
main.c
5
main.c
@ -914,6 +914,10 @@ main (int argc, char **argv, char **envp)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_ATEXIT
|
||||||
|
atexit (close_stdout);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Needed for OS/2 */
|
/* Needed for OS/2 */
|
||||||
initialize_main(&argc, &argv);
|
initialize_main(&argc, &argv);
|
||||||
|
|
||||||
@ -2176,6 +2180,7 @@ main (int argc, char **argv, char **envp)
|
|||||||
die (status);
|
die (status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* NOTREACHED */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
5
make.h
5
make.h
@ -459,8 +459,9 @@ extern void user_access PARAMS ((void));
|
|||||||
extern void make_access PARAMS ((void));
|
extern void make_access PARAMS ((void));
|
||||||
extern void child_access PARAMS ((void));
|
extern void child_access PARAMS ((void));
|
||||||
|
|
||||||
extern char *
|
extern void close_stdout PARAMS ((void));
|
||||||
strip_whitespace PARAMS ((const char **begpp, const char **endpp));
|
|
||||||
|
extern char *strip_whitespace PARAMS ((const char **begpp, const char **endpp));
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_VFORK_H
|
#ifdef HAVE_VFORK_H
|
||||||
|
47
misc.c
47
misc.c
@ -823,3 +823,50 @@ get_path_max (void)
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* This code is stolen from gnulib.
|
||||||
|
If/when we abandon the requirement to work with K&R compilers, we can
|
||||||
|
remove this (and perhaps other parts of GNU make!) and migrate to using
|
||||||
|
gnulib directly.
|
||||||
|
|
||||||
|
This is called only through atexit(), which means die() has already been
|
||||||
|
invoked. So, call exit() here directly. Apparently that works...?
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Close standard output, exiting with status 'exit_failure' on failure.
|
||||||
|
If a program writes *anything* to stdout, that program should close
|
||||||
|
stdout and make sure that it succeeds before exiting. Otherwise,
|
||||||
|
suppose that you go to the extreme of checking the return status
|
||||||
|
of every function that does an explicit write to stdout. The last
|
||||||
|
printf can succeed in writing to the internal stream buffer, and yet
|
||||||
|
the fclose(stdout) could still fail (due e.g., to a disk full error)
|
||||||
|
when it tries to write out that buffered data. Thus, you would be
|
||||||
|
left with an incomplete output file and the offending program would
|
||||||
|
exit successfully. Even calling fflush is not always sufficient,
|
||||||
|
since some file systems (NFS and CODA) buffer written/flushed data
|
||||||
|
until an actual close call.
|
||||||
|
|
||||||
|
Besides, it's wasteful to check the return value from every call
|
||||||
|
that writes to stdout -- just let the internal stream state record
|
||||||
|
the failure. That's what the ferror test is checking below.
|
||||||
|
|
||||||
|
It's important to detect such failures and exit nonzero because many
|
||||||
|
tools (most notably `make' and other build-management systems) depend
|
||||||
|
on being able to detect failure in other tools via their exit status. */
|
||||||
|
|
||||||
|
void
|
||||||
|
close_stdout (void)
|
||||||
|
{
|
||||||
|
int prev_fail = ferror (stdout);
|
||||||
|
int fclose_fail = fclose (stdout);
|
||||||
|
|
||||||
|
if (prev_fail || fclose_fail)
|
||||||
|
{
|
||||||
|
if (fclose_fail)
|
||||||
|
error (NILF, _("write error: %s"), strerror (errno));
|
||||||
|
else
|
||||||
|
error (NILF, _("write error"));
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
2005-06-12 Paul D. Smith <psmith@gnu.org>
|
||||||
|
|
||||||
|
* scripts/misc/close_stdout: Add a test for Savannah bug #1328.
|
||||||
|
This test only works on systems that have /dev/full (e.g., Linux).
|
||||||
|
|
||||||
2005-06-09 Paul D. Smith <psmith@gnu.org>
|
2005-06-09 Paul D. Smith <psmith@gnu.org>
|
||||||
|
|
||||||
* scripts/functions/foreach: Add a test for Savannah bug #11913.
|
* scripts/functions/foreach: Add a test for Savannah bug #11913.
|
||||||
|
9
tests/scripts/misc/close_stdout
Normal file
9
tests/scripts/misc/close_stdout
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# -*-perl-*-
|
||||||
|
|
||||||
|
$description = "Make sure make exits with an error if stdout is full.";
|
||||||
|
|
||||||
|
if (-e '/dev/full') {
|
||||||
|
run_make_test('', '-v > /dev/full', '#MAKE#: write error', 256);
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
Loading…
Reference in New Issue
Block a user