libbb/archival: make setup_unzip_on_fd() return bytes read if not compressed

setup_unzip_on_fd() does not return the transformer structure, so the user
does not know how much to seek back (or alternatively what the signature was)
when compressor signature is not detected.

Currently not needed (the only user is tar which dies anyway).
However, rpm2cpio may need this if we extend it to extract the internal .cpio
even if cpio's compressions algo is not known.

function                                             old     new   delta
setup_unzip_on_fd                                     53      59      +6

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2025-04-20 23:43:19 +02:00
parent 636315ccb9
commit c61fdadf97
7 changed files with 25 additions and 23 deletions

View file

@ -71,8 +71,8 @@ int FAST_FUNC bbunpack(char **argv,
goto err; goto err;
} else { } else {
/* "clever zcat" with FILE */ /* "clever zcat" with FILE */
/* fail_if_not_compressed because zcat refuses uncompressed input */ /* die_if_not_compressed because zcat refuses uncompressed input */
int fd = open_zipped(filename, /*fail_if_not_compressed:*/ 1); int fd = open_zipped(filename, /*die_if_not_compressed:*/ 1);
if (fd < 0) if (fd < 0)
goto err_name; goto err_name;
xmove_fd(fd, STDIN_FILENO); xmove_fd(fd, STDIN_FILENO);
@ -80,7 +80,7 @@ int FAST_FUNC bbunpack(char **argv,
} else } else
if (option_mask32 & BBUNPK_SEAMLESS_MAGIC) { if (option_mask32 & BBUNPK_SEAMLESS_MAGIC) {
/* "clever zcat" on stdin */ /* "clever zcat" on stdin */
if (setup_unzip_on_fd(STDIN_FILENO, /*fail_if_not_compressed*/ 1)) if (setup_unzip_on_fd(STDIN_FILENO, /*die_if_not_compressed*/ 1))
goto err; goto err;
} }

View file

@ -157,7 +157,7 @@ void FAST_FUNC fork_transformer(int fd, const char *transform_prog)
/* Used by e.g. rpm which gives us a fd without filename, /* Used by e.g. rpm which gives us a fd without filename,
* thus we can't guess the format from filename's extension. * thus we can't guess the format from filename's extension.
*/ */
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 die_if_not_compressed)
{ {
transformer_state_t *xstate; transformer_state_t *xstate;
@ -204,7 +204,7 @@ static transformer_state_t *setup_transformer_on_fd(int fd, int fail_if_not_comp
} }
/* No known magic seen */ /* No known magic seen */
if (fail_if_not_compressed) if (die_if_not_compressed)
bb_simple_error_msg_and_die("no gzip" bb_simple_error_msg_and_die("no gzip"
IF_FEATURE_SEAMLESS_BZ2("/bzip2") IF_FEATURE_SEAMLESS_BZ2("/bzip2")
IF_FEATURE_SEAMLESS_XZ("/xz") IF_FEATURE_SEAMLESS_XZ("/xz")
@ -240,13 +240,15 @@ static void fork_transformer_and_free(transformer_state_t *xstate)
/* Used by e.g. rpm which gives us a fd without filename, /* Used by e.g. rpm which gives us a fd without filename,
* thus we can't guess the format from filename's extension. * thus we can't guess the format from filename's extension.
*/ */
int FAST_FUNC setup_unzip_on_fd(int fd, int fail_if_not_compressed) int FAST_FUNC setup_unzip_on_fd(int fd, int die_if_not_compressed)
{ {
transformer_state_t *xstate = setup_transformer_on_fd(fd, fail_if_not_compressed); transformer_state_t *xstate = setup_transformer_on_fd(fd, die_if_not_compressed);
if (!xstate->xformer) { if (!xstate->xformer) {
/* Not compressed */
int retval = xstate->signature_skipped; /* never zero */
free(xstate); free(xstate);
return 1; return retval;
} }
fork_transformer_and_free(xstate); fork_transformer_and_free(xstate);
@ -264,7 +266,7 @@ void FAST_FUNC setup_lzma_on_fd(int fd)
} }
#endif #endif
static transformer_state_t *open_transformer(const char *fname, int fail_if_not_compressed) static transformer_state_t *open_transformer(const char *fname, int die_if_not_compressed)
{ {
transformer_state_t *xstate; transformer_state_t *xstate;
int fd; int fd;
@ -284,18 +286,18 @@ static transformer_state_t *open_transformer(const char *fname, int fail_if_not_
} }
} }
xstate = setup_transformer_on_fd(fd, fail_if_not_compressed); xstate = setup_transformer_on_fd(fd, die_if_not_compressed);
return xstate; return xstate;
} }
int FAST_FUNC open_zipped(const char *fname, int fail_if_not_compressed) int FAST_FUNC open_zipped(const char *fname, int die_if_not_compressed)
{ {
int fd; int fd;
transformer_state_t *xstate; transformer_state_t *xstate;
xstate = open_transformer(fname, fail_if_not_compressed); xstate = open_transformer(fname, die_if_not_compressed);
if (!xstate) if (!xstate) /* open error */
return -1; return -1;
fd = xstate->src_fd; fd = xstate->src_fd;
@ -326,7 +328,7 @@ void* FAST_FUNC xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_
transformer_state_t *xstate; transformer_state_t *xstate;
char *image; char *image;
xstate = open_transformer(fname, /*fail_if_not_compressed:*/ 0); xstate = open_transformer(fname, /*die_if_not_compressed:*/ 0);
if (!xstate) /* file open error */ if (!xstate) /* file open error */
return NULL; return NULL;
@ -371,7 +373,7 @@ void* FAST_FUNC xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_
int fd; int fd;
char *image; char *image;
fd = open_zipped(fname, /*fail_if_not_compressed:*/ 0); fd = open_zipped(fname, /*die_if_not_compressed:*/ 0);
if (fd < 0) if (fd < 0)
return NULL; return NULL;

View file

@ -316,7 +316,7 @@ static void extract_cpio(int fd, const char *source_rpm)
archive_handle->src_fd = fd; archive_handle->src_fd = fd;
/*archive_handle->offset = 0; - init_handle() did it */ /*archive_handle->offset = 0; - init_handle() did it */
setup_unzip_on_fd(archive_handle->src_fd, /*fail_if_not_compressed:*/ 1); setup_unzip_on_fd(archive_handle->src_fd, /*die_if_not_compressed:*/ 1);
while (get_header_cpio(archive_handle) == EXIT_SUCCESS) while (get_header_cpio(archive_handle) == EXIT_SUCCESS)
continue; continue;
} }
@ -541,7 +541,7 @@ int rpm2cpio_main(int argc UNUSED_PARAM, char **argv)
// set up decompressor without detection // set up decompressor without detection
setup_lzma_on_fd(rpm_fd); setup_lzma_on_fd(rpm_fd);
} else { } else {
setup_unzip_on_fd(rpm_fd, /*fail_if_not_compressed:*/ 1); setup_unzip_on_fd(rpm_fd, /*die_if_not_compressed:*/ 1);
} }
if (bb_copyfd_eof(rpm_fd, STDOUT_FILENO) < 0) if (bb_copyfd_eof(rpm_fd, STDOUT_FILENO) < 0)

