Changeset View
Changeset View
Standalone View
Standalone View
usr.bin/diff/pr.c
| Show All 23 Lines | |||||
| * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
| */ | */ | ||||
| #include <sys/procdesc.h> | #include <sys/procdesc.h> | ||||
| #include <sys/wait.h> | #include <sys/wait.h> | ||||
| #include <err.h> | #include <err.h> | ||||
| #include <errno.h> | #include <errno.h> | ||||
| #include <fcntl.h> | |||||
| #include <paths.h> | #include <paths.h> | ||||
| #include <signal.h> | #include <signal.h> | ||||
| #include <spawn.h> | |||||
| #include <stdio.h> | #include <stdio.h> | ||||
| #include <stdlib.h> | #include <stdlib.h> | ||||
| #include <unistd.h> | #include <unistd.h> | ||||
| #include "pr.h" | #include "pr.h" | ||||
| #include "diff.h" | #include "diff.h" | ||||
| #include "xmalloc.h" | #include "xmalloc.h" | ||||
| #define _PATH_PR "/usr/bin/pr" | #define _PATH_PR "/usr/bin/pr" | ||||
| extern char **environ; | |||||
| struct pr * | struct pr * | ||||
| start_pr(char *file1, char *file2) | start_pr(char *file1, char *file2) | ||||
| { | { | ||||
| int pfd[2]; | int pfd[2]; | ||||
| pid_t pid; | pid_t pid; | ||||
| char *header; | char *header; | ||||
| struct pr *pr; | struct pr *pr; | ||||
| posix_spawn_file_actions_t fa; | |||||
| posix_spawnattr_t sa; | |||||
| int error; | |||||
| pr = xcalloc(1, sizeof(*pr)); | pr = xcalloc(1, sizeof(*pr)); | ||||
| xasprintf(&header, "%s %s %s", diffargs, file1, file2); | xasprintf(&header, "%s %s %s", diffargs, file1, file2); | ||||
| signal(SIGPIPE, SIG_IGN); | signal(SIGPIPE, SIG_IGN); | ||||
| fflush(stdout); | fflush(stdout); | ||||
| if (pipe(pfd) == -1) | if (pipe(pfd) == -1) | ||||
| err(2, "pipe"); | err(2, "pipe"); | ||||
| switch ((pid = pdfork(&pr->procd, PD_CLOEXEC))) { | |||||
| case -1: | if ((error = posix_spawnattr_init(&sa)) != 0) | ||||
| err(2, "No more processes"); | errc(2, error, "posix_spawnattr_init"); | ||||
| case 0: | if ((error = posix_spawn_file_actions_init(&fa)) != 0) | ||||
| /* child */ | errc(2, error, "posix_spawn_file_actions_init"); | ||||
| posix_spawnattr_setprocdescp_np(&sa, &pr->procd, 0); | |||||
| if (pfd[0] != STDIN_FILENO) { | if (pfd[0] != STDIN_FILENO) { | ||||
| dup2(pfd[0], STDIN_FILENO); | posix_spawn_file_actions_adddup2(&fa, pfd[0], STDIN_FILENO); | ||||
| close(pfd[0]); | posix_spawn_file_actions_addclose(&fa, pfd[0]); | ||||
| } | } | ||||
| close(pfd[1]); | posix_spawn_file_actions_addclose(&fa, pfd[1]); | ||||
| execl(_PATH_PR, _PATH_PR, "-h", header, (char *)0); | |||||
| _exit(127); | char *argv[] = { __DECONST(char *, _PATH_PR), | ||||
| default: | __DECONST(char *, "-h"), header, NULL }; | ||||
| error = posix_spawn(&pid, _PATH_PR, &fa, &sa, argv, environ); | |||||
| if (error != 0) | |||||
| errc(2, error, "could not spawn pr"); | |||||
| posix_spawn_file_actions_destroy(&fa); | |||||
| posix_spawnattr_destroy(&sa); | |||||
| /* parent */ | /* parent */ | ||||
| if (pfd[1] == STDOUT_FILENO) { | if (pfd[1] == STDOUT_FILENO) { | ||||
| pr->ostdout = STDOUT_FILENO; | pr->ostdout = STDOUT_FILENO; | ||||
| } else { | } else { | ||||
| if ((pr->ostdout = dup(STDOUT_FILENO)) < 0 || | if ((pr->ostdout = dup(STDOUT_FILENO)) < 0 || | ||||
| dup2(pfd[1], STDOUT_FILENO) < 0) { | dup2(pfd[1], STDOUT_FILENO) < 0) { | ||||
| err(2, "stdout"); | err(2, "stdout"); | ||||
| } | } | ||||
| close(pfd[1]); | close(pfd[1]); | ||||
| } | } | ||||
| close(pfd[0]); | close(pfd[0]); | ||||
| free(header); | free(header); | ||||
| } | |||||
| return (pr); | return (pr); | ||||
| } | } | ||||
| /* close the pipe to pr and restore stdout */ | /* close the pipe to pr and restore stdout */ | ||||
| void | void | ||||
| stop_pr(struct pr *pr) | stop_pr(struct pr *pr) | ||||
| { | { | ||||
| int wstatus; | int wstatus; | ||||
| Show All 21 Lines | |||||