Magellan Linux

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

Parent Directory Parent Directory | Revision Log Revision Log


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

1 niro 842 --- 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);