+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
/* 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.
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;
}
if (real_s_name)
add_chunk_header ();
+ wrt = bytes_written;
header = find_next_block ();
bufsize = available_space_after (header);
while (bufsize < copy_size)
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 ();
}
while (size_left > 0)
{
size_t bufsize, count;
-
+
mv_size_left (size_left);
blk = find_next_block ();
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. */
multiv03.at\
multiv04.at\
multiv05.at\
+ multiv06.at\
old.at\
options.at\
options02.at\
--- /dev/null
+# 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
+
m4_include([multiv03.at])
m4_include([multiv04.at])
m4_include([multiv05.at])
+m4_include([multiv06.at])
m4_include([old.at])