Gentoo Archives: gentoo-commits

From: "Diego Petteno (flameeyes)" <flameeyes@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] gentoo-x86 commit in app-arch/libarchive/files: libarchive-2.7.0-pipe.patch
Date: Thu, 14 May 2009 22:12:43
Message-Id: E1M4jAP-0007gV-GG@stork.gentoo.org
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);