aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBaptiste Daroussin <bapt@FreeBSD.org>2026-03-25 10:22:02 +0000
committerBaptiste Daroussin <bapt@FreeBSD.org>2026-03-26 07:36:55 +0000
commit6d8b2ac449f34423be9d56492022421db61d920e (patch)
tree91d1669a6fa6c8521cdd7f215a0398b2c6af489a
parent5f7f0efe8e13247fc80a2a739e757f73a5d7ebda (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.c62
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);
}