mirror of
git://git.sv.gnu.org/coreutils.git
synced 2026-04-12 15:06:44 +02:00
mktemp: use more robust means to avoid double-close of stdout
Reverts earlier patch - fflush() can succeed but fclose() fail for some cases of write failures, and we want to catch those. * src/mktemp.c (stdout_closed): New variable. (maybe_close_stdout): New function, borrowed from dd.c. (main): Track whether stdout has been closed.
This commit is contained in:
20
src/mktemp.c
20
src/mktemp.c
@@ -128,6 +128,22 @@ mkdtemp_len (char *tmpl, size_t suff_len, size_t x_len, bool dry_run)
|
||||
x_len);
|
||||
}
|
||||
|
||||
/* True if we have already closed standard output. */
|
||||
static bool stdout_closed;
|
||||
|
||||
/* Avoid closing stdout twice. Since we conditionally call
|
||||
close_stream (stdout) in order to decide whether to clean up a
|
||||
temporary file, the exit hook needs to know whether to do all of
|
||||
close_stdout or just the stderr half. */
|
||||
static void
|
||||
maybe_close_stdout (void)
|
||||
{
|
||||
if (!stdout_closed)
|
||||
close_stdout ();
|
||||
else if (close_stream (stderr) != 0)
|
||||
_exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
@@ -153,7 +169,7 @@ main (int argc, char **argv)
|
||||
bindtextdomain (PACKAGE, LOCALEDIR);
|
||||
textdomain (PACKAGE);
|
||||
|
||||
atexit (close_stdout);
|
||||
atexit (maybe_close_stdout);
|
||||
|
||||
while ((c = getopt_long (argc, argv, "dp:qtuV", longopts, NULL)) != -1)
|
||||
{
|
||||
@@ -325,7 +341,7 @@ main (int argc, char **argv)
|
||||
puts (dest_name);
|
||||
/* If we created a file, but then failed to output the file
|
||||
name, we should clean up the mess before failing. */
|
||||
if (!dry_run && (ferror (stdout) || fflush (stdout) != 0))
|
||||
if (!dry_run && (stdout_closed = true) && close_stream (stdout) != 0)
|
||||
{
|
||||
int saved_errno = errno;
|
||||
remove (dest_name);
|
||||
|
||||
Reference in New Issue
Block a user