Magellan Linux

Contents of /trunk/libarchive/patches/libarchive-2.7.0-pipe.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 842 - (show annotations) (download)
Thu Jun 11 18:52:50 2009 UTC (14 years, 11 months ago) by niro
File size: 3859 byte(s)
-added libarchive patches

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