* gnulib.modules: Add closeout, exitfial.

* lib/.cvsignore: Add __fpending.c, __fpending.h, closeout.c,
closeout.h.
* src/buffer.c: Incluse closeout.h.
(_open_archive): Use freopen rather than fopen, so
that stdlis is always either stdout or stderr.  Use
close_stdout_set_file_name to report its name.
* src/tar.c: Include closeout.h and exitfail.h.
(parse_opt, usage): Call close_stdout as appropriate, to check for
write errors.
(decode_options): Exit with status TAREXIT_FAILURE, not 1.
(main): Set exit_failure, to exit with proper status on memory
allocation failure and the like.
Use close_stdout rather than rolling our own test.
This commit is contained in:
Paul Eggert
2006-02-07 23:51:37 +00:00
parent 78b078b455
commit 84378fa99a
5 changed files with 76 additions and 46 deletions

View File

@@ -1,5 +1,20 @@
2006-02-07 Paul Eggert <eggert@cs.ucla.edu>
* gnulib.modules: Add closeout, exitfial.
* lib/.cvsignore: Add __fpending.c, __fpending.h, closeout.c,
closeout.h.
* src/buffer.c: Incluse closeout.h.
(_open_archive): Use freopen rather than fopen, so
that stdlis is always either stdout or stderr. Use
close_stdout_set_file_name to report its name.
* src/tar.c: Include closeout.h and exitfail.h.
(parse_opt, usage): Call close_stdout as appropriate, to check for
write errors.
(decode_options): Exit with status TAREXIT_FAILURE, not 1.
(main): Set exit_failure, to exit with proper status on memory
allocation failure and the like.
Use close_stdout rather than rolling our own test.
* NEWS: --version now outputs copyright etc., to conform to the
GNU coding standards. Remove --license.
* gnulib.modules: Add version-etc-fsf.

View File

@@ -5,9 +5,11 @@ alloca
argmatch
argp
backupfile
closeout
dirname
error
exclude
exitfail
fileblocks
fnmatch-gnu
ftruncate

View File

@@ -1,4 +1,8 @@
.deps
__fpending.c
__fpending.h
closeout.c
closeout.h
Makefile
Makefile.am
Makefile.in

View File

