Used for "early exec", "pre-xfer exec", and the "name converter" script. */
| 498 | |
| 499 | /* Used for "early exec", "pre-xfer exec", and the "name converter" script. */ |
| 500 | static pid_t start_pre_exec(const char *cmd, int *arg_fd_ptr, int *error_fd_ptr) |
| 501 | { |
| 502 | int arg_fds[2], error_fds[2], arg_fd; |
| 503 | pid_t pid; |
| 504 | |
| 505 | if ((error_fd_ptr && pipe(error_fds) < 0) || pipe(arg_fds) < 0 || (pid = fork()) < 0) |
| 506 | return (pid_t)-1; |
| 507 | |
| 508 | if (pid == 0) { |
| 509 | char buf[BIGPATHBUFLEN]; |
| 510 | int j, len, status; |
| 511 | |
| 512 | if (error_fd_ptr) { |
| 513 | close(error_fds[0]); |
| 514 | set_blocking(error_fds[1]); |
| 515 | } |
| 516 | |
| 517 | close(arg_fds[1]); |
| 518 | arg_fd = arg_fds[0]; |
| 519 | set_blocking(arg_fd); |
| 520 | |
| 521 | len = read_arg_from_pipe(arg_fd, buf, BIGPATHBUFLEN); |
| 522 | if (len <= 0) |
| 523 | _exit(1); |
| 524 | set_env_str("RSYNC_REQUEST", buf); |
| 525 | |
| 526 | for (j = 0; ; j++) { |
| 527 | len = read_arg_from_pipe(arg_fd, buf, BIGPATHBUFLEN); |
| 528 | if (len <= 0) { |
| 529 | if (!len) |
| 530 | break; |
| 531 | _exit(1); |
| 532 | } |
| 533 | set_envN_str("RSYNC_ARG", j, buf); |
| 534 | } |
| 535 | |
| 536 | dup2(arg_fd, STDIN_FILENO); |
| 537 | close(arg_fd); |
| 538 | |
| 539 | if (error_fd_ptr) { |
| 540 | dup2(error_fds[1], STDOUT_FILENO); |
| 541 | close(error_fds[1]); |
| 542 | } |
| 543 | |
| 544 | status = shell_exec(cmd); |
| 545 | |
| 546 | if (!WIFEXITED(status)) |
| 547 | _exit(1); |
| 548 | _exit(WEXITSTATUS(status)); |
| 549 | } |
| 550 | |
| 551 | if (error_fd_ptr) { |
| 552 | close(error_fds[1]); |
| 553 | *error_fd_ptr = error_fds[0]; |
| 554 | set_blocking(error_fds[0]); |
| 555 | } |
| 556 | |
| 557 | close(arg_fds[0]); |
no test coverage detected