- 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