From b6052724ffc9d45894147b70e7aff226938bd2d3 Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Thu, 10 Jul 2008 17:43:01 +0000 Subject: [PATCH] open_transformer: do not return fd, it does not change libbb: adopt zipped read from modprobe-small function old new delta getoptscmd 708 713 +5 qgravechar 106 109 +3 huft_build 1165 1168 +3 tr_main 474 472 -2 open_transformer 91 89 -2 evalvar 1376 1374 -2 rpm_main 1691 1688 -3 qrealloc 36 33 -3 get_header_tar_lzma 55 52 -3 get_header_tar_gz 100 97 -3 get_header_tar_bz2 55 52 -3 get_header_tar_Z 89 86 -3 find_main 418 406 -12 prepare 302 283 -19 xmalloc_open_zipped_read_close 161 135 -26 xmalloc_read 248 199 -49 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 3/13 up/down: 11/-130) Total: -119 bytes --- archival/libunarchive/Kbuild | 2 + archival/libunarchive/get_header_tar_bz2.c | 2 +- archival/libunarchive/get_header_tar_gz.c | 2 +- archival/libunarchive/get_header_tar_lzma.c | 2 +- archival/libunarchive/open_transformer.c | 19 +++---- archival/rpm.c | 2 +- archival/tar.c | 2 +- include/libbb.h | 9 ++- include/unarchive.h | 6 +- libbb/read.c | 62 +++++++++++++++------ modutils/modprobe-small.c | 28 ---------- 11 files changed, 70 insertions(+), 66 deletions(-) diff --git a/archival/libunarchive/Kbuild b/archival/libunarchive/Kbuild index 1bc054a96..609bc50cb 100644 --- a/archival/libunarchive/Kbuild +++ b/archival/libunarchive/Kbuild @@ -43,6 +43,8 @@ lib-$(CONFIG_FEATURE_DEB_TAR_GZ) += open_transformer.o lib-$(CONFIG_FEATURE_DEB_TAR_BZ2) += open_transformer.o lib-$(CONFIG_FEATURE_DEB_TAR_LZMA) += open_transformer.o +lib-$(CONFIG_FEATURE_MODPROBE_SMALL_ZIPPED) += open_transformer.o decompress_unzip.o decompress_bunzip2.o + lib-$(CONFIG_AR) += get_header_ar.o unpack_ar_archive.o lib-$(CONFIG_BUNZIP2) += decompress_bunzip2.o lib-$(CONFIG_UNLZMA) += decompress_unlzma.o diff --git a/archival/libunarchive/get_header_tar_bz2.c b/archival/libunarchive/get_header_tar_bz2.c index cfdc016d6..035c10bfb 100644 --- a/archival/libunarchive/get_header_tar_bz2.c +++ b/archival/libunarchive/get_header_tar_bz2.c @@ -11,7 +11,7 @@ char FAST_FUNC get_header_tar_bz2(archive_handle_t *archive_handle) /* Can't lseek over pipes */ archive_handle->seek = seek_by_read; - archive_handle->src_fd = open_transformer(archive_handle->src_fd, unpack_bz2_stream, "bunzip2"); + open_transformer(archive_handle->src_fd, unpack_bz2_stream, "bunzip2"); archive_handle->offset = 0; while (get_header_tar(archive_handle) == EXIT_SUCCESS) continue; diff --git a/archival/libunarchive/get_header_tar_gz.c b/archival/libunarchive/get_header_tar_gz.c index 33c62729e..086c6df42 100644 --- a/archival/libunarchive/get_header_tar_gz.c +++ b/archival/libunarchive/get_header_tar_gz.c @@ -25,7 +25,7 @@ char FAST_FUNC get_header_tar_gz(archive_handle_t *archive_handle) } #endif - archive_handle->src_fd = open_transformer(archive_handle->src_fd, unpack_gz_stream, "gunzip"); + open_transformer(archive_handle->src_fd, unpack_gz_stream, "gunzip"); archive_handle->offset = 0; while (get_header_tar(archive_handle) == EXIT_SUCCESS) continue; diff --git a/archival/libunarchive/get_header_tar_lzma.c b/archival/libunarchive/get_header_tar_lzma.c index 730c1b1bb..03b1b792d 100644 --- a/archival/libunarchive/get_header_tar_lzma.c +++ b/archival/libunarchive/get_header_tar_lzma.c @@ -14,7 +14,7 @@ char FAST_FUNC get_header_tar_lzma(archive_handle_t *archive_handle) /* Can't lseek over pipes */ archive_handle->seek = seek_by_read; - archive_handle->src_fd = open_transformer(archive_handle->src_fd, unpack_lzma_stream, "unlzma"); + open_transformer(archive_handle->src_fd, unpack_lzma_stream, "unlzma"); archive_handle->offset = 0; while (get_header_tar(archive_handle) == EXIT_SUCCESS) continue; diff --git a/archival/libunarchive/open_transformer.c b/archival/libunarchive/open_transformer.c index a5ee97167..42fdd96a6 100644 --- a/archival/libunarchive/open_transformer.c +++ b/archival/libunarchive/open_transformer.c @@ -11,7 +11,7 @@ * On MMU machine, the transform_prog is removed by macro magic * in include/unarchive.h. On NOMMU, transformer is removed. */ -int FAST_FUNC open_transformer(int src_fd, +void FAST_FUNC open_transformer(int fd, USE_DESKTOP(long long) int FAST_FUNC (*transformer)(int src_fd, int dst_fd), const char *transform_prog) { @@ -32,20 +32,20 @@ int FAST_FUNC open_transformer(int src_fd, if (pid == 0) { /* child process */ - close(fd_pipe.rd); /* We don't want to read from the parent */ + close(fd_pipe.rd); /* we don't want to read from the parent */ // FIXME: error check? #if BB_MMU - transformer(src_fd, fd_pipe.wr); + transformer(fd, fd_pipe.wr); if (ENABLE_FEATURE_CLEAN_UP) { - close(fd_pipe.wr); /* Send EOF */ - close(src_fd); + close(fd_pipe.wr); /* send EOF */ + close(fd); } /* must be _exit! bug was actually seen here */ _exit(EXIT_SUCCESS); #else { char *argv[4]; - xmove_fd(src_fd, 0); + xmove_fd(fd, 0); xmove_fd(fd_pipe.wr, 1); argv[0] = (char*)transform_prog; argv[1] = (char*)"-cf"; @@ -59,9 +59,6 @@ int FAST_FUNC open_transformer(int src_fd, } /* parent process */ - close(fd_pipe.wr); /* Don't want to write to the child */ - -//TODO: get rid of return value (become void)? - xmove_fd(fd_pipe.rd, src_fd); - return src_fd; + close(fd_pipe.wr); /* don't want to write to the child */ + xmove_fd(fd_pipe.rd, fd); } diff --git a/archival/rpm.c b/archival/rpm.c index b3d7cd5f7..e6dd3d853 100644 --- a/archival/rpm.c +++ b/archival/rpm.c @@ -236,7 +236,7 @@ static void extract_cpio_gz(int fd) } xchdir("/"); /* Install RPM's to root */ - archive_handle->src_fd = open_transformer(archive_handle->src_fd, xformer, xformer_prog); + open_transformer(archive_handle->src_fd, xformer, xformer_prog); archive_handle->offset = 0; while (get_header_cpio(archive_handle) == EXIT_SUCCESS) continue; diff --git a/archival/tar.c b/archival/tar.c index 13cdbd930..a46442f8e 100644 --- a/archival/tar.c +++ b/archival/tar.c @@ -692,7 +692,7 @@ static char FAST_FUNC get_header_tar_Z(archive_handle_t *archive_handle) bb_error_msg_and_die("invalid magic"); } - archive_handle->src_fd = open_transformer(archive_handle->src_fd, uncompress, "uncompress"); + open_transformer(archive_handle->src_fd, uncompress, "uncompress"); archive_handle->offset = 0; while (get_header_tar(archive_handle) == EXIT_SUCCESS) continue; diff --git a/include/libbb.h b/include/libbb.h index 2dfdded5b..671584b43 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -583,15 +583,18 @@ extern unsigned char xread_char(int fd) FAST_FUNC; // Reads one line a-la fgets (but doesn't save terminating '\n'). // Uses single full_read() call, works only on seekable streams. extern char *reads(int fd, char *buf, size_t count) FAST_FUNC; +extern ssize_t read_close(int fd, void *buf, size_t maxsz) FAST_FUNC; +extern ssize_t open_read_close(const char *filename, void *buf, size_t maxsz) FAST_FUNC; // Reads one line a-la fgets (but doesn't save terminating '\n'). // Reads byte-by-byte. Useful when it is important to not read ahead. // Bytes are appended to pfx (which must be malloced, or NULL). extern char *xmalloc_reads(int fd, char *pfx, size_t *maxsz_p) FAST_FUNC; -extern ssize_t read_close(int fd, void *buf, size_t maxsz) FAST_FUNC; -extern ssize_t open_read_close(const char *filename, void *buf, size_t maxsz) FAST_FUNC; -extern void *xmalloc_read(int fd, size_t *sizep) FAST_FUNC; +/* Reads block up to *maxsz_p (default: MAX_INT(ssize_t)) */ +extern void *xmalloc_read(int fd, size_t *maxsz_p) FAST_FUNC; /* Returns NULL if file can't be opened */ extern void *xmalloc_open_read_close(const char *filename, size_t *maxsz_p) FAST_FUNC; +/* Autodetects .gz etc */ +extern void *xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_p) FAST_FUNC; /* Never returns NULL */ extern void *xmalloc_xopen_read_close(const char *filename, size_t *maxsz_p) FAST_FUNC; diff --git a/include/unarchive.h b/include/unarchive.h index 1fab570c3..0e380db08 100644 --- a/include/unarchive.h +++ b/include/unarchive.h @@ -126,12 +126,12 @@ extern USE_DESKTOP(long long) int unpack_gz_stream(int src_fd, int dst_fd) FAST_ extern USE_DESKTOP(long long) int unpack_lzma_stream(int src_fd, int dst_fd) FAST_FUNC; #if BB_MMU -extern int open_transformer(int src_fd, +extern void open_transformer(int fd, USE_DESKTOP(long long) int FAST_FUNC (*transformer)(int src_fd, int dst_fd)) FAST_FUNC; -#define open_transformer(src_fd, transformer, transform_prog) open_transformer(src_fd, transformer) +#define open_transformer(fd, transformer, transform_prog) open_transformer(fd, transformer) #else extern int open_transformer(int src_fd, const char *transform_prog) FAST_FUNC; -#define open_transformer(src_fd, transformer, transform_prog) open_transformer(src_fd, transform_prog) +#define open_transformer(fd, transformer, transform_prog) open_transformer(fd, transform_prog) #endif #if __GNUC_PREREQ(4,1) diff --git a/libbb/read.c b/libbb/read.c index e67bbfb7e..7af895207 100644 --- a/libbb/read.c +++ b/libbb/read.c @@ -8,6 +8,9 @@ */ #include "libbb.h" +#if ENABLE_FEATURE_MODPROBE_SMALL_ZIPPED +#include "unarchive.h" +#endif ssize_t FAST_FUNC safe_read(int fd, void *buf, size_t count) { @@ -206,14 +209,14 @@ ssize_t FAST_FUNC open_read_close(const char *filename, void *buf, size_t size) // Read (potentially big) files in one go. File size is estimated // by stat. Extra '\0' byte is appended. -void* FAST_FUNC xmalloc_read(int fd, size_t *sizep) +void* FAST_FUNC xmalloc_read(int fd, size_t *maxsz_p) { char *buf; size_t size, rd_size, total; - off_t to_read; + size_t to_read; struct stat st; - to_read = sizep ? *sizep : MAXINT(ssize_t); /* max to read */ + to_read = maxsz_p ? *maxsz_p : MAXINT(ssize_t); /* max to read */ /* Estimate file size */ st.st_size = 0; /* in case fstat fails, assume 0 */ @@ -229,16 +232,16 @@ void* FAST_FUNC xmalloc_read(int fd, size_t *sizep) size = to_read; buf = xrealloc(buf, total + size + 1); rd_size = full_read(fd, buf + total, size); - if ((ssize_t)rd_size < 0) { /* error */ + if ((ssize_t)rd_size == (ssize_t)(-1)) { /* error */ free(buf); return NULL; } total += rd_size; if (rd_size < size) /* EOF */ break; - to_read -= rd_size; - if (to_read <= 0) + if (to_read <= rd_size) break; + to_read -= rd_size; /* grow by 1/8, but in [1k..64k] bounds */ size = ((total / 8) | 0x3ff) + 1; if (size > 64*1024) @@ -247,8 +250,8 @@ void* FAST_FUNC xmalloc_read(int fd, size_t *sizep) xrealloc(buf, total + 1); buf[total] = '\0'; - if (sizep) - *sizep = total; + if (maxsz_p) + *maxsz_p = total; return buf; } @@ -260,7 +263,7 @@ void* FAST_FUNC xmalloc_read(int fd, size_t *sizep) // Read (potentially big) files in one go. File size is estimated by // lseek to end. -void* FAST_FUNC xmalloc_open_read_close(const char *filename, size_t *sizep) +void* FAST_FUNC xmalloc_open_read_close(const char *filename, size_t *maxsz_p) { char *buf; size_t size; @@ -277,7 +280,7 @@ void* FAST_FUNC xmalloc_open_read_close(const char *filename, size_t *sizep) len = lseek(fd, 0, SEEK_END) | 0x3ff; /* + up to 1k */ if (len != (off_t)-1) { xlseek(fd, 0, SEEK_SET); - size = sizep ? *sizep : INT_MAX; + size = maxsz_p ? *maxsz_p : INT_MAX; if (len < size) size = len; } @@ -291,15 +294,15 @@ void* FAST_FUNC xmalloc_open_read_close(const char *filename, size_t *sizep) xrealloc(buf, size + 1); buf[size] = '\0'; - if (sizep) - *sizep = size; + if (maxsz_p) + *maxsz_p = size; return buf; } #endif // Read (potentially big) files in one go. File size is estimated // by stat. -void* FAST_FUNC xmalloc_open_read_close(const char *filename, size_t *sizep) +void* FAST_FUNC xmalloc_open_read_close(const char *filename, size_t *maxsz_p) { char *buf; int fd; @@ -308,15 +311,42 @@ void* FAST_FUNC xmalloc_open_read_close(const char *filename, size_t *sizep) if (fd < 0) return NULL; - buf = xmalloc_read(fd, sizep); + buf = xmalloc_read(fd, maxsz_p); close(fd); return buf; } -void* FAST_FUNC xmalloc_xopen_read_close(const char *filename, size_t *sizep) +void* FAST_FUNC xmalloc_xopen_read_close(const char *filename, size_t *maxsz_p) { - void *buf = xmalloc_open_read_close(filename, sizep); + void *buf = xmalloc_open_read_close(filename, maxsz_p); if (!buf) bb_perror_msg_and_die("can't read '%s'", filename); return buf; } + +#if ENABLE_FEATURE_MODPROBE_SMALL_ZIPPED +void* FAST_FUNC xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_p) +{ + char *image; + char *suffix; + + int fd = open(fname, O_RDONLY); + if (fd < 0) + return NULL; + + suffix = strrchr(fname, '.'); + if (suffix) { + if (strcmp(suffix, ".gz") == 0) + open_transformer(fd, unpack_gz_stream, "gunzip"); + else if (strcmp(suffix, ".bz2") == 0) + open_transformer(fd, unpack_bz2_stream, "bunzip2"); + } + + image = xmalloc_read(fd, maxsz_p); + if (!image) + bb_perror_msg("read error from '%s'", fname); + close(fd); + + return image; +} +#endif diff --git a/modutils/modprobe-small.c b/modutils/modprobe-small.c index f28c42558..517c103d5 100644 --- a/modutils/modprobe-small.c +++ b/modutils/modprobe-small.c @@ -143,34 +143,6 @@ static char* str_2_list(const char *str) } #if ENABLE_FEATURE_MODPROBE_SMALL_ZIPPED -static char *xmalloc_open_zipped_read_close(const char *fname, size_t *sizep) -{ - size_t len; - char *image; - char *suffix; - - int fd = open_or_warn(fname, O_RDONLY); - if (fd < 0) - return NULL; - - suffix = strrchr(fname, '.'); - if (suffix) { - if (strcmp(suffix, ".gz") == 0) - fd = open_transformer(fd, unpack_gz_stream, "gunzip"); - else if (strcmp(suffix, ".bz2") == 0) - fd = open_transformer(fd, unpack_bz2_stream, "bunzip2"); - } - - len = (sizep) ? *sizep : 64 * 1024 * 1024; - image = xmalloc_read(fd, &len); - if (!image) - bb_perror_msg("read error from '%s'", fname); - close(fd); - - if (sizep) - *sizep = len; - return image; -} # define read_module xmalloc_open_zipped_read_close #else # define read_module xmalloc_open_read_close