mirror of https://github.com/mirror/busybox.git
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>1_31_stable
parent
309f5e3775
commit
dff2bd733f
|
@ -159,47 +159,44 @@ void FAST_FUNC fork_transformer(int fd, const char *transform_prog)
|
||||||
*/
|
*/
|
||||||
static transformer_state_t *setup_transformer_on_fd(int fd, int fail_if_not_compressed)
|
static transformer_state_t *setup_transformer_on_fd(int fd, int fail_if_not_compressed)
|
||||||
{
|
{
|
||||||
union {
|
|
||||||
uint8_t b[4];
|
|
||||||
uint16_t b16[2];
|
|
||||||
uint32_t b32[1];
|
|
||||||
} magic;
|
|
||||||
transformer_state_t *xstate;
|
transformer_state_t *xstate;
|
||||||
|
|
||||||
xstate = xzalloc(sizeof(*xstate));
|
xstate = xzalloc(sizeof(*xstate));
|
||||||
xstate->src_fd = fd;
|
xstate->src_fd = fd;
|
||||||
xstate->signature_skipped = 2;
|
|
||||||
|
|
||||||
/* .gz and .bz2 both have 2-byte signature, and their
|
/* .gz and .bz2 both have 2-byte signature, and their
|
||||||
* unpack_XXX_stream wants this header skipped. */
|
* unpack_XXX_stream wants this header skipped. */
|
||||||
xread(fd, magic.b16, sizeof(magic.b16[0]));
|
xstate->signature_skipped = 2;
|
||||||
|
xread(fd, xstate->magic.b16, 2);
|
||||||
if (ENABLE_FEATURE_SEAMLESS_GZ
|
if (ENABLE_FEATURE_SEAMLESS_GZ
|
||||||
&& magic.b16[0] == GZIP_MAGIC
|
&& xstate->magic.b16[0] == GZIP_MAGIC
|
||||||
) {
|
) {
|
||||||
xstate->xformer = unpack_gz_stream;
|
xstate->xformer = unpack_gz_stream;
|
||||||
USE_FOR_NOMMU(xstate->xformer_prog = "gunzip";)
|
USE_FOR_NOMMU(xstate->xformer_prog = "gunzip";)
|
||||||
goto found_magic;
|
goto found_magic;
|
||||||
}
|
}
|
||||||
if (ENABLE_FEATURE_SEAMLESS_Z
|
if (ENABLE_FEATURE_SEAMLESS_Z
|
||||||
&& magic.b16[0] == COMPRESS_MAGIC
|
&& xstate->magic.b16[0] == COMPRESS_MAGIC
|
||||||
) {
|
) {
|
||||||
xstate->xformer = unpack_Z_stream;
|
xstate->xformer = unpack_Z_stream;
|
||||||
USE_FOR_NOMMU(xstate->xformer_prog = "uncompress";)
|
USE_FOR_NOMMU(xstate->xformer_prog = "uncompress";)
|
||||||
goto found_magic;
|
goto found_magic;
|
||||||
}
|
}
|
||||||
if (ENABLE_FEATURE_SEAMLESS_BZ2
|
if (ENABLE_FEATURE_SEAMLESS_BZ2
|
||||||
&& magic.b16[0] == BZIP2_MAGIC
|
&& xstate->magic.b16[0] == BZIP2_MAGIC
|
||||||
) {
|
) {
|
||||||
xstate->xformer = unpack_bz2_stream;
|
xstate->xformer = unpack_bz2_stream;
|
||||||
USE_FOR_NOMMU(xstate->xformer_prog = "bunzip2";)
|
USE_FOR_NOMMU(xstate->xformer_prog = "bunzip2";)
|
||||||
goto found_magic;
|
goto found_magic;
|
||||||
}
|
}
|
||||||
if (ENABLE_FEATURE_SEAMLESS_XZ
|
if (ENABLE_FEATURE_SEAMLESS_XZ
|
||||||
&& magic.b16[0] == XZ_MAGIC1
|
&& xstate->magic.b16[0] == XZ_MAGIC1
|
||||||
) {
|
) {
|
||||||
|
uint32_t v32;
|
||||||
xstate->signature_skipped = 6;
|
xstate->signature_skipped = 6;
|
||||||
xread(fd, magic.b32, sizeof(magic.b32[0]));
|
xread(fd, &xstate->magic.b16[1], 4);
|
||||||
if (magic.b32[0] == XZ_MAGIC2) {
|
move_from_unaligned32(v32, &xstate->magic.b16[1]);
|
||||||
|
if (v32 == XZ_MAGIC2) {
|
||||||
xstate->xformer = unpack_xz_stream;
|
xstate->xformer = unpack_xz_stream;
|
||||||
USE_FOR_NOMMU(xstate->xformer_prog = "unxz";)
|
USE_FOR_NOMMU(xstate->xformer_prog = "unxz";)
|
||||||
goto found_magic;
|
goto found_magic;
|
||||||
|
@ -344,11 +341,24 @@ void* FAST_FUNC xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_
|
||||||
*maxsz_p = xstate->mem_output_size;
|
*maxsz_p = xstate->mem_output_size;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* File is not compressed */
|
/* File is not compressed.
|
||||||
//FIXME: avoid seek
|
* We already read first few bytes, account for that.
|
||||||
xlseek(xstate->src_fd, - xstate->signature_skipped, SEEK_CUR);
|
* Exmaple where it happens:
|
||||||
|
* "modinfo MODULE.ko" (not compressed)
|
||||||
|
* open("MODULE.ko", O_RDONLY|O_LARGEFILE) = 4
|
||||||
|
* read(4, "\177E", 2) = 2
|
||||||
|
* fstat64(4, ...)
|
||||||
|
* mmap(...)
|
||||||
|
* read(4, "LF\2\1\1\0\0\0\0"...
|
||||||
|
* ...and we avoided seeking on the fd! :)
|
||||||
|
*/
|
||||||
xstate->signature_skipped = 0;
|
xstate->signature_skipped = 0;
|
||||||
image = xmalloc_read(xstate->src_fd, maxsz_p);
|
image = xmalloc_read_with_initial_buf(
|
||||||
|
xstate->src_fd,
|
||||||
|
maxsz_p,
|
||||||
|
xmemdup(&xstate->magic, xstate->signature_skipped),
|
||||||
|
xstate->signature_skipped
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!image)
|
if (!image)
|
||||||
|
|
|
@ -235,6 +235,12 @@ typedef struct transformer_state_t {
|
||||||
off_t bytes_in; /* used in unzip code only: needs to know packed size */
|
off_t bytes_in; /* used in unzip code only: needs to know packed size */
|
||||||
uint32_t crc32;
|
uint32_t crc32;
|
||||||
time_t mtime; /* gunzip code may set this on exit */
|
time_t mtime; /* gunzip code may set this on exit */
|
||||||
|
|
||||||
|
union { /* if we read magic, it's saved here */
|
||||||
|
uint8_t b[8];
|
||||||
|
uint16_t b16[4];
|
||||||
|
uint32_t b32[2];
|
||||||
|
} magic;
|
||||||
} transformer_state_t;
|
} transformer_state_t;
|
||||||
|
|
||||||
void init_transformer_state(transformer_state_t *xstate) FAST_FUNC;
|
void init_transformer_state(transformer_state_t *xstate) FAST_FUNC;
|
||||||
|
|
|
@ -881,6 +881,7 @@ extern ssize_t open_read_close(const char *filename, void *buf, size_t maxsz) FA
|
||||||
extern char *xmalloc_reads(int fd, size_t *maxsz_p) FAST_FUNC;
|
extern char *xmalloc_reads(int fd, size_t *maxsz_p) FAST_FUNC;
|
||||||
/* Reads block up to *maxsz_p (default: INT_MAX - 4095) */
|
/* Reads block up to *maxsz_p (default: INT_MAX - 4095) */
|
||||||
extern void *xmalloc_read(int fd, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC;
|
extern void *xmalloc_read(int fd, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC;
|
||||||
|
extern void *xmalloc_read_with_initial_buf(int fd, size_t *maxsz_p, char *buf, size_t total) FAST_FUNC;
|
||||||
/* Returns NULL if file can't be opened (default max size: INT_MAX - 4095) */
|
/* Returns NULL if file can't be opened (default max size: INT_MAX - 4095) */
|
||||||
extern void *xmalloc_open_read_close(const char *filename, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC;
|
extern void *xmalloc_open_read_close(const char *filename, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC;
|
||||||
/* Never returns NULL */
|
/* Never returns NULL */
|
||||||
|
|
|
@ -102,10 +102,9 @@ char* FAST_FUNC xmalloc_reads(int fd, size_t *maxsz_p)
|
||||||
|
|
||||||
// Read (potentially big) files in one go. File size is estimated
|
// Read (potentially big) files in one go. File size is estimated
|
||||||
// by stat. Extra '\0' byte is appended.
|
// by stat. Extra '\0' byte is appended.
|
||||||
void* FAST_FUNC xmalloc_read(int fd, size_t *maxsz_p)
|
void* FAST_FUNC xmalloc_read_with_initial_buf(int fd, size_t *maxsz_p, char *buf, size_t total)
|
||||||
{
|
{
|
||||||
char *buf;
|
size_t size, rd_size;
|
||||||
size_t size, rd_size, total;
|
|
||||||
size_t to_read;
|
size_t to_read;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
||||||
|
@ -118,8 +117,6 @@ void* FAST_FUNC xmalloc_read(int fd, size_t *maxsz_p)
|
||||||
/* In order to make such files readable, we add small const */
|
/* In order to make such files readable, we add small const */
|
||||||
size = (st.st_size | 0x3ff) + 1;
|
size = (st.st_size | 0x3ff) + 1;
|
||||||
|
|
||||||
total = 0;
|
|
||||||
buf = NULL;
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (to_read < size)
|
if (to_read < size)
|
||||||
size = to_read;
|
size = to_read;
|
||||||
|
@ -148,6 +145,11 @@ void* FAST_FUNC xmalloc_read(int fd, size_t *maxsz_p)
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* FAST_FUNC xmalloc_read(int fd, size_t *maxsz_p)
|
||||||
|
{
|
||||||
|
return xmalloc_read_with_initial_buf(fd, maxsz_p, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef USING_LSEEK_TO_GET_SIZE
|
#ifdef USING_LSEEK_TO_GET_SIZE
|
||||||
/* Alternatively, file size can be obtained by lseek to the end.
|
/* Alternatively, file size can be obtained by lseek to the end.
|
||||||
* The code is slightly bigger. Retained in case fstat approach
|
* The code is slightly bigger. Retained in case fstat approach
|
||||||
|
|
Loading…
Reference in New Issue