diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2016-03-15 00:02:40 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2016-03-15 00:02:40 +0200 |
commit | 2a7c84b4a9d2a0740c7453e82433518218d1bb17 (patch) | |
tree | c988df57abe6f05a5e1b90b12e2186dd6bf03d1e /src/buffer.c | |
parent | da7845c6563e7337bf3e8364046a7989091f190e (diff) | |
download | tar-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.c | 22 |
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) |