* 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:
15
ChangeLog
15
ChangeLog
@@ -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.
|
||||
|
||||
@@ -5,9 +5,11 @@ alloca
|
||||
argmatch
|
||||
argp
|
||||
backupfile
|
||||
closeout
|
||||
dirname
|
||||
error
|
||||
exclude
|
||||
exitfail
|
||||
fileblocks
|
||||
fnmatch-gnu
|
||||
ftruncate
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
.deps
|
||||
__fpending.c
|
||||
__fpending.h
|
||||
closeout.c
|
||||
closeout.h
|
||||
Makefile
|
||||
Makefile.am
|
||||
Makefile.in
|
||||
|
||||
79
src/buffer.c
79
src/buffer.c
@@ -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 (¤t_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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
22
src/tar.c
22
src/tar.c
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user