diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2019-05-24 17:03:28 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2019-05-24 17:03:28 +0200 |
commit | dff2bd733fc2dac08d34f2cfad0e68aeb8e7a7a2 (patch) | |
tree | 0085fabf15b8ca5034636f39e97e9ba306ca7671 /archival/libarchive | |
parent | 309f5e3775ed9cc0837c6d93482735bc4f117d5b (diff) | |
download | busybox-w32-dff2bd733fc2dac08d34f2cfad0e68aeb8e7a7a2.tar.gz busybox-w32-dff2bd733fc2dac08d34f2cfad0e68aeb8e7a7a2.tar.bz2 busybox-w32-dff2bd733fc2dac08d34f2cfad0e68aeb8e7a7a2.zip |
libarchive: treat one "FIXME: avoid seek"
function old new delta
xmalloc_read_with_initial_buf - 205 +205
setup_transformer_on_fd 154 150 -4
xmalloc_open_zipped_read_close 143 135 -8
xmalloc_read 201 10 -191
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 0/3 up/down: 205/-203) Total: 2 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'archival/libarchive')
-rw-r--r-- | archival/libarchive/open_transformer.c | 44 |
1 files changed, 27 insertions, 17 deletions
diff --git a/archival/libarchive/open_transformer.c b/archival/libarchive/open_transformer.c index 4a4bf3916..97bcc32f0 100644 --- a/archival/libarchive/open_transformer.c +++ b/archival/libarchive/open_transformer.c | |||
@@ -159,47 +159,44 @@ void FAST_FUNC fork_transformer(int fd, const char *transform_prog) | |||
159 | */ | 159 | */ |
160 | static transformer_state_t *setup_transformer_on_fd(int fd, int fail_if_not_compressed) | 160 | static transformer_state_t *setup_transformer_on_fd(int fd, int fail_if_not_compressed) |
161 | { | 161 | { |
162 | union { | ||
163 | uint8_t b[4]; | ||
164 | uint16_t b16[2]; | ||
165 | uint32_t b32[1]; | ||
166 | } magic; | ||
167 | transformer_state_t *xstate; | 162 | transformer_state_t *xstate; |
168 | 163 | ||
169 | xstate = xzalloc(sizeof(*xstate)); | 164 | xstate = xzalloc(sizeof(*xstate)); |
170 | xstate->src_fd = fd; | 165 | xstate->src_fd = fd; |
171 | xstate->signature_skipped = 2; | ||
172 | 166 | ||
173 | /* .gz and .bz2 both have 2-byte signature, and their | 167 | /* .gz and .bz2 both have 2-byte signature, and their |
174 | * unpack_XXX_stream wants this header skipped. */ | 168 | * unpack_XXX_stream wants this header skipped. */ |
175 | xread(fd, magic.b16, sizeof(magic.b16[0])); | 169 | xstate->signature_skipped = 2; |
170 | xread(fd, xstate->magic.b16, 2); | ||
176 | if (ENABLE_FEATURE_SEAMLESS_GZ | 171 | if (ENABLE_FEATURE_SEAMLESS_GZ |
177 | && magic.b16[0] == GZIP_MAGIC | 172 | && xstate->magic.b16[0] == GZIP_MAGIC |
178 | ) { | 173 | ) { |
179 | xstate->xformer = unpack_gz_stream; | 174 | xstate->xformer = unpack_gz_stream; |
180 | USE_FOR_NOMMU(xstate->xformer_prog = "gunzip";) | 175 | USE_FOR_NOMMU(xstate->xformer_prog = "gunzip";) |
181 | goto found_magic; | 176 | goto found_magic; |
182 | } | 177 | } |
183 | if (ENABLE_FEATURE_SEAMLESS_Z | 178 | if (ENABLE_FEATURE_SEAMLESS_Z |
184 | && magic.b16[0] == COMPRESS_MAGIC | 179 | && xstate->magic.b16[0] == COMPRESS_MAGIC |
185 | ) { | 180 | ) { |
186 | xstate->xformer = unpack_Z_stream; | 181 | xstate->xformer = unpack_Z_stream; |
187 | USE_FOR_NOMMU(xstate->xformer_prog = "uncompress";) | 182 | USE_FOR_NOMMU(xstate->xformer_prog = "uncompress";) |
188 | goto found_magic; | 183 | goto found_magic; |
189 | } | 184 | } |
190 | if (ENABLE_FEATURE_SEAMLESS_BZ2 | 185 | if (ENABLE_FEATURE_SEAMLESS_BZ2 |
191 | && magic.b16[0] == BZIP2_MAGIC | 186 | && xstate->magic.b16[0] == BZIP2_MAGIC |
192 | ) { | 187 | ) { |
193 | xstate->xformer = unpack_bz2_stream; | 188 | xstate->xformer = unpack_bz2_stream; |
194 | USE_FOR_NOMMU(xstate->xformer_prog = "bunzip2";) | 189 | USE_FOR_NOMMU(xstate->xformer_prog = "bunzip2";) |
195 | goto found_magic; | 190 | goto found_magic; |
196 | } | 191 | } |
197 | if (ENABLE_FEATURE_SEAMLESS_XZ | 192 | if (ENABLE_FEATURE_SEAMLESS_XZ |
198 | && magic.b16[0] == XZ_MAGIC1 | 193 | && xstate->magic.b16[0] == XZ_MAGIC1 |
199 | ) { | 194 | ) { |
195 | uint32_t v32; | ||
200 | xstate->signature_skipped = 6; | 196 | xstate->signature_skipped = 6; |
201 | xread(fd, magic.b32, sizeof(magic.b32[0])); | 197 | xread(fd, &xstate->magic.b16[1], 4); |
202 | if (magic.b32[0] == XZ_MAGIC2) { | 198 | move_from_unaligned32(v32, &xstate->magic.b16[1]); |
199 | if (v32 == XZ_MAGIC2) { | ||
203 | xstate->xformer = unpack_xz_stream; | 200 | xstate->xformer = unpack_xz_stream; |
204 | USE_FOR_NOMMU(xstate->xformer_prog = "unxz";) | 201 | USE_FOR_NOMMU(xstate->xformer_prog = "unxz";) |
205 | goto found_magic; | 202 | goto found_magic; |
@@ -344,11 +341,24 @@ void* FAST_FUNC xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_ | |||
344 | *maxsz_p = xstate->mem_output_size; | 341 | *maxsz_p = xstate->mem_output_size; |
345 | } | 342 | } |
346 | } else { | 343 | } else { |
347 | /* File is not compressed */ | 344 | /* File is not compressed. |
348 | //FIXME: avoid seek | 345 | * We already read first few bytes, account for that. |
349 | xlseek(xstate->src_fd, - xstate->signature_skipped, SEEK_CUR); | 346 | * Exmaple where it happens: |
347 | * "modinfo MODULE.ko" (not compressed) | ||
348 | * open("MODULE.ko", O_RDONLY|O_LARGEFILE) = 4 | ||
349 | * read(4, "\177E", 2) = 2 | ||
350 | * fstat64(4, ...) | ||
351 | * mmap(...) | ||
352 | * read(4, "LF\2\1\1\0\0\0\0"... | ||
353 | * ...and we avoided seeking on the fd! :) | ||
354 | */ | ||
350 | xstate->signature_skipped = 0; | 355 | xstate->signature_skipped = 0; |
351 | image = xmalloc_read(xstate->src_fd, maxsz_p); | 356 | image = xmalloc_read_with_initial_buf( |
357 | xstate->src_fd, | ||
358 | maxsz_p, | ||
359 | xmemdup(&xstate->magic, xstate->signature_skipped), | ||
360 | xstate->signature_skipped | ||
361 | ); | ||
352 | } | 362 | } |
353 | 363 | ||
354 | if (!image) | 364 | if (!image) |