- extract sparse files even if the output fd is not seekable.(#154882)
- (sparse_scan_file): Bugfix. offset had incorrect type.
This commit is contained in:
parent
1aa29f3857
commit
cd8b09bcba
162
tar-1.15.1-lseek.patch
Normal file
162
tar-1.15.1-lseek.patch
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
--- tar-1.15.1/src/sparse.c.lseek 2004-09-06 13:30:57.000000000 +0200
|
||||||
|
+++ tar-1.15.1/src/sparse.c 2005-04-15 10:33:17.990735744 +0200
|
||||||
|
@@ -46,6 +46,9 @@
|
||||||
|
struct tar_sparse_file
|
||||||
|
{
|
||||||
|
int fd; /* File descriptor */
|
||||||
|
+ bool seekable; /* Is fd seekable? */
|
||||||
|
+ size_t offset; /* Current offset in fd if seekable==false.
|
||||||
|
+ Otherwise unused */
|
||||||
|
size_t dumped_size; /* Number of bytes actually written
|
||||||
|
to the archive */
|
||||||
|
struct tar_stat_info *stat_info; /* Information about the file */
|
||||||
|
@@ -54,6 +57,39 @@
|
||||||
|
reqiure */
|
||||||
|
};
|
||||||
|
|
||||||
|
+/* Dump zeros to file->fd until offset is reached. It is used instead of
|
||||||
|
+ lseek if the output file is not seekable */
|
||||||
|
+static long
|
||||||
|
+dump_zeros (struct tar_sparse_file *file, off_t offset)
|
||||||
|
+{
|
||||||
|
+ char buf[BLOCKSIZE];
|
||||||
|
+
|
||||||
|
+ if (offset - file->offset < 0)
|
||||||
|
+ {
|
||||||
|
+ errno = EINVAL;
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ memset (buf, 0, sizeof buf);
|
||||||
|
+ while (file->offset < offset)
|
||||||
|
+ {
|
||||||
|
+ size_t size = offset - file->offset;
|
||||||
|
+ size_t wrbytes;
|
||||||
|
+
|
||||||
|
+ if (size > sizeof buf)
|
||||||
|
+ size = sizeof buf;
|
||||||
|
+ wrbytes = write (file->fd, buf, size);
|
||||||
|
+ if (wrbytes <= 0)
|
||||||
|
+ {
|
||||||
|
+ if (wrbytes == 0)
|
||||||
|
+ errno = EINVAL;
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ file->offset += wrbytes;
|
||||||
|
+ }
|
||||||
|
+ return file->offset;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static bool
|
||||||
|
tar_sparse_member_p (struct tar_sparse_file *file)
|
||||||
|
{
|
||||||
|
@@ -130,9 +166,16 @@
|
||||||
|
|
||||||
|
|
||||||
|
static bool
|
||||||
|
-lseek_or_error (struct tar_sparse_file *file, off_t offset, int whence)
|
||||||
|
+lseek_or_error (struct tar_sparse_file *file, off_t offset)
|
||||||
|
{
|
||||||
|
- if (lseek (file->fd, offset, whence) < 0)
|
||||||
|
+ off_t off;
|
||||||
|
+
|
||||||
|
+ if (file->seekable)
|
||||||
|
+ off = lseek (file->fd, offset, SEEK_SET);
|
||||||
|
+ else
|
||||||
|
+ off = dump_zeros (file, offset);
|
||||||
|
+
|
||||||
|
+ if (off < 0)
|
||||||
|
{
|
||||||
|
seek_diag_details (file->stat_info->orig_file_name, offset);
|
||||||
|
return false;
|
||||||
|
@@ -182,10 +225,10 @@
|
||||||
|
{
|
||||||
|
static char buffer[BLOCKSIZE];
|
||||||
|
size_t count;
|
||||||
|
- size_t offset = 0;
|
||||||
|
+ off_t offset = 0;
|
||||||
|
struct sp_array sp = {0, 0};
|
||||||
|
|
||||||
|
- if (!lseek_or_error (file, 0, SEEK_SET))
|
||||||
|
+ if (!lseek_or_error (file, 0))
|
||||||
|
return false;
|
||||||
|
clear_block (buffer);
|
||||||
|
|
||||||
|
@@ -269,8 +312,7 @@
|
||||||
|
union block *blk;
|
||||||
|
off_t bytes_left = file->stat_info->sparse_map[i].numbytes;
|
||||||
|
|
||||||
|
- if (!lseek_or_error (file, file->stat_info->sparse_map[i].offset,
|
||||||
|
- SEEK_SET))
|
||||||
|
+ if (!lseek_or_error (file, file->stat_info->sparse_map[i].offset))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
while (bytes_left > 0)
|
||||||
|
@@ -304,8 +346,7 @@
|
||||||
|
{
|
||||||
|
size_t write_size;
|
||||||
|
|
||||||
|
- if (!lseek_or_error (file, file->stat_info->sparse_map[i].offset,
|
||||||
|
- SEEK_SET))
|
||||||
|
+ if (!lseek_or_error (file, file->stat_info->sparse_map[i].offset))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
write_size = file->stat_info->sparse_map[i].numbytes;
|
||||||
|
@@ -313,7 +354,7 @@
|
||||||
|
if (write_size == 0)
|
||||||
|
{
|
||||||
|
/* Last block of the file is a hole */
|
||||||
|
- if (sys_truncate (file->fd))
|
||||||
|
+ if (file->seekable && sys_truncate (file->fd))
|
||||||
|
truncate_warn (file->stat_info->orig_file_name);
|
||||||
|
}
|
||||||
|
else while (write_size > 0)
|
||||||
|
@@ -330,6 +371,7 @@
|
||||||
|
count = full_write (file->fd, blk->buffer, wrbytes);
|
||||||
|
write_size -= count;
|
||||||
|
file->dumped_size += count;
|
||||||
|
+ file->offset += count;
|
||||||
|
if (count != wrbytes)
|
||||||
|
{
|
||||||
|
write_error_details (file->stat_info->orig_file_name,
|
||||||
|
@@ -351,7 +393,9 @@
|
||||||
|
|
||||||
|
file.stat_info = st;
|
||||||
|
file.fd = fd;
|
||||||
|
-
|
||||||
|
+ file.seekable = true; /* File *must* be seekable for dump to work */
|
||||||
|
+ file.offset = 0;
|
||||||
|
+
|
||||||
|
if (!sparse_select_optab (&file)
|
||||||
|
|| !tar_sparse_init (&file))
|
||||||
|
return dump_status_not_implemented;
|
||||||
|
@@ -414,7 +458,9 @@
|
||||||
|
|
||||||
|
file.stat_info = st;
|
||||||
|
file.fd = fd;
|
||||||
|
-
|
||||||
|
+ file.seekable = lseek (fd, 0, SEEK_SET) == 0;
|
||||||
|
+ file.offset = 0;
|
||||||
|
+
|
||||||
|
if (!sparse_select_optab (&file)
|
||||||
|
|| !tar_sparse_init (&file))
|
||||||
|
return dump_status_not_implemented;
|
||||||
|
@@ -450,7 +496,7 @@
|
||||||
|
static bool
|
||||||
|
check_sparse_region (struct tar_sparse_file *file, off_t beg, off_t end)
|
||||||
|
{
|
||||||
|
- if (!lseek_or_error (file, beg, SEEK_SET))
|
||||||
|
+ if (!lseek_or_error (file, beg))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
while (beg < end)
|
||||||
|
@@ -486,8 +532,7 @@
|
||||||
|
{
|
||||||
|
size_t size_left;
|
||||||
|
|
||||||
|
- if (!lseek_or_error (file, file->stat_info->sparse_map[i].offset,
|
||||||
|
- SEEK_SET))
|
||||||
|
+ if (!lseek_or_error (file, file->stat_info->sparse_map[i].offset))
|
||||||
|
return false;
|
||||||
|
size_left = file->stat_info->sparse_map[i].numbytes;
|
||||||
|
while (size_left > 0)
|
8
tar.spec
8
tar.spec
@ -1,7 +1,7 @@
|
|||||||
Summary: A GNU file archiving program.
|
Summary: A GNU file archiving program.
|
||||||
Name: tar
|
Name: tar
|
||||||
Version: 1.15.1
|
Version: 1.15.1
|
||||||
Release: 4
|
Release: 5
|
||||||
License: GPL
|
License: GPL
|
||||||
Group: Applications/Archiving
|
Group: Applications/Archiving
|
||||||
URL: http://www.gnu.org/software/tar/
|
URL: http://www.gnu.org/software/tar/
|
||||||
@ -13,6 +13,7 @@ Patch7: tar-1.14-err.patch
|
|||||||
Patch8: tar-1.14-loneZeroWarning.patch
|
Patch8: tar-1.14-loneZeroWarning.patch
|
||||||
Patch9: tar-1.15.1-makeCheck.patch
|
Patch9: tar-1.15.1-makeCheck.patch
|
||||||
Patch10: tar-1.15.1-gcc4.patch
|
Patch10: tar-1.15.1-gcc4.patch
|
||||||
|
Patch11: tar-1.15.1-lseek.patch
|
||||||
Prereq: info
|
Prereq: info
|
||||||
BuildRequires: autoconf automake gzip
|
BuildRequires: autoconf automake gzip
|
||||||
Buildroot: %{_tmppath}/%{name}-%{version}-root
|
Buildroot: %{_tmppath}/%{name}-%{version}-root
|
||||||
@ -37,6 +38,7 @@ the rmt package.
|
|||||||
%patch8 -p1 -b .loneZeroWarning
|
%patch8 -p1 -b .loneZeroWarning
|
||||||
%patch9 -p1 -b .makeCheck
|
%patch9 -p1 -b .makeCheck
|
||||||
%patch10 -p1 -b .gcc4
|
%patch10 -p1 -b .gcc4
|
||||||
|
%patch11 -p1 -b .lseek
|
||||||
|
|
||||||
%build
|
%build
|
||||||
|
|
||||||
@ -107,6 +109,10 @@ fi
|
|||||||
%{_infodir}/tar.info*
|
%{_infodir}/tar.info*
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Fri Apr 15 2005 Peter Vrabec <pvrabec@redhat.com> 1.15.1-5
|
||||||
|
- extract sparse files even if the output fd is not seekable.(#154882)
|
||||||
|
- (sparse_scan_file): Bugfix. offset had incorrect type.
|
||||||
|
|
||||||
* Mon Mar 14 2005 Peter Vrabec <pvrabec@redhat.com>
|
* Mon Mar 14 2005 Peter Vrabec <pvrabec@redhat.com>
|
||||||
- gcc4 fix (#150993) 1.15.1-4
|
- gcc4 fix (#150993) 1.15.1-4
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user