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 38 FILE_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 53 typedef 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 70 int 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 */ 87 static const char zlibcode[] = 88 "import sys, zlib; sys.stdout.write(zlib.decompress(sys.stdin.read()))"; 89 90 static const char *zlib_args[] = { "python", "-c", zlibcode, NULL }; 91 92 static int 93 zlibcmp(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 114 static const char *gzip_args[] = { 115 "gzip", gzip_flags, NULL 116 }; 117 static const char *uncompress_args[] = { 118 "uncompress", "-c", NULL 119 }; 120 static const char *bzip2_args[] = { 121 "bzip2", "-cd", NULL 122 }; 123 static const char *lzip_args[] = { 124 "lzip", lzip_flags, NULL 125 }; 126 static const char *xz_args[] = { 127 "xz", "-cd", NULL 128 }; 129 static const char *lrzip_args[] = { 130 "lrzip", lrzip_flags, NULL 131 }; 132 static const char *lz4_args[] = { 133 "lz4", "-cd", NULL 134 }; 135 static const char *zstd_args[] = { 136 "zstd", "-cd", NULL 137 }; 138 139 private 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 170 private ssize_t swrite(int, const void *, size_t); 171 #if HAVE_FORK 172 private size_t ncompr = sizeof(compr) / sizeof(compr[0]); 173 private int uncompressbuf(int, size_t, size_t, const unsigned char *, 174 unsigned char **, size_t *); 175 #ifdef BUILTIN_DECOMPRESS 176 private int uncompresszlib(const unsigned char *, unsigned char **, size_t, 177 size_t *, int); 178 private int uncompressgzipped(const unsigned char *, unsigned char **, size_t, 179 size_t *); 180 #endif 181 static int makeerror(unsigned char **, size_t *, const char *, ...) 182 __attribute__((__format__(__printf__, 3, 4))); 183 private const char *methodname(size_t); 184 185 protected int 186 file_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 } 271 out: 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 */ 286 private ssize_t 287 swrite(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 */ 311 protected ssize_t 312 sread(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 358 nocheck: 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 376 protected int 377 file_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 452 private int 453 uncompressgzipped(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); 483 err: 484 return makeerror(newch, n, "File too short"); 485 } 486 487 private int 488 uncompresszlib(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; 523 err: 524 strlcpy((char *)*newch, z.msg ? z.msg : zError(rc), bytes_max); 525 *n = strlen((char *)*newch); 526 return ERRDATA; 527 } 528 #endif 529 530 static int 531 makeerror(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 550 static void 551 closefd(int *fd, size_t i) 552 { 553 if (fd[i] == -1) 554 return; 555 (void) close(fd[i]); 556 fd[i] = -1; 557 } 558 559 static void 560 closep(int *fd) 561 { 562 size_t i; 563 for (i = 0; i < 2; i++) 564 closefd(fd, i); 565 } 566 567 static void 568 copydesc(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 580 static void 581 writechild(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 615 static ssize_t 616 filter_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 643 private const char * 644 methodname(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 654 private int 655 uncompressbuf(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'; 742 err: 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