compress.c revision 309848
1/*
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.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
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.
15 *
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
26 * SUCH DAMAGE.
27 */
28/*
29 * compress routines:
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
34 */
35#include "file.h"
36
37#ifndef lint
38FILE_RCSID("@(#)$File: compress.c,v 1.100 2016/10/24 18:02:17 christos Exp $")
39#endif
40
41#include "magic.h"
42#include <stdlib.h>
43#ifdef HAVE_UNISTD_H
44#include <unistd.h>
45#endif
46#include <string.h>
47#include <errno.h>
48#include <ctype.h>
49#include <stdarg.h>
50#ifdef HAVE_SIGNAL_H
51#include <signal.h>
52# ifndef HAVE_SIG_T
53typedef void (*sig_t)(int);
54# endif /* HAVE_SIG_T */
55#endif
56#if !defined(__MINGW32__) && !defined(WIN32)
57#include <sys/ioctl.h>
58#endif
59#ifdef HAVE_SYS_WAIT_H
60#include <sys/wait.h>
61#endif
62#if defined(HAVE_SYS_TIME_H)
63#include <sys/time.h>
64#endif
65#if defined(HAVE_ZLIB_H)
66#define BUILTIN_DECOMPRESS
67#include <zlib.h>
68#endif
69#ifdef DEBUG
70int tty = -1;
71#define DPRINTF(...)	do { \
72	if (tty == -1) \
73		tty = open("/dev/tty", O_RDWR); \
74	if (tty == -1) \
75		abort(); \
76	dprintf(tty, __VA_ARGS__); \
77} while (/*CONSTCOND*/0)
78#else
79#define DPRINTF(...)
80#endif
81
82#ifdef ZLIBSUPPORT
83/*
84 * The following python code is not really used because ZLIBSUPPORT is only
85 * defined if we have a built-in zlib, and the built-in zlib handles that.
86 */
87static const char zlibcode[] =
88    "import sys, zlib; sys.stdout.write(zlib.decompress(sys.stdin.read()))";
89
90static const char *zlib_args[] = { "python", "-c", zlibcode, NULL };
91
92static int
93zlibcmp(const unsigned char *buf)
94{
95	unsigned short x = 1;
96	unsigned char *s = (unsigned char *)&x;
97
98	if ((buf[0] & 0xf) != 8 || (buf[0] & 0x80) != 0)
99		return 0;
100	if (s[0] != 1)	/* endianness test */
101		x = buf[0] | (buf[1] << 8);
102	else
103		x = buf[1] | (buf[0] << 8);
104	if (x % 31)
105		return 0;
106	return 1;
107}
108#endif
109
110#define gzip_flags "-cd"
111#define lrzip_flags "-do"
112#define lzip_flags gzip_flags
113
114static const char *gzip_args[] = {
115	"gzip", gzip_flags, NULL
116};
117static const char *uncompress_args[] = {
118	"uncompress", "-c", NULL
119};
120static const char *bzip2_args[] = {
121	"bzip2", "-cd", NULL
122};
123static const char *lzip_args[] = {
124	"lzip", lzip_flags, NULL
125};
126static const char *xz_args[] = {
127	"xz", "-cd", NULL
128};
129static const char *lrzip_args[] = {
130	"lrzip", lrzip_flags, NULL
131};
132static const char *lz4_args[] = {
133	"lz4", "-cd", NULL
134};
135static const char *zstd_args[] = {
136	"zstd", "-cd", NULL
137};
138
139private const struct {
140	const void *magic;
141	size_t maglen;
142	const char **argv;
143} compr[] = {
144	{ "\037\235",	2, gzip_args },		/* compressed */
145	/* Uncompress can get stuck; so use gzip first if we have it
146	 * Idea from Damien Clark, thanks! */
147	{ "\037\235",	2, uncompress_args },	/* compressed */
148	{ "\037\213",	2, gzip_args },		/* gzipped */
149	{ "\037\236",	2, gzip_args },		/* frozen */
150	{ "\037\240",	2, gzip_args },		/* SCO LZH */
151	/* the standard pack utilities do not accept standard input */
152	{ "\037\036",	2, gzip_args },		/* packed */
153	{ "PK\3\4",	4, gzip_args },		/* pkzipped, */
154	/* ...only first file examined */
155	{ "BZh",	3, bzip2_args },	/* bzip2-ed */
156	{ "LZIP",	4, lzip_args },		/* lzip-ed */
157 	{ "\3757zXZ\0",	6, xz_args },		/* XZ Utils */
158 	{ "LRZI",	4, lrzip_args },	/* LRZIP */
159 	{ "\004\"M\030",4, lz4_args },		/* LZ4 */
160 	{ "\x28\xB5\x2F\xFD", 4, zstd_args },	/* zstd */
161#ifdef ZLIBSUPPORT
162	{ RCAST(const void *, zlibcmp),	0, zlib_args },		/* zlib */
163#endif
164};
165
166#define OKDATA 	0
167#define NODATA	1
168#define ERRDATA	2
169
170private ssize_t swrite(int, const void *, size_t);
171#if HAVE_FORK
172private size_t ncompr = sizeof(compr) / sizeof(compr[0]);
173private int uncompressbuf(int, size_t, size_t, const unsigned char *,
174    unsigned char **, size_t *);
175#ifdef BUILTIN_DECOMPRESS
176private int uncompresszlib(const unsigned char *, unsigned char **, size_t,
177    size_t *, int);
178private int uncompressgzipped(const unsigned char *, unsigned char **, size_t,
179    size_t *);
180#endif
181static int makeerror(unsigned char **, size_t *, const char *, ...)
182    __attribute__((__format__(__printf__, 3, 4)));
183private const char *methodname(size_t);
184
185protected int
186file_zmagic(struct magic_set *ms, int fd, const char *name,
187    const unsigned char *buf, size_t nbytes)
188{
189	unsigned char *newbuf = NULL;
190	size_t i, nsz;
191	char *rbuf;
192	file_pushbuf_t *pb;
193	int urv, prv, rv = 0;
194	int mime = ms->flags & MAGIC_MIME;
195#ifdef HAVE_SIGNAL_H
196	sig_t osigpipe;
197#endif
198
199	if ((ms->flags & MAGIC_COMPRESS) == 0)
200		return 0;
201
202#ifdef HAVE_SIGNAL_H
203	osigpipe = signal(SIGPIPE, SIG_IGN);
204#endif
205	for (i = 0; i < ncompr; i++) {
206		int zm;
207		if (nbytes < compr[i].maglen)
208			continue;
209#ifdef ZLIBSUPPORT
210		if (compr[i].maglen == 0)
211			zm = (RCAST(int (*)(const unsigned char *),
212			    CCAST(void *, compr[i].magic)))(buf);
213		else
214#endif
215			zm = memcmp(buf, compr[i].magic, compr[i].maglen) == 0;
216
217		if (!zm)
218			continue;
219		nsz = nbytes;
220		urv = uncompressbuf(fd, ms->bytes_max, i, buf, &newbuf, &nsz);
221		DPRINTF("uncompressbuf = %d, %s, %zu\n", urv, (char *)newbuf,
222		    nsz);
223		switch (urv) {
224		case OKDATA:
225		case ERRDATA:
226
227			ms->flags &= ~MAGIC_COMPRESS;
228			if (urv == ERRDATA)
229				prv = file_printf(ms, "%s ERROR: %s",
230				    methodname(i), newbuf);
231			else
232				prv = file_buffer(ms, -1, name, newbuf, nsz);
233			if (prv == -1)
234				goto error;
235			rv = 1;
236			if ((ms->flags & MAGIC_COMPRESS_TRANSP) != 0)
237				goto out;
238			if (mime != MAGIC_MIME && mime != 0)
239				goto out;
240			if ((file_printf(ms,
241			    mime ? " compressed-encoding=" : " (")) == -1)
242				goto error;
243			if ((pb = file_push_buffer(ms)) == NULL)
244				goto error;
245			/*
246			 * XXX: If file_buffer fails here, we overwrite
247			 * the compressed text. FIXME.
248			 */
249			if (file_buffer(ms, -1, NULL, buf, nbytes) == -1)
250				goto error;
251			if ((rbuf = file_pop_buffer(ms, pb)) != NULL) {
252				if (file_printf(ms, "%s", rbuf) == -1) {
253					free(rbuf);
254					goto error;
255				}
256				free(rbuf);
257			}
258			if (!mime && file_printf(ms, ")") == -1)
259				goto error;
260			/*FALLTHROUGH*/
261		case NODATA:
262			break;
263		default:
264			abort();
265			/*NOTREACHED*/
266		error:
267			rv = -1;
268			break;
269		}
270	}
271out:
272	DPRINTF("rv = %d\n", rv);
273
274#ifdef HAVE_SIGNAL_H
275	(void)signal(SIGPIPE, osigpipe);
276#endif
277	free(newbuf);
278	ms->flags |= MAGIC_COMPRESS;
279	DPRINTF("Zmagic returns %d\n", rv);
280	return rv;
281}
282#endif
283/*
284 * `safe' write for sockets and pipes.
285 */
286private ssize_t
287swrite(int fd, const void *buf, size_t n)
288{
289	ssize_t rv;
290	size_t rn = n;
291
292	do
293		switch (rv = write(fd, buf, n)) {
294		case -1:
295			if (errno == EINTR)
296				continue;
297			return -1;
298		default:
299			n -= rv;
300			buf = CAST(const char *, buf) + rv;
301			break;
302		}
303	while (n > 0);
304	return rn;
305}
306
307
308/*
309 * `safe' read for sockets and pipes.
310 */
311protected ssize_t
312sread(int fd, void *buf, size_t n, int canbepipe __attribute__((__unused__)))
313{
314	ssize_t rv;
315#ifdef FIONREAD
316	int t = 0;
317#endif
318	size_t rn = n;
319
320	if (fd == STDIN_FILENO)
321		goto nocheck;
322
323#ifdef FIONREAD
324	if (canbepipe && (ioctl(fd, FIONREAD, &t) == -1 || t == 0)) {
325#ifdef FD_ZERO
326		ssize_t cnt;
327		for (cnt = 0;; cnt++) {
328			fd_set check;
329			struct timeval tout = {0, 100 * 1000};
330			int selrv;
331
332			FD_ZERO(&check);
333			FD_SET(fd, &check);
334
335			/*
336			 * Avoid soft deadlock: do not read if there
337			 * is nothing to read from sockets and pipes.
338			 */
339			selrv = select(fd + 1, &check, NULL, NULL, &tout);
340			if (selrv == -1) {
341				if (errno == EINTR || errno == EAGAIN)
342					continue;
343			} else if (selrv == 0 && cnt >= 5) {
344				return 0;
345			} else
346				break;
347		}
348#endif
349		(void)ioctl(fd, FIONREAD, &t);
350	}
351
352	if (t > 0 && (size_t)t < n) {
353		n = t;
354		rn = n;
355	}
356#endif
357
358nocheck:
359	do
360		switch ((rv = read(fd, buf, n))) {
361		case -1:
362			if (errno == EINTR)
363				continue;
364			return -1;
365		case 0:
366			return rn - n;
367		default:
368			n -= rv;
369			buf = CAST(char *, CCAST(void *, buf)) + rv;
370			break;
371		}
372	while (n > 0);
373	return rn;
374}
375
376protected int
377file_pipe2file(struct magic_set *ms, int fd, const void *startbuf,
378    size_t nbytes)
379{
380	char buf[4096];
381	ssize_t r;
382	int tfd;
383
384	(void)strlcpy(buf, "/tmp/file.XXXXXX", sizeof buf);
385#ifndef HAVE_MKSTEMP
386	{
387		char *ptr = mktemp(buf);
388		tfd = open(ptr, O_RDWR|O_TRUNC|O_EXCL|O_CREAT, 0600);
389		r = errno;
390		(void)unlink(ptr);
391		errno = r;
392	}
393#else
394	{
395		int te;
396		tfd = mkstemp(buf);
397		te = errno;
398		(void)unlink(buf);
399		errno = te;
400	}
401#endif
402	if (tfd == -1) {
403		file_error(ms, errno,
404		    "cannot create temporary file for pipe copy");
405		return -1;
406	}
407
408	if (swrite(tfd, startbuf, nbytes) != (ssize_t)nbytes)
409		r = 1;
410	else {
411		while ((r = sread(fd, buf, sizeof(buf), 1)) > 0)
412			if (swrite(tfd, buf, (size_t)r) != r)
413				break;
414	}
415
416	switch (r) {
417	case -1:
418		file_error(ms, errno, "error copying from pipe to temp file");
419		return -1;
420	case 0:
421		break;
422	default:
423		file_error(ms, errno, "error while writing to temp file");
424		return -1;
425	}
426
427	/*
428	 * We duplicate the file descriptor, because fclose on a
429	 * tmpfile will delete the file, but any open descriptors
430	 * can still access the phantom inode.
431	 */
432	if ((fd = dup2(tfd, fd)) == -1) {
433		file_error(ms, errno, "could not dup descriptor for temp file");
434		return -1;
435	}
436	(void)close(tfd);
437	if (lseek(fd, (off_t)0, SEEK_SET) == (off_t)-1) {
438		file_badseek(ms);
439		return -1;
440	}
441	return fd;
442}
443#if HAVE_FORK
444#ifdef BUILTIN_DECOMPRESS
445
446#define FHCRC		(1 << 1)
447#define FEXTRA		(1 << 2)
448#define FNAME		(1 << 3)
449#define FCOMMENT	(1 << 4)
450
451
452private int
453uncompressgzipped(const unsigned char *old, unsigned char **newch,
454    size_t bytes_max, size_t *n)
455{
456	unsigned char flg = old[3];
457	size_t data_start = 10;
458
459	if (flg & FEXTRA) {
460		if (data_start + 1 >= *n)
461			goto err;
462		data_start += 2 + old[data_start] + old[data_start + 1] * 256;
463	}
464	if (flg & FNAME) {
465		while(data_start < *n && old[data_start])
466			data_start++;
467		data_start++;
468	}
469	if (flg & FCOMMENT) {
470		while(data_start < *n && old[data_start])
471			data_start++;
472		data_start++;
473	}
474	if (flg & FHCRC)
475		data_start += 2;
476
477	if (data_start >= *n)
478		goto err;
479
480	*n -= data_start;
481	old += data_start;
482	return uncompresszlib(old, newch, bytes_max, n, 0);
483err:
484	return makeerror(newch, n, "File too short");
485}
486
487private int
488uncompresszlib(const unsigned char *old, unsigned char **newch,
489    size_t bytes_max, size_t *n, int zlib)
490{
491	int rc;
492	z_stream z;
493
494	if ((*newch = CAST(unsigned char *, malloc(bytes_max + 1))) == NULL)
495		return makeerror(newch, n, "No buffer, %s", strerror(errno));
496
497	z.next_in = CCAST(Bytef *, old);
498	z.avail_in = CAST(uint32_t, *n);
499	z.next_out = *newch;
500	z.avail_out = bytes_max;
501	z.zalloc = Z_NULL;
502	z.zfree = Z_NULL;
503	z.opaque = Z_NULL;
504
505	/* LINTED bug in header macro */
506	rc = zlib ? inflateInit(&z) : inflateInit2(&z, -15);
507	if (rc != Z_OK)
508		goto err;
509
510	rc = inflate(&z, Z_SYNC_FLUSH);
511	if (rc != Z_OK && rc != Z_STREAM_END)
512		goto err;
513
514	*n = (size_t)z.total_out;
515	rc = inflateEnd(&z);
516	if (rc != Z_OK)
517		goto err;
518
519	/* let's keep the nul-terminate tradition */
520	(*newch)[*n] = '\0';
521
522	return OKDATA;
523err:
524	strlcpy((char *)*newch, z.msg ? z.msg : zError(rc), bytes_max);
525	*n = strlen((char *)*newch);
526	return ERRDATA;
527}
528#endif
529
530static int
531makeerror(unsigned char **buf, size_t *len, const char *fmt, ...)
532{
533	char *msg;
534	va_list ap;
535	int rv;
536
537	va_start(ap, fmt);
538	rv = vasprintf(&msg, fmt, ap);
539	va_end(ap);
540	if (rv < 0) {
541		*buf = NULL;
542		*len = 0;
543		return NODATA;
544	}
545	*buf = (unsigned char *)msg;
546	*len = strlen(msg);
547	return ERRDATA;
548}
549
550static void
551closefd(int *fd, size_t i)
552{
553	if (fd[i] == -1)
554		return;
555	(void) close(fd[i]);
556	fd[i] = -1;
557}
558
559static void
560closep(int *fd)
561{
562	size_t i;
563	for (i = 0; i < 2; i++)
564		closefd(fd, i);
565}
566
567static void
568copydesc(int i, int *fd)
569{
570	int j = fd[i == STDIN_FILENO ? 0 : 1];
571	if (j == i)
572		return;
573	if (dup2(j, i) == -1) {
574		DPRINTF("dup(%d, %d) failed (%s)\n", j, i, strerror(errno));
575		exit(1);
576	}
577	closep(fd);
578}
579
580static void
581writechild(int fdp[3][2], const void *old, size_t n)
582{
583	int status;
584
585	closefd(fdp[STDIN_FILENO], 0);
586	/*
587	 * fork again, to avoid blocking because both
588	 * pipes filled
589	 */
590	switch (fork()) {
591	case 0: /* child */
592		closefd(fdp[STDOUT_FILENO], 0);
593		if (swrite(fdp[STDIN_FILENO][1], old, n) != (ssize_t)n) {
594			DPRINTF("Write failed (%s)\n", strerror(errno));
595			exit(1);
596		}
597		exit(0);
598		/*NOTREACHED*/
599
600	case -1:
601		DPRINTF("Fork failed (%s)\n", strerror(errno));
602		exit(1);
603		/*NOTREACHED*/
604
605	default:  /* parent */
606		if (wait(&status) == -1) {
607			DPRINTF("Wait failed (%s)\n", strerror(errno));
608			exit(1);
609		}
610		DPRINTF("Grandchild wait return %#x\n", status);
611	}
612	closefd(fdp[STDIN_FILENO], 1);
613}
614
615static ssize_t
616filter_error(unsigned char *ubuf, ssize_t n)
617{
618	char *p;
619	char *buf;
620
621	ubuf[n] = '\0';
622	buf = (char *)ubuf;
623	while (isspace((unsigned char)*buf))
624		buf++;
625	DPRINTF("Filter error[[[%s]]]\n", buf);
626	if ((p = strchr((char *)buf, '\n')) != NULL)
627		*p = '\0';
628	if ((p = strchr((char *)buf, ';')) != NULL)
629		*p = '\0';
630	if ((p = strrchr((char *)buf, ':')) != NULL) {
631		++p;
632		while (isspace((unsigned char)*p))
633			p++;
634		n = strlen(p);
635		memmove(ubuf, p, n + 1);
636	}
637	DPRINTF("Filter error after[[[%s]]]\n", (char *)ubuf);
638	if (islower(*ubuf))
639		*ubuf = toupper(*ubuf);
640	return n;
641}
642
643private const char *
644methodname(size_t method)
645{
646#ifdef BUILTIN_DECOMPRESS
647        /* FIXME: This doesn't cope with bzip2 */
648	if (method == 2 || compr[method].maglen == 0)
649	    return "zlib";
650#endif
651	return compr[method].argv[0];
652}
653
654private int
655uncompressbuf(int fd, size_t bytes_max, size_t method, const unsigned char *old,
656    unsigned char **newch, size_t* n)
657{
658	int fdp[3][2];
659	int status, rv;
660	size_t i;
661	ssize_t r;
662
663#ifdef BUILTIN_DECOMPRESS
664        /* FIXME: This doesn't cope with bzip2 */
665	if (method == 2)
666		return uncompressgzipped(old, newch, bytes_max, n);
667	if (compr[method].maglen == 0)
668		return uncompresszlib(old, newch, bytes_max, n, 1);
669#endif
670	(void)fflush(stdout);
671	(void)fflush(stderr);
672
673	for (i = 0; i < __arraycount(fdp); i++)
674		fdp[i][0] = fdp[i][1] = -1;
675
676	if ((fd == -1 && pipe(fdp[STDIN_FILENO]) == -1) ||
677	    pipe(fdp[STDOUT_FILENO]) == -1 || pipe(fdp[STDERR_FILENO]) == -1) {
678		closep(fdp[STDIN_FILENO]);
679		closep(fdp[STDOUT_FILENO]);
680		return makeerror(newch, n, "Cannot create pipe, %s",
681		    strerror(errno));
682	}
683	switch (fork()) {
684	case 0:	/* child */
685		if (fd != -1) {
686			fdp[STDIN_FILENO][0] = fd;
687			(void) lseek(fd, (off_t)0, SEEK_SET);
688		}
689
690		for (i = 0; i < __arraycount(fdp); i++)
691			copydesc(i, fdp[i]);
692
693		(void)execvp(compr[method].argv[0],
694		    (char *const *)(intptr_t)compr[method].argv);
695		dprintf(STDERR_FILENO, "exec `%s' failed, %s",
696		    compr[method].argv[0], strerror(errno));
697		exit(1);
698		/*NOTREACHED*/
699	case -1:
700		return makeerror(newch, n, "Cannot fork, %s",
701		    strerror(errno));
702
703	default: /* parent */
704		for (i = 1; i < __arraycount(fdp); i++)
705			closefd(fdp[i], 1);
706
707		/* Write the buffer data to the child, if we don't have fd */
708		if (fd == -1)
709			writechild(fdp, old, *n);
710
711		*newch = CAST(unsigned char *, malloc(bytes_max + 1));
712		if (*newch == NULL) {
713			rv = makeerror(newch, n, "No buffer, %s",
714			    strerror(errno));
715			goto err;
716		}
717		rv = OKDATA;
718		if ((r = sread(fdp[STDOUT_FILENO][0], *newch, bytes_max, 0)) > 0)
719			break;
720		DPRINTF("Read stdout failed %d (%s)\n", fdp[STDOUT_FILENO][0],
721		    r != -1 ? strerror(errno) : "no data");
722
723		rv = ERRDATA;
724		if (r == 0 &&
725		    (r = sread(fdp[STDERR_FILENO][0], *newch, bytes_max, 0)) > 0)
726		{
727			r = filter_error(*newch, r);
728			break;
729		}
730		free(*newch);
731		if  (r == 0)
732			rv = makeerror(newch, n, "Read failed, %s",
733			    strerror(errno));
734		else
735			rv = makeerror(newch, n, "No data");
736		goto err;
737	}
738
739	*n = r;
740	/* NUL terminate, as every buffer is handled here. */
741	(*newch)[*n] = '\0';
742err:
743	closefd(fdp[STDIN_FILENO], 1);
744	closefd(fdp[STDOUT_FILENO], 0);
745	closefd(fdp[STDERR_FILENO], 0);
746	if (wait(&status) == -1) {
747		free(*newch);
748		rv = makeerror(newch, n, "Wait failed, %s", strerror(errno));
749		DPRINTF("Child wait return %#x\n", status);
750	} else if (!WIFEXITED(status)) {
751		DPRINTF("Child not exited (0x%x)\n", status);
752	} else if (WEXITSTATUS(status) != 0) {
753		DPRINTF("Child exited (0x%d)\n", WEXITSTATUS(status));
754	}
755
756	closefd(fdp[STDIN_FILENO], 0);
757	DPRINTF("Returning %p n=%zu rv=%d\n", *newch, *n, rv);
758
759	return rv;
760}
761#endif
762