Contents of /trunk/libarchive/patches/libarchive-2.7.0-pipe.patch
Parent Directory | Revision Log
Revision 842 -
(show annotations)
(download)
Thu Jun 11 18:52:50 2009 UTC (15 years, 3 months ago) by niro
File size: 3859 byte(s)
Thu Jun 11 18:52:50 2009 UTC (15 years, 3 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); |