]> granicus.if.org Git - file/commitdiff
don't use uncompress anymore because it gets stuck.
authorChristos Zoulas <christos@zoulas.com>
Sat, 17 Mar 2001 20:03:26 +0000 (20:03 +0000)
committerChristos Zoulas <christos@zoulas.com>
Sat, 17 Mar 2001 20:03:26 +0000 (20:03 +0000)
use safe read and write and handle errors better.

src/compress.c

index 5f18d8289fdde5fc3d49ce507dbe8281407416cc..31208ea6e9f3df289a0440a9fafa1f0ba7252c30 100644 (file)
@@ -16,7 +16,7 @@
 #include <sys/wait.h>
 #endif
 #ifndef lint
-FILE_RCSID("@(#)$Id: compress.c,v 1.17 2000/08/05 17:36:47 christos Exp $")
+FILE_RCSID("@(#)$Id: compress.c,v 1.18 2001/03/17 20:03:26 christos Exp $")
 #endif
 
 
@@ -26,7 +26,10 @@ static struct {
        const char *const argv[3];
        int      silent;
 } compr[] = {
-       { "\037\235", 2, { "uncompress", "-c", NULL }, 0 },     /* compressed */
+#if 0
+       /* We don't use uncompress anymore because it gets stuck */
+       { "\037\235", 2, { "uncompress", "-c", NULL }, 1 },     /* compressed */
+#endif
        { "\037\235", 2, { "gzip", "-cdq", NULL }, 1 },         /* compressed */
        { "\037\213", 2, { "gzip", "-cdq", NULL }, 1 },         /* gzipped */
        { "\037\236", 2, { "gzip", "-cdq", NULL }, 1 },         /* frozen */
@@ -40,6 +43,8 @@ static int ncompr = sizeof(compr) / sizeof(compr[0]);
 
 
 static int uncompress __P((int, const unsigned char *, unsigned char **, int));
+static int swrite __P((int, const void *, size_t));
+static int sread __P((int, void *, size_t));
 
 int
 zmagic(buf, nbytes)
@@ -70,6 +75,60 @@ zmagic(buf, nbytes)
        return 1;
 }
 
+/*
+ * `safe' write for sockets and pipes.
+ */
+static int
+swrite(fd, buf, n)
+       int fd;
+       const void *buf;
+       size_t n;
+{
+       int rv;
+       size_t rn = n;
+
+       do
+               switch (rv = write(fd, buf, n)) {
+               case -1:
+                       if (errno == EINTR)
+                               continue;
+                       return -1;
+               default:
+                       n -= rv;
+                       buf = ((char *)buf) + rv;
+                       break;
+               }
+       while (n > 0);
+       return rn;
+}
+
+
+/*
+ * `safe' read for sockets and pipes.
+ */
+static int
+sread(fd, buf, n)
+       int fd;
+       void *buf;
+       size_t n;
+{
+       int rv;
+       size_t rn = n;
+
+       do
+               switch (rv = read(fd, buf, n)) {
+               case -1:
+                       if (errno == EINTR)
+                               continue;
+                       return -1;
+               default:
+                       n -= rv;
+                       buf = ((char *)buf) + rv;
+                       break;
+               }
+       while (n > 0);
+       return rn;
+}
 
 static int
 uncompress(method, old, newch, n)
@@ -109,15 +168,24 @@ uncompress(method, old, newch, n)
        default: /* parent */
                (void) close(fdin[0]);
                (void) close(fdout[1]);
-               if (write(fdin[1], old, n) != n)
-                       return 0;
+               if (swrite(fdin[1], old, n) != n) {
+                       n = 0;
+                       goto err;
+               }
                (void) close(fdin[1]);
-               if ((*newch = (unsigned char *) malloc(n)) == NULL)
-                       return 0;
-               if ((n = read(fdout[0], *newch, n)) <= 0) {
+               fdin[1] = -1;
+               if ((*newch = (unsigned char *) malloc(n)) == NULL) {
+                       n = 0;
+                       goto err;
+               }
+               if ((n = sread(fdout[0], *newch, n)) <= 0) {
                        free(*newch);
-                       return 0;
+                       n = 0;
+                       goto err;
                }
+err:
+               if (fdin[1] != -1)
+                       (void) close(fdin[1]);
                (void) close(fdout[0]);
                (void) wait(NULL);
                return n;