From 8fdd042394b7395c13bee66afb45dd3875c60c63 Mon Sep 17 00:00:00 2001 From: graham.gower Date: Thu, 26 Nov 2009 20:22:10 -0500 Subject: Check the unzip child process for errors and pass the upwards. Also, avoid child from being killed by SIGPIPE. git-svn-id: http://opkg.googlecode.com/svn/trunk@392 e8e0d7a0-c8d9-11dd-a880-a1081c7ac358 --- diff --git a/libbb/gz_open.c b/libbb/gz_open.c index f9ee8c1..3d07b58 100644 --- a/libbb/gz_open.c +++ b/libbb/gz_open.c @@ -29,7 +29,8 @@ #include #include "libbb.h" -extern FILE *gz_open(FILE *compressed_file, int *pid) +FILE * +gz_open(FILE *compressed_file, int *pid) { int unzip_pipe[2]; @@ -54,9 +55,35 @@ extern FILE *gz_open(FILE *compressed_file, int *pid) return(fdopen(unzip_pipe[0], "r")); } -extern void gz_close(int gunzip_pid) +int +gz_close(int gunzip_pid) { - if (waitpid(gunzip_pid, NULL, 0) == -1) { - perror_msg("%s wait", __FUNCTION__); + int status; + int ret; + + if (waitpid(gunzip_pid, &status, 0) == -1) { + perror_msg("%s: waitpid", __FUNCTION__); + return -1; + } + + if (WIFSIGNALED(status)) { + error_msg("%s: unzip process killed by signal %d\n", + __FUNCTION__, WTERMSIG(status)); + return -1; + } + + if (!WIFEXITED(status)) { + /* shouldn't happen */ + error_msg("%s: Your system is broken: got status %d from waitpid\n", + __FUNCTION__, status); + return -1; } + + if ((ret = WEXITSTATUS(status))) { + error_msg("%s: unzip process failed with return code %d.\n", + __FUNCTION__, ret); + return -1; + } + + return 0; } diff --git a/libbb/libbb.h b/libbb/libbb.h index 879786e..17f3c25 100644 --- a/libbb/libbb.h +++ b/libbb/libbb.h @@ -98,7 +98,7 @@ char *deb_extract(const char *package_filename, FILE *out_stream, const char *filename, int *err); extern int unzip(FILE *l_in_file, FILE *l_out_file); -extern void gz_close(int gunzip_pid); +extern int gz_close(int gunzip_pid); extern FILE *gz_open(FILE *compressed_file, int *pid); int make_directory (const char *path, long mode, int flags); diff --git a/libbb/unarchive.c b/libbb/unarchive.c index 3108f37..c3630b0 100644 --- a/libbb/unarchive.c +++ b/libbb/unarchive.c @@ -624,6 +624,7 @@ deb_extract(const char *package_filename, FILE *out_stream, char *output_buffer = NULL; char *ared_file = NULL; char ar_magic[8]; + int gz_err; *err = 0; @@ -678,7 +679,9 @@ deb_extract(const char *package_filename, FILE *out_stream, extract_function, prefix, file_list, err); fclose(uncompressed_stream); - gz_close(gunzip_pid); + gz_err = gz_close(gunzip_pid); + if (gz_err) + *err = -1; free_header_ar(ar_header); break; } @@ -726,7 +729,9 @@ deb_extract(const char *package_filename, FILE *out_stream, free_header_tar(tar_header); fclose(uncompressed_stream); - gz_close(gunzip_pid); + gz_err = gz_close(gunzip_pid); + if (gz_err) + *err = -1; free_header_tar(tar_header); break; } @@ -734,7 +739,9 @@ deb_extract(const char *package_filename, FILE *out_stream, free_header_tar(tar_header); } fclose(unzipped_opkg_stream); - gz_close(unzipped_opkg_pid); + gz_err = gz_close(unzipped_opkg_pid); + if (gz_err) + *err = -1; goto cleanup; } else { diff --git a/libbb/unzip.c b/libbb/unzip.c index 186da59..7ff07a5 100644 --- a/libbb/unzip.c +++ b/libbb/unzip.c @@ -46,6 +46,7 @@ #include #include #include +#include #include "libbb.h" static FILE *in_file, *out_file; @@ -149,6 +150,14 @@ static void flush_window(void) } if (fwrite(window, 1, outcnt, out_file) != outcnt) { + /* + * The Parent process may not be interested in all the data we have, + * in which case it will rudely close its end of the pipe and + * wait for us to exit. + */ + if (errno == EPIPE) + _exit(EXIT_SUCCESS); + error_msg("Couldnt write"); _exit(EXIT_FAILURE); } @@ -917,6 +926,8 @@ extern int unzip(FILE *l_in_file, FILE *l_out_file) } #endif + signal(SIGPIPE, SIG_IGN); + /* Allocate all global buffers (for DYN_ALLOC option) */ window = xmalloc((size_t)(((2L*WSIZE)+1L)*sizeof(unsigned char))); outcnt = 0; -- cgit v0.9.1