]> Dogcows Code - chaz/tar/commitdiff
Fix multivolume archive creation when volume length=record size.
authorSergey Poznyakoff <gray@gnu.org.ua>
Thu, 24 Jul 2008 18:16:08 +0000 (18:16 +0000)
committerSergey Poznyakoff <gray@gnu.org.ua>
Thu, 24 Jul 2008 18:16:08 +0000 (18:16 +0000)
* 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

ChangeLog
src/buffer.c
src/create.c
src/tar.c
tests/Makefile.am
tests/multiv06.at [new file with mode: 0644]
tests/testsuite.at

index 6b9676c0ad3e15462db70f8cd6c3f9170e3e8aaa..b2e94524cc0b4344b6656c787574369b4d691802 100644 (file)
--- a/ChangeLog
+++ b/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
index be0b3784e02897f3c1cd4b8173a5349f584f144f..e590e12834280f52400b3d2a797c7106b0033d39 100644 (file)
@@ -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 ();
 }
 
index 413115cf06e974834f39f0f551f5b10fd420c1cc..fc26f1ef3374792a59fbe6caaf03299c33203fb5 100644 (file)
@@ -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 ();
index cc11ba5810eba0e3c2799a76b254d80d44507e89..4680f4677f33f1aac85eff797bceba0cbd95aa68 100644 (file)
--- a/src/tar.c
+++ b/src/tar.c
@@ -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.  */
 
index 729bdd95fa96cd362f223e12e985cfb1e3a217a1..263f6eefd02d58eb1170b94cbe24824bb8354564 100644 (file)
@@ -89,6 +89,7 @@ TESTSUITE_AT = \
  multiv03.at\
  multiv04.at\
  multiv05.at\
+ multiv06.at\
  old.at\
  options.at\
  options02.at\
diff --git a/tests/multiv06.at b/tests/multiv06.at
new file mode 100644 (file)
index 0000000..4df9cd7
--- /dev/null
@@ -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
+
index 5b633540016331e1563669618e2f864954f39efb..11f108bd6c3c58d8b701a9860caf3f89e7fd2e14 100644 (file)
@@ -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])
 
This page took 0.036438 seconds and 4 git commands to generate.