summaryrefslogtreecommitdiff
path: root/src/buffer.c
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2016-03-15 00:02:40 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2016-03-15 00:02:40 +0200
commit2a7c84b4a9d2a0740c7453e82433518218d1bb17 (patch)
treec988df57abe6f05a5e1b90b12e2186dd6bf03d1e /src/buffer.c
parentda7845c6563e7337bf3e8364046a7989091f190e (diff)
downloadtar-2a7c84b4a9d2a0740c7453e82433518218d1bb17.tar.gz
Fix appending to archive with changed blocking factor.
* src/buffer.c (flush_archive): If previous reading attempt resulted in short read, correctly use the remaining record space. (backspace_output): Fix position calculation (still has to be improved). * tests/append05.at: New test case. * tests/Makefile.am: Add new test. * tests/testsuite.at: Likewise.
Diffstat (limited to 'src/buffer.c')
-rw-r--r--src/buffer.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/src/buffer.c b/src/buffer.c
index b5fa210b..dcbfd028 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -983,18 +983,28 @@ short_read (size_t status)
void
flush_archive (void)
{
- size_t buffer_level = current_block->buffer - record_start->buffer;
- record_start_block += record_end - record_start;
- current_block = record_start;
- record_end = record_start + blocking_factor;
-
+ size_t buffer_level;
+
if (access_mode == ACCESS_READ && time_to_start_writing)
{
access_mode = ACCESS_WRITE;
time_to_start_writing = false;
backspace_output ();
+ if (record_end - record_start < blocking_factor)
+ {
+ memset (record_end, 0,
+ (blocking_factor - (record_end - record_start))
+ * BLOCKSIZE);
+ record_end = record_start + blocking_factor;
+ return;
+ }
}
+ buffer_level = current_block->buffer - record_start->buffer;
+ record_start_block += record_end - record_start;
+ current_block = record_start;
+ record_end = record_start + blocking_factor;
+
switch (access_mode)
{
case ACCESS_READ:
@@ -1034,7 +1044,7 @@ backspace_output (void)
/* Seek back to the beginning of this record and start writing there. */
- position -= record_size;
+ position -= record_end->buffer - record_start->buffer;
if (position < 0)
position = 0;
if (rmtlseek (archive, position, SEEK_SET) != position)