2 * Copyright (c) Ian F. Darwin 1986-1995.
3 * Software written by Ian F. Darwin and others;
4 * maintained 1995-present by Christos Zoulas and others.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice immediately at the beginning of the file, without modification,
11 * this list of conditions, and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * zmagic() - returns 0 if not recognized, uncompresses and prints
31 * information if recognized
32 * uncompress(method, old, n, newch) - uncompress old into new,
33 * using method, return sizeof new
38 FILE_RCSID("@(#)$File: compress.c,v 1.136 2022/09/13 16:08:34 christos Exp $")
55 typedef void (*sig_t
)(int);
56 #endif /* HAVE_SIG_T */
57 #ifdef HAVE_SYS_IOCTL_H
58 #include <sys/ioctl.h>
60 #ifdef HAVE_SYS_WAIT_H
63 #if defined(HAVE_SYS_TIME_H)
67 #if defined(HAVE_ZLIB_H) && defined(ZLIBSUPPORT)
68 #define BUILTIN_DECOMPRESS
72 #if defined(HAVE_BZLIB_H) && defined(BZLIBSUPPORT)
77 #if defined(HAVE_LZMA_H) && defined(XZLIBSUPPORT)
84 #define DPRINTF(...) do { \
86 tty = open("/dev/tty", O_RDWR); \
89 dprintf(tty, __VA_ARGS__); \
90 } while (/*CONSTCOND*/0)
97 * The following python code is not really used because ZLIBSUPPORT is only
98 * defined if we have a built-in zlib, and the built-in zlib handles that.
99 * That is not true for android where we have zlib.h and not -lz.
101 static const char zlibcode
[] =
102 "import sys, zlib; sys.stdout.write(zlib.decompress(sys.stdin.read()))";
104 static const char *zlib_args
[] = { "python", "-c", zlibcode
, NULL
};
107 zlibcmp(const unsigned char *buf
)
109 unsigned short x
= 1;
110 unsigned char *s
= CAST(unsigned char *, CAST(void *, &x
));
112 if ((buf
[0] & 0xf) != 8 || (buf
[0] & 0x80) != 0)
114 if (s
[0] != 1) /* endianness test */
115 x
= buf
[0] | (buf
[1] << 8);
117 x
= buf
[1] | (buf
[0] << 8);
125 lzmacmp(const unsigned char *buf
)
127 if (buf
[0] != 0x5d || buf
[1] || buf
[2])
129 if (buf
[12] && buf
[12] != 0xff)
134 #define gzip_flags "-cd"
135 #define lrzip_flags "-do"
136 #define lzip_flags gzip_flags
138 static const char *gzip_args
[] = {
139 "gzip", gzip_flags
, NULL
141 static const char *uncompress_args
[] = {
142 "uncompress", "-c", NULL
144 static const char *bzip2_args
[] = {
147 static const char *lzip_args
[] = {
148 "lzip", lzip_flags
, NULL
150 static const char *xz_args
[] = {
153 static const char *lrzip_args
[] = {
154 "lrzip", lrzip_flags
, NULL
156 static const char *lz4_args
[] = {
159 static const char *zstd_args
[] = {
164 #define do_bzlib NULL
166 private const struct {
169 int (*func
)(const unsigned char *);
175 #define METH_FROZEN 2
180 { { .magic
= "\037\235" }, 2, gzip_args
, NULL
}, /* 0, compressed */
181 /* Uncompress can get stuck; so use gzip first if we have it
182 * Idea from Damien Clark, thanks! */
183 { { .magic
= "\037\235" }, 2, uncompress_args
, NULL
},/* 1, compressed */
184 { { .magic
= "\037\213" }, 2, gzip_args
, do_zlib
},/* 2, gzipped */
185 { { .magic
= "\037\236" }, 2, gzip_args
, NULL
}, /* 3, frozen */
186 { { .magic
= "\037\240" }, 2, gzip_args
, NULL
}, /* 4, SCO LZH */
187 /* the standard pack utilities do not accept standard input */
188 { { .magic
= "\037\036" }, 2, gzip_args
, NULL
}, /* 5, packed */
189 { { .magic
= "PK\3\4" }, 4, gzip_args
, NULL
}, /* 6, pkziped */
190 /* ...only first file examined */
191 { { .magic
= "BZh" }, 3, bzip2_args
, do_bzlib
},/* 7, bzip2-ed */
192 { { .magic
= "LZIP" }, 4, lzip_args
, NULL
}, /* 8, lzip-ed */
193 { { .magic
= "\3757zXZ\0" },6, xz_args
, NULL
}, /* 9, XZ Util */
194 { { .magic
= "LRZI" }, 4, lrzip_args
, NULL
}, /* 10, LRZIP */
195 { { .magic
= "\004\"M\030" },4, lz4_args
, NULL
}, /* 11, LZ4 */
196 { { .magic
= "\x28\xB5\x2F\xFD" }, 4, zstd_args
, NULL
},/* 12, zstd */
197 { { .func
= lzmacmp
}, -13, xz_args
, NULL
}, /* 13, lzma */
199 { { .func
= zlibcmp
}, -2, zlib_args
, NULL
}, /* 14, zlib */
207 private ssize_t
swrite(int, const void *, size_t);
209 private size_t ncompr
= __arraycount(compr
);
210 private int uncompressbuf(int, size_t, size_t, const unsigned char *,
211 unsigned char **, size_t *);
212 #ifdef BUILTIN_DECOMPRESS
213 private int uncompresszlib(const unsigned char *, unsigned char **, size_t,
215 private int uncompressgzipped(const unsigned char *, unsigned char **, size_t,
219 private int uncompressbzlib(const unsigned char *, unsigned char **, size_t,
223 private int uncompressxzlib(const unsigned char *, unsigned char **, size_t,
227 static int makeerror(unsigned char **, size_t *, const char *, ...)
228 __attribute__((__format__(__printf__
, 3, 4)));
229 private const char *methodname(size_t);
232 format_decompression_error(struct magic_set
*ms
, size_t i
, unsigned char *buf
)
235 int mime
= ms
->flags
& MAGIC_MIME
;
238 return file_printf(ms
, "ERROR:[%s: %s]", methodname(i
), buf
);
240 for (p
= buf
; *p
; p
++)
244 return file_printf(ms
, "application/x-decompression-error-%s-%s",
249 file_zmagic(struct magic_set
*ms
, const struct buffer
*b
, const char *name
)
251 unsigned char *newbuf
= NULL
;
255 int urv
, prv
, rv
= 0;
256 int mime
= ms
->flags
& MAGIC_MIME
;
258 const unsigned char *buf
= CAST(const unsigned char *, b
->fbuf
);
259 size_t nbytes
= b
->flen
;
261 struct sigaction sig_act
;
263 if ((ms
->flags
& MAGIC_COMPRESS
) == 0)
266 for (i
= 0; i
< ncompr
; i
++) {
268 if (nbytes
< CAST(size_t, abs(compr
[i
].maglen
)))
270 if (compr
[i
].maglen
< 0) {
271 zm
= (*compr
[i
].u
.func
)(buf
);
273 zm
= memcmp(buf
, compr
[i
].u
.magic
,
274 CAST(size_t, compr
[i
].maglen
)) == 0;
280 /* Prevent SIGPIPE death if child dies unexpectedly */
282 //We can use sig_act for both new and old, but
283 struct sigaction new_act
;
284 memset(&new_act
, 0, sizeof(new_act
));
285 new_act
.sa_handler
= SIG_IGN
;
286 sa_saved
= sigaction(SIGPIPE
, &new_act
, &sig_act
) != -1;
290 urv
= uncompressbuf(fd
, ms
->bytes_max
, i
, buf
, &newbuf
, &nsz
);
291 DPRINTF("uncompressbuf = %d, %s, %" SIZE_T_FORMAT
"u\n", urv
,
292 (char *)newbuf
, nsz
);
296 ms
->flags
&= ~MAGIC_COMPRESS
;
298 prv
= format_decompression_error(ms
, i
, newbuf
);
300 prv
= file_buffer(ms
, -1, NULL
, name
, newbuf
, nsz
);
304 if ((ms
->flags
& MAGIC_COMPRESS_TRANSP
) != 0)
306 if (mime
!= MAGIC_MIME
&& mime
!= 0)
309 mime
? " compressed-encoding=" : " (")) == -1)
311 if ((pb
= file_push_buffer(ms
)) == NULL
)
314 * XXX: If file_buffer fails here, we overwrite
315 * the compressed text. FIXME.
317 if (file_buffer(ms
, -1, NULL
, NULL
, buf
, nbytes
) == -1) {
318 if (file_pop_buffer(ms
, pb
) != NULL
)
322 if ((rbuf
= file_pop_buffer(ms
, pb
)) != NULL
) {
323 if (file_printf(ms
, "%s", rbuf
) == -1) {
329 if (!mime
&& file_printf(ms
, ")") == -1)
343 DPRINTF("rv = %d\n", rv
);
345 if (sa_saved
&& sig_act
.sa_handler
!= SIG_IGN
)
346 (void)sigaction(SIGPIPE
, &sig_act
, NULL
);
349 ms
->flags
|= MAGIC_COMPRESS
;
350 DPRINTF("Zmagic returns %d\n", rv
);
355 * `safe' write for sockets and pipes.
358 swrite(int fd
, const void *buf
, size_t n
)
364 switch (rv
= write(fd
, buf
, n
)) {
371 buf
= CAST(const char *, buf
) + rv
;
380 * `safe' read for sockets and pipes.
383 sread(int fd
, void *buf
, size_t n
, int canbepipe
__attribute__((__unused__
)))
391 if (fd
== STDIN_FILENO
)
395 if (canbepipe
&& (ioctl(fd
, FIONREAD
, &t
) == -1 || t
== 0)) {
398 for (cnt
= 0;; cnt
++) {
400 struct timeval tout
= {0, 100 * 1000};
407 * Avoid soft deadlock: do not read if there
408 * is nothing to read from sockets and pipes.
410 selrv
= select(fd
+ 1, &check
, NULL
, NULL
, &tout
);
412 if (errno
== EINTR
|| errno
== EAGAIN
)
414 } else if (selrv
== 0 && cnt
>= 5) {
420 (void)ioctl(fd
, FIONREAD
, &t
);
423 if (t
> 0 && CAST(size_t, t
) < n
) {
431 switch ((rv
= read(fd
, buf
, n
))) {
440 buf
= CAST(char *, CCAST(void *, buf
)) + rv
;
448 file_pipe2file(struct magic_set
*ms
, int fd
, const void *startbuf
,
458 if ((t
= getenv("TEMP")) != NULL
)
459 (void)strlcpy(buf
, t
, sizeof(buf
));
460 else if ((t
= getenv("TMP")) != NULL
)
461 (void)strlcpy(buf
, t
, sizeof(buf
));
462 else if ((t
= getenv("TMPDIR")) != NULL
)
463 (void)strlcpy(buf
, t
, sizeof(buf
));
465 (void)strlcat(buf
, "/", sizeof(buf
));
466 (void)strlcat(buf
, "file.XXXXXX", sizeof(buf
));
468 (void)strlcpy(buf
, "/tmp/file.XXXXXX", sizeof(buf
));
472 char *ptr
= mktemp(buf
);
473 tfd
= open(ptr
, O_RDWR
|O_TRUNC
|O_EXCL
|O_CREAT
, 0600);
481 mode_t ou
= umask(0);
490 file_error(ms
, errno
,
491 "cannot create temporary file for pipe copy");
495 if (swrite(tfd
, startbuf
, nbytes
) != CAST(ssize_t
, nbytes
))
498 while ((r
= sread(fd
, buf
, sizeof(buf
), 1)) > 0)
499 if (swrite(tfd
, buf
, CAST(size_t, r
)) != r
)
505 file_error(ms
, errno
, "error copying from pipe to temp file");
510 file_error(ms
, errno
, "error while writing to temp file");
515 * We duplicate the file descriptor, because fclose on a
516 * tmpfile will delete the file, but any open descriptors
517 * can still access the phantom inode.
519 if ((fd
= dup2(tfd
, fd
)) == -1) {
520 file_error(ms
, errno
, "could not dup descriptor for temp file");
524 if (lseek(fd
, CAST(off_t
, 0), SEEK_SET
) == CAST(off_t
, -1)) {
531 #ifdef BUILTIN_DECOMPRESS
533 #define FHCRC (1 << 1)
534 #define FEXTRA (1 << 2)
535 #define FNAME (1 << 3)
536 #define FCOMMENT (1 << 4)
540 uncompressgzipped(const unsigned char *old
, unsigned char **newch
,
541 size_t bytes_max
, size_t *n
)
543 unsigned char flg
= old
[3];
544 size_t data_start
= 10;
547 if (data_start
+ 1 >= *n
)
549 data_start
+= 2 + old
[data_start
] + old
[data_start
+ 1] * 256;
552 while(data_start
< *n
&& old
[data_start
])
556 if (flg
& FCOMMENT
) {
557 while(data_start
< *n
&& old
[data_start
])
564 if (data_start
>= *n
)
569 return uncompresszlib(old
, newch
, bytes_max
, n
, 0);
571 return makeerror(newch
, n
, "File too short");
575 uncompresszlib(const unsigned char *old
, unsigned char **newch
,
576 size_t bytes_max
, size_t *n
, int zlib
)
581 if ((*newch
= CAST(unsigned char *, malloc(bytes_max
+ 1))) == NULL
)
582 return makeerror(newch
, n
, "No buffer, %s", strerror(errno
));
584 z
.next_in
= CCAST(Bytef
*, old
);
585 z
.avail_in
= CAST(uint32_t, *n
);
587 z
.avail_out
= CAST(unsigned int, bytes_max
);
592 /* LINTED bug in header macro */
593 rc
= zlib
? inflateInit(&z
) : inflateInit2(&z
, -15);
597 rc
= inflate(&z
, Z_SYNC_FLUSH
);
598 if (rc
!= Z_OK
&& rc
!= Z_STREAM_END
)
601 *n
= CAST(size_t, z
.total_out
);
606 /* let's keep the nul-terminate tradition */
611 strlcpy(RCAST(char *, *newch
), z
.msg
? z
.msg
: zError(rc
), bytes_max
);
612 *n
= strlen(RCAST(char *, *newch
));
619 uncompressbzlib(const unsigned char *old
, unsigned char **newch
,
620 size_t bytes_max
, size_t *n
)
625 memset(&bz
, 0, sizeof(bz
));
626 rc
= BZ2_bzDecompressInit(&bz
, 0, 0);
630 if ((*newch
= CAST(unsigned char *, malloc(bytes_max
+ 1))) == NULL
)
631 return makeerror(newch
, n
, "No buffer, %s", strerror(errno
));
633 bz
.next_in
= CCAST(char *, RCAST(const char *, old
));
634 bz
.avail_in
= CAST(uint32_t, *n
);
635 bz
.next_out
= RCAST(char *, *newch
);
636 bz
.avail_out
= CAST(unsigned int, bytes_max
);
638 rc
= BZ2_bzDecompress(&bz
);
639 if (rc
!= BZ_OK
&& rc
!= BZ_STREAM_END
)
642 /* Assume byte_max is within 32bit */
643 /* assert(bz.total_out_hi32 == 0); */
644 *n
= CAST(size_t, bz
.total_out_lo32
);
645 rc
= BZ2_bzDecompressEnd(&bz
);
649 /* let's keep the nul-terminate tradition */
654 snprintf(RCAST(char *, *newch
), bytes_max
, "bunzip error %d", rc
);
655 *n
= strlen(RCAST(char *, *newch
));
662 uncompressxzlib(const unsigned char *old
, unsigned char **newch
,
663 size_t bytes_max
, size_t *n
)
668 memset(&xz
, 0, sizeof(xz
));
669 rc
= lzma_auto_decoder(&xz
, UINT64_MAX
, 0);
673 if ((*newch
= CAST(unsigned char *, malloc(bytes_max
+ 1))) == NULL
)
674 return makeerror(newch
, n
, "No buffer, %s", strerror(errno
));
676 xz
.next_in
= CCAST(const uint8_t *, old
);
677 xz
.avail_in
= CAST(uint32_t, *n
);
678 xz
.next_out
= RCAST(uint8_t *, *newch
);
679 xz
.avail_out
= CAST(unsigned int, bytes_max
);
681 rc
= lzma_code(&xz
, LZMA_RUN
);
682 if (rc
!= LZMA_OK
&& rc
!= LZMA_STREAM_END
)
685 *n
= CAST(size_t, xz
.total_out
);
689 /* let's keep the nul-terminate tradition */
694 snprintf(RCAST(char *, *newch
), bytes_max
, "unxz error %d", rc
);
695 *n
= strlen(RCAST(char *, *newch
));
702 makeerror(unsigned char **buf
, size_t *len
, const char *fmt
, ...)
709 rv
= vasprintf(&msg
, fmt
, ap
);
716 *buf
= RCAST(unsigned char *, msg
);
722 closefd(int *fd
, size_t i
)
734 for (i
= 0; i
< 2; i
++)
739 movedesc(void *v
, int i
, int fd
)
742 return; /* "no dup was necessary" */
743 #ifdef HAVE_POSIX_SPAWNP
744 posix_spawn_file_actions_t
*fa
= RCAST(posix_spawn_file_actions_t
*, v
);
745 posix_spawn_file_actions_adddup2(fa
, fd
, i
);
746 posix_spawn_file_actions_addclose(fa
, fd
);
748 if (dup2(fd
, i
) == -1) {
749 DPRINTF("dup(%d, %d) failed (%s)\n", fd
, i
, strerror(errno
));
757 closedesc(void *v
, int fd
)
759 #ifdef HAVE_POSIX_SPAWNP
760 posix_spawn_file_actions_t
*fa
= RCAST(posix_spawn_file_actions_t
*, v
);
761 posix_spawn_file_actions_addclose(fa
, fd
);
768 handledesc(void *v
, int fd
, int fdp
[3][2])
771 (void) lseek(fd
, CAST(off_t
, 0), SEEK_SET
);
772 movedesc(v
, STDIN_FILENO
, fd
);
774 movedesc(v
, STDIN_FILENO
, fdp
[STDIN_FILENO
][0]);
775 if (fdp
[STDIN_FILENO
][1] > 2)
776 closedesc(v
, fdp
[STDIN_FILENO
][1]);
779 file_clear_closexec(STDIN_FILENO
);
781 ///FIXME: if one of the fdp[i][j] is 0 or 1, this can bomb spectacularly
782 movedesc(v
, STDOUT_FILENO
, fdp
[STDOUT_FILENO
][1]);
783 if (fdp
[STDOUT_FILENO
][0] > 2)
784 closedesc(v
, fdp
[STDOUT_FILENO
][0]);
786 file_clear_closexec(STDOUT_FILENO
);
788 movedesc(v
, STDERR_FILENO
, fdp
[STDERR_FILENO
][1]);
789 if (fdp
[STDERR_FILENO
][0] > 2)
790 closedesc(v
, fdp
[STDERR_FILENO
][0]);
792 file_clear_closexec(STDERR_FILENO
);
796 writechild(int fd
, const void *old
, size_t n
)
801 * fork again, to avoid blocking because both
806 DPRINTF("Fork failed (%s)\n", strerror(errno
));
811 if (swrite(fd
, old
, n
) != CAST(ssize_t
, n
)) {
812 DPRINTF("Write failed (%s)\n", strerror(errno
));
822 filter_error(unsigned char *ubuf
, ssize_t n
)
828 buf
= RCAST(char *, ubuf
);
829 while (isspace(CAST(unsigned char, *buf
)))
831 DPRINTF("Filter error[[[%s]]]\n", buf
);
832 if ((p
= strchr(CAST(char *, buf
), '\n')) != NULL
)
834 if ((p
= strchr(CAST(char *, buf
), ';')) != NULL
)
836 if ((p
= strrchr(CAST(char *, buf
), ':')) != NULL
) {
838 while (isspace(CAST(unsigned char, *p
)))
841 memmove(ubuf
, p
, CAST(size_t, n
+ 1));
843 DPRINTF("Filter error after[[[%s]]]\n", (char *)ubuf
);
845 *ubuf
= toupper(*ubuf
);
850 methodname(size_t method
)
853 #ifdef BUILTIN_DECOMPRESS
868 return compr
[method
].argv
[0];
873 uncompressbuf(int fd
, size_t bytes_max
, size_t method
, const unsigned char *old
,
874 unsigned char **newch
, size_t* n
)
883 #ifdef HAVE_POSIX_SPAWNP
884 posix_spawn_file_actions_t fa
;
888 #ifdef BUILTIN_DECOMPRESS
890 return uncompressgzipped(old
, newch
, bytes_max
, n
);
892 return uncompresszlib(old
, newch
, bytes_max
, n
, 1);
896 return uncompressbzlib(old
, newch
, bytes_max
, n
);
901 return uncompressxzlib(old
, newch
, bytes_max
, n
);
907 (void)fflush(stdout
);
908 (void)fflush(stderr
);
910 for (i
= 0; i
< __arraycount(fdp
); i
++)
911 fdp
[i
][0] = fdp
[i
][1] = -1;
914 * There are multithreaded users who run magic_file()
915 * from dozens of threads. If two parallel magic_file() calls
916 * analyze two large compressed files, both will spawn
917 * an uncompressing child here, which writes out uncompressed data.
918 * We read some portion, then close the pipe, then waitpid() the child.
919 * If uncompressed data is larger, child shound get EPIPE and exit.
920 * However, with *parallel* calls OTHER child may unintentionally
921 * inherit pipe fds, thus keeping pipe open and making writes in
922 * our child block instead of failing with EPIPE!
923 * (For the bug to occur, two threads must mutually inherit their pipes,
924 * and both must have large outputs. Thus it happens not that often).
925 * To avoid this, be sure to create pipes with O_CLOEXEC.
927 if ((fd
== -1 && file_pipe_closexec(fdp
[STDIN_FILENO
]) == -1) ||
928 file_pipe_closexec(fdp
[STDOUT_FILENO
]) == -1 ||
929 file_pipe_closexec(fdp
[STDERR_FILENO
]) == -1) {
930 closep(fdp
[STDIN_FILENO
]);
931 closep(fdp
[STDOUT_FILENO
]);
932 return makeerror(newch
, n
, "Cannot create pipe, %s",
936 args
= RCAST(char *const *, RCAST(intptr_t, compr
[method
].argv
));
937 #ifdef HAVE_POSIX_SPAWNP
938 posix_spawn_file_actions_init(&fa
);
940 handledesc(&fa
, fd
, fdp
);
942 status
= posix_spawnp(&pid
, compr
[method
].argv
[0], &fa
, NULL
,
945 posix_spawn_file_actions_destroy(&fa
);
948 return makeerror(newch
, n
, "Cannot posix_spawn `%s', %s",
949 compr
[method
].argv
[0], strerror(errno
));
952 /* For processes with large mapped virtual sizes, vfork
953 * may be _much_ faster (10-100 times) than fork.
957 return makeerror(newch
, n
, "Cannot vfork, %s",
962 /* Note: we are after vfork, do not modify memory
963 * in a way which confuses parent. In particular,
964 * do not modify fdp[i][j].
966 handledesc(NULL
, fd
, fdp
);
968 (void)execvp(compr
[method
].argv
[0], args
);
969 dprintf(STDERR_FILENO
, "exec `%s' failed, %s",
970 compr
[method
].argv
[0], strerror(errno
));
971 _exit(1); /* _exit(), not exit(), because of vfork */
975 /* Close write sides of child stdout/err pipes */
976 for (i
= 1; i
< __arraycount(fdp
); i
++)
978 /* Write the buffer data to child stdin, if we don't have fd */
980 closefd(fdp
[STDIN_FILENO
], 0);
981 writepid
= writechild(fdp
[STDIN_FILENO
][1], old
, *n
);
982 closefd(fdp
[STDIN_FILENO
], 1);
985 *newch
= CAST(unsigned char *, malloc(bytes_max
+ 1));
986 if (*newch
== NULL
) {
987 rv
= makeerror(newch
, n
, "No buffer, %s",
993 r
= sread(fdp
[STDOUT_FILENO
][0], *newch
, bytes_max
, 0);
994 if (r
== 0 && errno
== 0)
997 DPRINTF("Read stdout failed %d (%s)\n", fdp
[STDOUT_FILENO
][0],
998 r
!= -1 ? strerror(errno
) : "no data");
1002 (r
= sread(fdp
[STDERR_FILENO
][0], *newch
, bytes_max
, 0)) > 0)
1004 r
= filter_error(*newch
, r
);
1009 rv
= makeerror(newch
, n
, "Read failed, %s",
1012 rv
= makeerror(newch
, n
, "No data");
1017 /* NUL terminate, as every buffer is handled here. */
1018 (*newch
)[*n
] = '\0';
1020 closefd(fdp
[STDIN_FILENO
], 1);
1021 closefd(fdp
[STDOUT_FILENO
], 0);
1022 closefd(fdp
[STDERR_FILENO
], 0);
1024 w
= waitpid(pid
, &status
, 0);
1028 rv
= makeerror(newch
, n
, "Wait failed, %s", strerror(errno
));
1029 DPRINTF("Child wait return %#x\n", status
);
1030 } else if (!WIFEXITED(status
)) {
1031 DPRINTF("Child not exited (%#x)\n", status
);
1032 } else if (WEXITSTATUS(status
) != 0) {
1033 DPRINTF("Child exited (%#x)\n", WEXITSTATUS(status
));
1036 /* _After_ we know decompressor has exited, our input writer
1037 * definitely will exit now (at worst, writing fails in it,
1038 * since output fd is closed now on the reading size).
1040 w
= waitpid(writepid
, &status
, 0);
1045 closefd(fdp
[STDIN_FILENO
], 0); //why? it is already closed here!
1046 DPRINTF("Returning %p n=%" SIZE_T_FORMAT
"u rv=%d\n", *newch
, *n
, rv
);