@@ -1,7 +1,7 @@
/* Buffer management for tar.
Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001,
2003, 2004, 2005 Free Software Foundation, Inc.
2003, 2004, 2005, 2006 Free Software Foundation, Inc.
Written by John Gilmore, on 1985-08-25.
@@ -23,6 +23,7 @@
#include <signal.h>
#include <closeout.h>
#include <fnmatch.h>
#include <human.h>
#include <quotearg.h>
@@ -368,7 +369,7 @@ init_buffer ()
{
if (!record_buffer[record_index])
page_aligned_alloc (&record_buffer[record_index], record_size);
record_start = record_buffer[record_index];
current_block = record_start;
record_end = record_start + blocking_factor;
@@ -383,9 +384,10 @@ _open_archive (enum access_mode wanted_access)
if (index_file_name)
{
stdlis = fopen (index_file_name, "w");
stdlis = freopen (index_file_name, "w", stdout);
if (! stdlis)
open_error (index_file_name);
close_stdout_set_file_name (index_file_name);
}
else
stdlis = to_stdout_option ? stderr : stdout;
@@ -402,7 +404,7 @@ _open_archive (enum access_mode wanted_access)
record_index = 0;
init_buffer ();
/* When updating the archive, we start with reading. */
access_mode = wanted_access == ACCESS_UPDATE ? ACCESS_READ : wanted_access;
@@ -876,19 +878,19 @@ change_tape_menu (FILE *read_file)
_("Prepare volume #%d for %s and hit return: "),
global_volno + 1, quote (*archive_name_cursor));
fflush (stderr);
if (getline (&input_buffer, &size, read_file) <= 0)
{
WARN ((0, 0, _("EOF where user reply was expected")));
if (subcommand_option != EXTRACT_SUBCOMMAND
&& subcommand_option != LIST_SUBCOMMAND
&& subcommand_option != DIFF_SUBCOMMAND)
WARN ((0, 0, _("WARNING: Archive is incomplete")));
fatal_exit ();
}
if (input_buffer[0] == '\n'
|| input_buffer[0] == 'y'
|| input_buffer[0] == 'Y')
@@ -910,37 +912,37 @@ change_tape_menu (FILE *read_file)
case 'q':
/* Quit. */
WARN ((0, 0, _("No new volume; exiting.\n")));
if (subcommand_option != EXTRACT_SUBCOMMAND
&& subcommand_option != LIST_SUBCOMMAND
&& subcommand_option != DIFF_SUBCOMMAND)
WARN ((0, 0, _("WARNING: Archive is incomplete")));
fatal_exit ();
case 'n':
/* Get new file name. */
{
char *name;
char *cursor;
for (name = input_buffer + 1;
*name == ' ' || *name == '\t';
name++)
;
for (cursor = name; *cursor && *cursor != '\n'; cursor++)
;
*cursor = '\0';
/* FIXME: the following allocation is never reclaimed. */
*archive_name_cursor = xstrdup (name);
}
break;
case '!':
if (!restrict_option)
{
@@ -977,7 +979,7 @@ new_volume (enum access_mode mode)
assign_string (&volume_label, NULL);
assign_string (&continued_file_name, NULL);
continued_file_size = continued_file_offset = 0;
if (rmtclose (archive) != 0)
close_warn (*archive_name_cursor);
@@ -1111,7 +1113,7 @@ try_new_volume ()
}
break;
}
case GNUTYPE_VOLHDR:
if (!read_header0 ())
return false;
@@ -1121,7 +1123,7 @@ try_new_volume ()
if (header->header.typeflag != GNUTYPE_MULTIVOL)
break;
/* FALL THROUGH */
case GNUTYPE_MULTIVOL:
if (!read_header0 ())
return false;
@@ -1131,7 +1133,7 @@ try_new_volume ()
continued_file_offset =
UINTMAX_FROM_HEADER (current_header->oldgnu_header.offset);
break;
default:
break;
}
@@ -1139,7 +1141,7 @@ try_new_volume ()
if (real_s_name)
{
uintmax_t s;
if (!continued_file_name
if (!continued_file_name
|| strcmp (continued_file_name, real_s_name))
{
WARN ((0, 0, _("%s is not continued on this volume"),
@@ -1162,7 +1164,7 @@ try_new_volume ()
STRINGIFY_BIGINT (continued_file_offset, s2buf)));
return false;
}
if (real_s_totsize - real_s_sizeleft != continued_file_offset)
{
WARN ((0, 0, _("This volume is out of sequence")));
@@ -1228,7 +1230,7 @@ _write_volume_label (const char *str)
else
{
union block *label = find_next_block ();
memset (label, 0, BLOCKSIZE);
strcpy (label->header.name, volume_label_option);
@@ -1280,7 +1282,7 @@ add_chunk_header ()
real_s_part_no);
st.file_name = st.orig_file_name;
st.archive_file_size = st.stat.st_size = real_s_sizeleft;
block_ordinal = current_block_ordinal ();
blk = start_header (&st);
free (st.orig_file_name);
@@ -1307,25 +1309,25 @@ gnu_add_multi_volume_header (void)
{
int tmp;
union block *block = find_next_block ();
if (strlen (real_s_name) > NAME_FIELD_SIZE)
WARN ((0, 0,
_("%s: file name too long to be stored in a GNU multivolume header, truncated"),
quotearg_colon (real_s_name)));
memset (block, 0, BLOCKSIZE);
/* FIXME: Michael P Urban writes: [a long name file] is being written
when a new volume rolls around [...] Looks like the wrong value is
being preserved in real_s_name, though. */
strncpy (block->header.name, real_s_name, NAME_FIELD_SIZE);
block->header.typeflag = GNUTYPE_MULTIVOL;
OFF_TO_CHARS (real_s_sizeleft, block->header.size);
OFF_TO_CHARS (real_s_totsize - real_s_sizeleft,
block->oldgnu_header.offset);
tmp = verbose_option;
verbose_option = 0;
finish_header (&current_stat_info, block, -1);
@@ -1401,7 +1403,7 @@ simple_flush_read (void)
if (status != record_size)
archive_write_error (status);
}
for (;;)
{
status = rmtread (archive, record_start->buffer, record_size);
@@ -1493,7 +1495,7 @@ _gnu_flush_read (void)
else if (status == SAFE_READ_ERROR)
{
archive_read_error ();
continue;
continue;
}
break;
}
@@ -1505,7 +1507,7 @@ gnu_flush_read (void)
{
flush_read_ptr = simple_flush_read; /* Avoid recursion */
_gnu_flush_read ();
flush_read_ptr = gnu_flush_read;
flush_read_ptr = gnu_flush_read;
}
static void
@@ -1516,7 +1518,7 @@ _gnu_flush_write (size_t buffer_level)
char *copy_ptr;
size_t copy_size;
size_t bufsize;
status = _flush_write ();
if (status != record_size && !multi_volume_option)
archive_write_error (status);
@@ -1552,7 +1554,7 @@ _gnu_flush_write (size_t buffer_level)
/* Switch to the next buffer */
record_index = !record_index;
init_buffer ();
if (volume_label_option)
add_volume_label ();
@@ -1584,7 +1586,7 @@ gnu_flush_write (size_t buffer_level)
{
flush_write_ptr = simple_flush_write; /* Avoid recursion */
_gnu_flush_write (buffer_level);
flush_write_ptr = gnu_flush_write;
flush_write_ptr = gnu_flush_write;
}
void
@@ -1597,7 +1599,7 @@ void
flush_write ()
{
flush_write_ptr (record_size);
}
}
void
open_archive (enum access_mode wanted_access)
@@ -1623,4 +1625,3 @@ open_archive (enum access_mode wanted_access)
break;
}
}

