Fix multivolume archive creation when volume length=record size.
* src/tar.c (decode_options): Do not allow volume length less than record size. * src/buffer.c (_gnu_flush_write): Compensate for the effect of eventual flush_archive occurring in the middle of buffer move. Increment records_written only if _flush_write was able to write something. * tests/multiv06.at: New testcase. * tests/Makefile.am, test/testsuite.at: Add tests/multiv06.at
This commit is contained in:
13
ChangeLog
13
ChangeLog
@@ -1,3 +1,16 @@
|
||||
2008-07-24 Sergey Poznyakoff <gray@gnu.org.ua>
|
||||
|
||||
* src/tar.c (decode_options): Do not allow volume length less
|
||||
than record size.
|
||||
|
||||
* src/buffer.c (_gnu_flush_write): Compensate for the effect
|
||||
of eventual flush_archive occurring in the middle of buffer
|
||||
move.
|
||||
Increment records_written only if _flush_write was able to write
|
||||
something.
|
||||
* tests/multiv06.at: New testcase.
|
||||
* tests/Makefile.am, test/testsuite.at: Add tests/multiv06.at
|
||||
|
||||
2008-06-26 Sergey Poznyakoff <gray@gnu.org.ua>
|
||||
|
||||
* configure.ac, NEWS: Version 1.20.90
|
||||
|
||||
19
src/buffer.c
19
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, 2006, 2007 Free Software Foundation, Inc.
|
||||
2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
|
||||
|
||||
Written by John Gilmore, on 1985-08-25.
|
||||
|
||||
@@ -1599,13 +1599,15 @@ _gnu_flush_write (size_t buffer_level)
|
||||
char *copy_ptr;
|
||||
size_t copy_size;
|
||||
size_t bufsize;
|
||||
|
||||
tarlong wrt;
|
||||
|
||||
status = _flush_write ();
|
||||
if (status != record_size && !multi_volume_option)
|
||||
archive_write_error (status);
|
||||
else
|
||||
{
|
||||
records_written++;
|
||||
if (status)
|
||||
records_written++;
|
||||
bytes_written += status;
|
||||
}
|
||||
|
||||
@@ -1654,6 +1656,7 @@ _gnu_flush_write (size_t buffer_level)
|
||||
|
||||
if (real_s_name)
|
||||
add_chunk_header ();
|
||||
wrt = bytes_written;
|
||||
header = find_next_block ();
|
||||
bufsize = available_space_after (header);
|
||||
while (bufsize < copy_size)
|
||||
@@ -1668,6 +1671,16 @@ _gnu_flush_write (size_t buffer_level)
|
||||
memcpy (header->buffer, copy_ptr, copy_size);
|
||||
memset (header->buffer + copy_size, 0, bufsize - copy_size);
|
||||
set_next_block_after (header + (copy_size - 1) / BLOCKSIZE);
|
||||
if (multi_volume_option && wrt < bytes_written)
|
||||
{
|
||||
/* The value of bytes_written has changed while moving data;
|
||||
that means that flush_archive was executed at least once in
|
||||
between, and, as a consequence, copy_size bytes were not written
|
||||
to disk. We need to update sizeleft variables to compensate for
|
||||
that. */
|
||||
save_sizeleft += copy_size;
|
||||
multi_volume_sync ();
|
||||
}
|
||||
find_next_block ();
|
||||
}
|
||||
|
||||
|
||||
@@ -1041,7 +1041,7 @@ dump_regular_file (int fd, struct tar_stat_info *st)
|
||||
while (size_left > 0)
|
||||
{
|
||||
size_t bufsize, count;
|
||||
|
||||
|
||||
mv_size_left (size_left);
|
||||
|
||||
blk = find_next_block ();
|
||||
|
||||
@@ -2324,6 +2324,9 @@ decode_options (int argc, char **argv)
|
||||
else if (utc_option)
|
||||
verbose_option = 2;
|
||||
|
||||
if (tape_length_option && tape_length_option < record_size)
|
||||
USAGE_ERROR ((0, 0, _("Volume length cannot be less than record size")));
|
||||
|
||||
/* Forbid using -c with no input files whatsoever. Check that `-f -',
|
||||
explicit or implied, is used correctly. */
|
||||
|
||||
|
||||
@@ -89,6 +89,7 @@ TESTSUITE_AT = \
|
||||
multiv03.at\
|
||||
multiv04.at\
|
||||
multiv05.at\
|
||||
multiv06.at\
|
||||
old.at\
|
||||
options.at\
|
||||
options02.at\
|
||||
|
||||
57
tests/multiv06.at
Normal file
57
tests/multiv06.at
Normal file
@@ -0,0 +1,57 @@
|
||||
# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
|
||||
# Test suite for GNU tar.
|
||||
# Copyright (C) 2008 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, 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, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
# 02110-1301, USA.
|
||||
|
||||
# When volume size equals record size, swapping buffers in
|
||||
# new_volume triggers a call to flush_archive. The size left variables
|
||||
# must be corrected after that, which was not done in versions <= 1.20.
|
||||
# Reported by: Marek Kielar <mkielar@go2.pl>
|
||||
# References: <1907cbb6.79e32b49.48887f09.fd55@o2.pl>
|
||||
|
||||
AT_SETUP([Multivolumes with L=record_size])
|
||||
AT_KEYWORDS([multivolume multiv multiv06])
|
||||
|
||||
m4_define([echo2],[
|
||||
echo $*
|
||||
echo >&2 $*
|
||||
])
|
||||
|
||||
AT_TAR_CHECK([
|
||||
exec <&-
|
||||
echo2("Creating file")
|
||||
genfile --length 20139 --file file
|
||||
echo2("Creating archive")
|
||||
tar -c -M -L10 -b20 -farc.1 -farc.2 -farc.3 file
|
||||
echo2("Testing archive")
|
||||
tar -t -M -farc.1 -farc.2 -farc.3],
|
||||
[0],
|
||||
[Creating file
|
||||
Creating archive
|
||||
Testing archive
|
||||
file
|
||||
],
|
||||
[Creating file
|
||||
Creating archive
|
||||
Testing archive
|
||||
],
|
||||
[],[],
|
||||
[gnu, pax])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
@@ -155,6 +155,7 @@ m4_include([multiv02.at])
|
||||
m4_include([multiv03.at])
|
||||
m4_include([multiv04.at])
|
||||
m4_include([multiv05.at])
|
||||
m4_include([multiv06.at])
|
||||
|
||||
m4_include([old.at])
|
||||
|
||||
|
||||
Reference in New Issue
Block a user