diff options
| author | Baptiste Daroussin <bapt@FreeBSD.org> | 2026-03-25 10:22:02 +0000 |
|---|---|---|
| committer | Baptiste Daroussin <bapt@FreeBSD.org> | 2026-03-26 07:36:55 +0000 |
| commit | 6d8b2ac449f34423be9d56492022421db61d920e (patch) | |
| tree | 91d1669a6fa6c8521cdd7f215a0398b2c6af489a | |
| parent | 5f7f0efe8e13247fc80a2a739e757f73a5d7ebda (diff) | |
diff: prefer posix_spawn over pdfork/execl
MFC After: 1 week
Reviewed by: kib
Differential Revision: https://reviews.freebsd.org/D56076
| -rw-r--r-- | usr.bin/diff/pr.c | 62 |
1 files changed, 39 insertions, 23 deletions
diff --git a/usr.bin/diff/pr.c b/usr.bin/diff/pr.c index 189e6b34649e..51cf2c765283 100644 --- a/usr.bin/diff/pr.c +++ b/usr.bin/diff/pr.c @@ -29,8 +29,10 @@ #include <err.h> #include <errno.h> +#include <fcntl.h> #include <paths.h> #include <signal.h> +#include <spawn.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> @@ -41,6 +43,8 @@ #define _PATH_PR "/usr/bin/pr" +extern char **environ; + struct pr * start_pr(char *file1, char *file2) { @@ -48,6 +52,9 @@ start_pr(char *file1, char *file2) pid_t pid; char *header; struct pr *pr; + posix_spawn_file_actions_t fa; + posix_spawnattr_t sa; + int error; pr = xcalloc(1, sizeof(*pr)); @@ -56,32 +63,41 @@ start_pr(char *file1, char *file2) fflush(stdout); if (pipe(pfd) == -1) err(2, "pipe"); - switch ((pid = pdfork(&pr->procd, PD_CLOEXEC))) { - case -1: - err(2, "No more processes"); - case 0: - /* child */ - if (pfd[0] != STDIN_FILENO) { - dup2(pfd[0], STDIN_FILENO); - close(pfd[0]); + + if ((error = posix_spawnattr_init(&sa)) != 0) + errc(2, error, "posix_spawnattr_init"); + if ((error = posix_spawn_file_actions_init(&fa)) != 0) + errc(2, error, "posix_spawn_file_actions_init"); + + posix_spawnattr_setprocdescp_np(&sa, &pr->procd, 0); + + if (pfd[0] != STDIN_FILENO) { + posix_spawn_file_actions_adddup2(&fa, pfd[0], STDIN_FILENO); + posix_spawn_file_actions_addclose(&fa, pfd[0]); + } + posix_spawn_file_actions_addclose(&fa, pfd[1]); + + char *argv[] = { __DECONST(char *, _PATH_PR), + __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 */ + if (pfd[1] == STDOUT_FILENO) { + pr->ostdout = STDOUT_FILENO; + } else { + if ((pr->ostdout = dup(STDOUT_FILENO)) < 0 || + dup2(pfd[1], STDOUT_FILENO) < 0) { + err(2, "stdout"); } close(pfd[1]); - execl(_PATH_PR, _PATH_PR, "-h", header, (char *)0); - _exit(127); - default: - /* parent */ - if (pfd[1] == STDOUT_FILENO) { - pr->ostdout = STDOUT_FILENO; - } else { - if ((pr->ostdout = dup(STDOUT_FILENO)) < 0 || - dup2(pfd[1], STDOUT_FILENO) < 0) { - err(2, "stdout"); - } - close(pfd[1]); - } - close(pfd[0]); - free(header); } + close(pfd[0]); + free(header); return (pr); } |
