1 |
flameeyes 09/05/14 22:12:41 |
2 |
|
3 |
Added: libarchive-2.7.0-pipe.patch |
4 |
Log: |
5 |
Add a patch to fix behaviour with pipe, allows for bsdtar to work with current Portage behaviour. |
6 |
(Portage version: 2.2_rc33/cvs/Linux x86_64) |
7 |
|
8 |
Revision Changes Path |
9 |
1.1 app-arch/libarchive/files/libarchive-2.7.0-pipe.patch |
10 |
|
11 |
file : http://sources.gentoo.org/viewcvs.py/gentoo-x86/app-arch/libarchive/files/libarchive-2.7.0-pipe.patch?rev=1.1&view=markup |
12 |
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 |
13 |
|
14 |
Index: libarchive-2.7.0-pipe.patch |
15 |
=================================================================== |
16 |
--- head/lib/libarchive/archive_read_open_filename.c 2009/05/07 21:51:13 191903 |
17 |
+++ head/lib/libarchive/archive_read_open_filename.c 2009/05/07 23:01:03 191904 |
18 |
@@ -85,19 +85,31 @@ |
19 |
int fd; |
20 |
|
21 |
- if (filename == NULL || filename[0] == '\0') |
22 |
- return (archive_read_open_fd(a, 0, block_size)); |
23 |
- |
24 |
- fd = open(filename, O_RDONLY | O_BINARY); |
25 |
- if (fd < 0) { |
26 |
- archive_set_error(a, errno, "Failed to open '%s'", filename); |
27 |
- return (ARCHIVE_FATAL); |
28 |
+ if (filename == NULL || filename[0] == '\0') { |
29 |
+ /* We used to invoke archive_read_open_fd(a,0,block_size) |
30 |
+ * here, but that doesn't (and shouldn't) handle the |
31 |
+ * end-of-file flush when reading stdout from a pipe. |
32 |
+ * Basically, read_open_fd() is intended for folks who |
33 |
+ * are willing to handle such details themselves. This |
34 |
+ * API is intended to be a little smarter for folks who |
35 |
+ * want easy handling of the common case. |
36 |
+ */ |
37 |
+ filename = ""; /* Normalize NULL to "" */ |
38 |
+ fd = 0; |
39 |
+ } else { |
40 |
+ fd = open(filename, O_RDONLY | O_BINARY); |
41 |
+ if (fd < 0) { |
42 |
+ archive_set_error(a, errno, |
43 |
+ "Failed to open '%s'", filename); |
44 |
+ return (ARCHIVE_FATAL); |
45 |
+ } |
46 |
} |
47 |
if (fstat(fd, &st) != 0) { |
48 |
archive_set_error(a, errno, "Can't stat '%s'", filename); |
49 |
return (ARCHIVE_FATAL); |
50 |
} |
51 |
|
52 |
- mine = (struct read_file_data *)malloc(sizeof(*mine) + strlen(filename)); |
53 |
+ mine = (struct read_file_data *)calloc(1, |
54 |
+ sizeof(*mine) + strlen(filename)); |
55 |
b = malloc(block_size); |
56 |
if (mine == NULL || b == NULL) { |
57 |
archive_set_error(a, ENOMEM, "No memory"); |
58 |
@@ -117,15 +129,20 @@ |
59 |
if (S_ISREG(st.st_mode)) { |
60 |
archive_read_extract_set_skip_file(a, st.st_dev, st.st_ino); |
61 |
/* |
62 |
- * Skip is a performance optimization for anything |
63 |
- * that supports lseek(). Generally, that only |
64 |
- * includes regular files and possibly raw disk |
65 |
- * devices, but there's no good portable way to detect |
66 |
- * raw disks. |
67 |
+ * Enabling skip here is a performance optimization |
68 |
+ * for anything that supports lseek(). On FreeBSD |
69 |
+ * (and probably many other systems), only regular |
70 |
+ * files and raw disk devices support lseek() (on |
71 |
+ * other input types, lseek() returns success but |
72 |
+ * doesn't actually change the file pointer, which |
73 |
+ * just completely screws up the position-tracking |
74 |
+ * logic). In addition, I've yet to find a portable |
75 |
+ * way to determine if a device is a raw disk device. |
76 |
+ * So I don't see a way to do much better than to only |
77 |
+ * enable this optimization for regular files. |
78 |
*/ |
79 |
mine->can_skip = 1; |
80 |
- } else |
81 |
- mine->can_skip = 0; |
82 |
+ } |
83 |
return (archive_read_open2(a, mine, |
84 |
NULL, file_read, file_skip, file_close)); |
85 |
} |
86 |
@@ -139,8 +156,11 @@ |
87 |
*buff = mine->buffer; |
88 |
bytes_read = read(mine->fd, mine->buffer, mine->block_size); |
89 |
if (bytes_read < 0) { |
90 |
- archive_set_error(a, errno, "Error reading '%s'", |
91 |
- mine->filename); |
92 |
+ if (mine->filename[0] == '\0') |
93 |
+ archive_set_error(a, errno, "Error reading stdin"); |
94 |
+ else |
95 |
+ archive_set_error(a, errno, "Error reading '%s'", |
96 |
+ mine->filename); |
97 |
} |
98 |
return (bytes_read); |
99 |
} |
100 |
@@ -190,8 +210,15 @@ |
101 |
* likely caused by a programmer error (too large request) |
102 |
* or a corrupted archive file. |
103 |
*/ |
104 |
- archive_set_error(a, errno, "Error seeking in '%s'", |
105 |
- mine->filename); |
106 |
+ if (mine->filename[0] == '\0') |
107 |
+ /* |
108 |
+ * Should never get here, since lseek() on stdin ought |
109 |
+ * to return an ESPIPE error. |
110 |
+ */ |
111 |
+ archive_set_error(a, errno, "Error seeking in stdin"); |
112 |
+ else |
113 |
+ archive_set_error(a, errno, "Error seeking in '%s'", |
114 |
+ mine->filename); |
115 |
return (-1); |
116 |
} |
117 |
return (new_offset - old_offset); |
118 |
@@ -225,7 +252,9 @@ |
119 |
mine->block_size); |
120 |
} while (bytesRead > 0); |
121 |
} |
122 |
- close(mine->fd); |
123 |
+ /* If a named file was opened, then it needs to be closed. */ |
124 |
+ if (mine->filename[0] != '\0') |
125 |
+ close(mine->fd); |
126 |
} |
127 |
free(mine->buffer); |
128 |
free(mine); |