summaryrefslogtreecommitdiffstats
path: root/contrib/file/compress.c
diff options
context:
space:
mode:
authorobrien <obrien@FreeBSD.org>2001-04-25 07:41:21 +0000
committerobrien <obrien@FreeBSD.org>2001-04-25 07:41:21 +0000
commit30980cd72da9ade33a9b331e58e75660d180a109 (patch)
tree000ebc599c417e0830db5f66711d1e99a3edfdcb /contrib/file/compress.c
parentfd87285c4e3e4e4fbf7112229c209a1c6ea64494 (diff)
downloadFreeBSD-src-30980cd72da9ade33a9b331e58e75660d180a109.zip
FreeBSD-src-30980cd72da9ade33a9b331e58e75660d180a109.tar.gz
Virgin import of Christos Zoulas's FILE 3.35.
Diffstat (limited to 'contrib/file/compress.c')
-rw-r--r--contrib/file/compress.c83
1 files changed, 75 insertions, 8 deletions
diff --git a/contrib/file/compress.c b/contrib/file/compress.c
index 5f18d82..e84d62d 100644
--- a/contrib/file/compress.c
+++ b/contrib/file/compress.c
@@ -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.19 2001/03/20 04:22:02 christos Exp $")
#endif
@@ -26,8 +26,10 @@ static struct {
const char *const argv[3];
int silent;
} compr[] = {
- { "\037\235", 2, { "uncompress", "-c", NULL }, 0 }, /* compressed */
{ "\037\235", 2, { "gzip", "-cdq", NULL }, 1 }, /* compressed */
+ /* Uncompress can get stuck; so use gzip first if we have it
+ * Idea from Damien Clark, thanks! */
+ { "\037\235", 2, { "uncompress", "-c", NULL }, 1 }, /* compressed */
{ "\037\213", 2, { "gzip", "-cdq", NULL }, 1 }, /* gzipped */
{ "\037\236", 2, { "gzip", "-cdq", NULL }, 1 }, /* frozen */
{ "\037\240", 2, { "gzip", "-cdq", NULL }, 1 }, /* SCO LZH */
@@ -40,6 +42,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 +74,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 +167,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;
OpenPOWER on IntegriCloud