Check the unzip child process for errors and pass the upwards. Also, avoid child...
authorgraham.gower <graham.gower@e8e0d7a0-c8d9-11dd-a880-a1081c7ac358>
Fri, 27 Nov 2009 01:22:10 +0000 (01:22 +0000)
committergraham.gower <graham.gower@e8e0d7a0-c8d9-11dd-a880-a1081c7ac358>
Fri, 27 Nov 2009 01:22:10 +0000 (01:22 +0000)
git-svn-id: http://opkg.googlecode.com/svn/trunk@392 e8e0d7a0-c8d9-11dd-a880-a1081c7ac358

libbb/gz_open.c
libbb/libbb.h
libbb/unarchive.c
libbb/unzip.c

index f9ee8c10b53cdde04f2475316b17ae7872afe972..3d07b58ab8d87bd33608bf33b68b11b087868fba 100644 (file)
@@ -29,7 +29,8 @@
 #include <unistd.h>
 #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;
 }
index 879786ebae3aceab607082d02c9af428fdadd815..17f3c25cf905ab581b72e2752bff1d5872dd2908 100644 (file)
@@ -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);
index 3108f37bae03b2a55bd915451ec302bca86b5c52..c3630b070960c0516785c165c4634f588d716d9e 100644 (file)
@@ -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 {
index 186da594a45c8fff04bb3748fbd769cf391615a1..7ff07a515364745fecd233dc6cc14474b2d16841 100644 (file)
@@ -46,6 +46,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <errno.h>
 #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;