Don't assume archive read from stdin starts at offset 0

* src/buffer.c (start_offset): New variable.
(get_archive_status): If reading from seekable stdin, store the
position in the stream corresponding to record_start in start_offset.
(seek_archive): Compute current offset relative to start_offset.
This commit is contained in:
Sergey Poznyakoff
2024-10-31 19:09:28 +02:00
parent bd06b114d9
commit 647cafff96

View File

@@ -65,6 +65,7 @@ union block *current_block; /* current block of archive */
enum access_mode access_mode; /* how do we handle the archive */ enum access_mode access_mode; /* how do we handle the archive */
off_t records_read; /* number of records read from this archive */ off_t records_read; /* number of records read from this archive */
off_t records_written; /* likewise, for records written */ off_t records_written; /* likewise, for records written */
off_t start_offset; /* start offset in the archive */
/* When file status was last computed. */ /* When file status was last computed. */
static struct timespec last_stat_time; static struct timespec last_stat_time;
@@ -710,7 +711,20 @@ get_archive_status (enum access_mode wanted_access, bool backed_up_flag)
|| S_ISBLK (archive_stat.st_mode)) || S_ISBLK (archive_stat.st_mode))
: seek_option)); : seek_option));
if (wanted_access != ACCESS_READ) if (wanted_access == ACCESS_READ)
{
if (archive == STDIN_FILENO && seekable_archive)
{
start_offset = lseek (archive, 0, SEEK_CUR);
if (start_offset == -1)
seekable_archive = false;
else
start_offset -= (record_end - record_start) * BLOCKSIZE;
}
else
start_offset = 0;
}
else
sys_detect_dev_null_output (); sys_detect_dev_null_output ();
SET_BINARY_MODE (archive); SET_BINARY_MODE (archive);
@@ -1096,6 +1110,8 @@ seek_archive (off_t size)
if (offset < 0) if (offset < 0)
return offset; return offset;
offset -= start_offset;
if (offset % record_size) if (offset % record_size)
paxfatal (0, _("rmtlseek not stopped at a record boundary")); paxfatal (0, _("rmtlseek not stopped at a record boundary"));