public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-commits] gentoo-x86 commit in app-arch/libarchive/files: libarchive-2.7.0-pipe.patch
@ 2009-05-14 22:12 Diego Petteno (flameeyes)
  0 siblings, 0 replies; only message in thread
From: Diego Petteno (flameeyes) @ 2009-05-14 22:12 UTC (permalink / raw
  To: gentoo-commits

flameeyes    09/05/14 22:12:41

  Added:                libarchive-2.7.0-pipe.patch
  Log:
  Add a patch to fix behaviour with pipe, allows for bsdtar to work with current Portage behaviour.
  (Portage version: 2.2_rc33/cvs/Linux x86_64)

Revision  Changes    Path
1.1                  app-arch/libarchive/files/libarchive-2.7.0-pipe.patch

file : http://sources.gentoo.org/viewcvs.py/gentoo-x86/app-arch/libarchive/files/libarchive-2.7.0-pipe.patch?rev=1.1&view=markup
plain: http://sources.gentoo.org/viewcvs.py/gentoo-x86/app-arch/libarchive/files/libarchive-2.7.0-pipe.patch?rev=1.1&content-type=text/plain

Index: libarchive-2.7.0-pipe.patch
===================================================================
--- head/lib/libarchive/archive_read_open_filename.c	2009/05/07 21:51:13	191903
+++ head/lib/libarchive/archive_read_open_filename.c	2009/05/07 23:01:03	191904
@@ -85,19 +85,31 @@
 	int fd;
 
-	if (filename == NULL || filename[0] == '\0')
-		return (archive_read_open_fd(a, 0, block_size));
-
-	fd = open(filename, O_RDONLY | O_BINARY);
-	if (fd < 0) {
-		archive_set_error(a, errno, "Failed to open '%s'", filename);
-		return (ARCHIVE_FATAL);
+	if (filename == NULL || filename[0] == '\0') {
+		/* We used to invoke archive_read_open_fd(a,0,block_size)
+		 * here, but that doesn't (and shouldn't) handle the
+		 * end-of-file flush when reading stdout from a pipe.
+		 * Basically, read_open_fd() is intended for folks who
+		 * are willing to handle such details themselves.  This
+		 * API is intended to be a little smarter for folks who
+		 * want easy handling of the common case.
+		 */
+		filename = ""; /* Normalize NULL to "" */
+		fd = 0;
+	} else {
+		fd = open(filename, O_RDONLY | O_BINARY);
+		if (fd < 0) {
+			archive_set_error(a, errno,
+			    "Failed to open '%s'", filename);
+			return (ARCHIVE_FATAL);
+		}
 	}
 	if (fstat(fd, &st) != 0) {
 		archive_set_error(a, errno, "Can't stat '%s'", filename);
 		return (ARCHIVE_FATAL);
 	}
 
-	mine = (struct read_file_data *)malloc(sizeof(*mine) + strlen(filename));
+	mine = (struct read_file_data *)calloc(1,
+	    sizeof(*mine) + strlen(filename));
 	b = malloc(block_size);
 	if (mine == NULL || b == NULL) {
 		archive_set_error(a, ENOMEM, "No memory");
@@ -117,15 +129,20 @@
 	if (S_ISREG(st.st_mode)) {
 		archive_read_extract_set_skip_file(a, st.st_dev, st.st_ino);
 		/*
-		 * Skip is a performance optimization for anything
-		 * that supports lseek().  Generally, that only
-		 * includes regular files and possibly raw disk
-		 * devices, but there's no good portable way to detect
-		 * raw disks.
+		 * Enabling skip here is a performance optimization
+		 * for anything that supports lseek().  On FreeBSD
+		 * (and probably many other systems), only regular
+		 * files and raw disk devices support lseek() (on
+		 * other input types, lseek() returns success but
+		 * doesn't actually change the file pointer, which
+		 * just completely screws up the position-tracking
+		 * logic).  In addition, I've yet to find a portable
+		 * way to determine if a device is a raw disk device.
+		 * So I don't see a way to do much better than to only
+		 * enable this optimization for regular files.
 		 */
 		mine->can_skip = 1;
-	} else
-		mine->can_skip = 0;
+	}
 	return (archive_read_open2(a, mine,
 		NULL, file_read, file_skip, file_close));
 }
@@ -139,8 +156,11 @@
 	*buff = mine->buffer;
 	bytes_read = read(mine->fd, mine->buffer, mine->block_size);
 	if (bytes_read < 0) {
-		archive_set_error(a, errno, "Error reading '%s'",
-		    mine->filename);
+		if (mine->filename[0] == '\0')
+			archive_set_error(a, errno, "Error reading stdin");
+		else
+			archive_set_error(a, errno, "Error reading '%s'",
+			    mine->filename);
 	}
 	return (bytes_read);
 }
@@ -190,8 +210,15 @@
 		 * likely caused by a programmer error (too large request)
 		 * or a corrupted archive file.
 		 */
-		archive_set_error(a, errno, "Error seeking in '%s'",
-		    mine->filename);
+		if (mine->filename[0] == '\0')
+			/*
+			 * Should never get here, since lseek() on stdin ought
+			 * to return an ESPIPE error.
+			 */
+			archive_set_error(a, errno, "Error seeking in stdin");
+		else
+			archive_set_error(a, errno, "Error seeking in '%s'",
+			    mine->filename);
 		return (-1);
 	}
 	return (new_offset - old_offset);
@@ -225,7 +252,9 @@
 				    mine->block_size);
 			} while (bytesRead > 0);
 		}
-		close(mine->fd);
+		/* If a named file was opened, then it needs to be closed. */
+		if (mine->filename[0] != '\0')
+			close(mine->fd);
 	}
 	free(mine->buffer);
 	free(mine);






^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2009-05-14 22:12 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-05-14 22:12 [gentoo-commits] gentoo-x86 commit in app-arch/libarchive/files: libarchive-2.7.0-pipe.patch Diego Petteno (flameeyes)

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox