| 590 | } |
| 591 | |
| 592 | static char *finish_pre_exec(const char *desc, pid_t pid, int read_fd) |
| 593 | { |
| 594 | char buf[BIGPATHBUFLEN], *bp, *cr; |
| 595 | int j, status = -1, msglen = sizeof buf - 1; |
| 596 | |
| 597 | if (read_fd >= 0) { |
| 598 | /* Read the stdout from the program. This it is only displayed |
| 599 | * to the user if the script also returns an error status. */ |
| 600 | for (bp = buf, cr = buf; msglen > 0; msglen -= j) { |
| 601 | if ((j = read(read_fd, bp, msglen)) <= 0) { |
| 602 | if (j == 0) |
| 603 | break; |
| 604 | if (errno == EINTR) |
| 605 | continue; |
| 606 | break; /* Just ignore the read error for now... */ |
| 607 | } |
| 608 | bp[j] = '\0'; |
| 609 | while (1) { |
| 610 | if ((cr = strchr(cr, '\r')) == NULL) { |
| 611 | cr = bp + j; |
| 612 | break; |
| 613 | } |
| 614 | if (!cr[1]) |
| 615 | break; /* wait for more data before we decide what to do */ |
| 616 | if (cr[1] == '\n') { |
| 617 | memmove(cr, cr+1, j - (cr - bp)); |
| 618 | j--; |
| 619 | } else |
| 620 | cr++; |
| 621 | } |
| 622 | bp += j; |
| 623 | } |
| 624 | *bp = '\0'; |
| 625 | |
| 626 | close(read_fd); |
| 627 | } else |
| 628 | *buf = '\0'; |
| 629 | |
| 630 | if (wait_process(pid, &status, 0) < 0 |
| 631 | || !WIFEXITED(status) || WEXITSTATUS(status) != 0) { |
| 632 | char *e; |
| 633 | if (asprintf(&e, "%s returned failure (%d)%s%s%s\n%s", |
| 634 | desc, status, status < 0 ? ": " : "", |
| 635 | status < 0 ? strerror(errno) : "", |
| 636 | *buf ? ":" : "", buf) < 0) |
| 637 | return "out_of_memory in finish_pre_exec\n"; |
| 638 | return e; |
| 639 | } |
| 640 | return NULL; |
| 641 | } |
| 642 | |
| 643 | static int path_failure(int f_out, const char *dir, BOOL was_chdir) |
| 644 | { |
no test coverage detected