View File

@@ -37,6 +37,8 @@
#include "common.h"
#include <argmatch.h>
#include <closeout.h>
#include <exitfail.h>
#include <getdate.h>
#include <localedir.h>
#include <rmt.h>
@@ -1441,7 +1443,8 @@ parse_opt (int key, char *arg, struct argp_state *state)
case SHOW_DEFAULTS_OPTION:
show_default_settings (stdout);
exit(0);
close_stdout ();
exit (0);
case STRIP_COMPONENTS_OPTION:
{
@@ -1605,16 +1608,18 @@ parse_opt (int key, char *arg, struct argp_state *state)
fprintf (state->out_stream, "\n");
fprintf (state->out_stream, _("Report bugs to %s.\n"),
argp_program_bug_address);
close_stdout ();
exit (0);
case USAGE_OPTION:
argp_state_help (state, state->out_stream,
ARGP_HELP_USAGE | ARGP_HELP_EXIT_OK);
break;
argp_state_help (state, state->out_stream, ARGP_HELP_USAGE);
close_stdout ();
exit (0);
case VERSION_OPTION:
version_etc (state->out_stream, "tar", PACKAGE_NAME, VERSION,
"John Gilmore", "Jay Fenlason", (char *) NULL);
close_stdout ();
exit (0);
case HANG_OPTION:
@@ -1643,6 +1648,7 @@ void
usage (int status)
{
argp_help (&argp, stderr, ARGP_HELP_SEE, (char*) program_name);
close_stdout ();
exit (status);
}
@@ -1753,7 +1759,7 @@ decode_options (int argc, char **argv)
if (argp_parse (&argp, argc, argv, ARGP_IN_ORDER|ARGP_NO_HELP,
&index, &args))
exit (1);
exit (TAREXIT_FAILURE);
/* Special handling for 'o' option:
@@ -2003,6 +2009,7 @@ main (int argc, char **argv)
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
exit_failure = TAREXIT_FAILURE;
exit_status = TAREXIT_SUCCESS;
filename_terminator = '\n';
set_quoting_style (0, DEFAULT_QUOTING_STYLE);
@@ -2089,8 +2096,9 @@ main (int argc, char **argv)
free (archive_name_array);
name_term ();
if (stdlis != stderr && (ferror (stdlis) || fclose (stdlis) != 0))
FATAL_ERROR ((0, 0, _("Error in writing to standard output")));
if (stdlis == stdout)
close_stdout ();
if (exit_status == TAREXIT_FAILURE)
error (0, 0, _("Error exit delayed from previous errors"));
if (ferror (stderr) || fclose (stderr) != 0)