View file

@ -1164,7 +1164,7 @@ int tar_main(int argc UNUSED_PARAM, char **argv)
* on e.g. tarball with 1st file named "BZh5". * on e.g. tarball with 1st file named "BZh5".
*/ */
) { ) {
tar_handle->src_fd = open_zipped(tar_filename, /*fail_if_not_compressed:*/ 0); tar_handle->src_fd = open_zipped(tar_filename, /*die_if_not_compressed:*/ 0);
if (tar_handle->src_fd < 0) if (tar_handle->src_fd < 0)
bb_perror_msg_and_die("can't open '%s'", tar_filename); bb_perror_msg_and_die("can't open '%s'", tar_filename);
} else { } else {

View file

@ -1011,13 +1011,13 @@ unsigned bb_clk_tck(void) FAST_FUNC;
#if SEAMLESS_COMPRESSION #if SEAMLESS_COMPRESSION
/* Autodetects gzip/bzip2 formats. fd may be in the middle of the file! */ /* Autodetects gzip/bzip2 formats. fd may be in the middle of the file! */
int setup_unzip_on_fd(int fd, int fail_if_not_compressed) FAST_FUNC; int setup_unzip_on_fd(int fd, int die_if_not_compressed) FAST_FUNC;
/* Autodetects .gz etc */ /* Autodetects .gz etc */
extern int open_zipped(const char *fname, int fail_if_not_compressed) FAST_FUNC; extern int open_zipped(const char *fname, int die_if_not_compressed) FAST_FUNC;
extern void *xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC; extern void *xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC;
#else #else
# define setup_unzip_on_fd(...) (0) # define setup_unzip_on_fd(...) (0)
# define open_zipped(fname, fail_if_not_compressed) open((fname), O_RDONLY); # define open_zipped(fname, die_if_not_compressed) open((fname), O_RDONLY);
# define xmalloc_open_zipped_read_close(fname, maxsz_p) xmalloc_open_read_close((fname), (maxsz_p)) # define xmalloc_open_zipped_read_close(fname, maxsz_p) xmalloc_open_read_close((fname), (maxsz_p))
#endif #endif
/* lzma has no signature, need a little helper. NB: exist only for ENABLE_FEATURE_SEAMLESS_LZMA=y */ /* lzma has no signature, need a little helper. NB: exist only for ENABLE_FEATURE_SEAMLESS_LZMA=y */

View file

@ -382,7 +382,7 @@ static void fb_drawimage(void)
if (LONE_DASH(G.image_filename)) { if (LONE_DASH(G.image_filename)) {
theme_file = stdin; theme_file = stdin;
} else { } else {
int fd = open_zipped(G.image_filename, /*fail_if_not_compressed:*/ 0); int fd = open_zipped(G.image_filename, /*die_if_not_compressed:*/ 0);
if (fd < 0) if (fd < 0)
bb_simple_perror_msg_and_die(G.image_filename); bb_simple_perror_msg_and_die(G.image_filename);
theme_file = xfdopen_for_read(fd); theme_file = xfdopen_for_read(fd);

View file

@ -143,7 +143,7 @@ static int run_pipe(char *man_filename, int man, int level)
ordinary_manpage: ordinary_manpage:
close(STDIN_FILENO); close(STDIN_FILENO);
open_zipped(man_filename, /*fail_if_not_compressed:*/ 0); /* guaranteed to use fd 0 (STDIN_FILENO) */ open_zipped(man_filename, /*die_if_not_compressed:*/ 0); /* guaranteed to use fd 0 (STDIN_FILENO) */
if (man) { if (man) {
int w = get_terminal_width(-1); int w = get_terminal_width(-1);
if (w > 10) if (w > 10)