git: 8cc85a87510a - stable/15 - diff: prefer posix_spawn over pdfork/execl
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 06 Apr 2026 16:52:19 UTC
The branch stable/15 has been updated by bapt:
URL: https://cgit.FreeBSD.org/src/commit/?id=8cc85a87510a56afee49a3f5d153ab0328b676d7
commit 8cc85a87510a56afee49a3f5d153ab0328b676d7
Author: Baptiste Daroussin <bapt@FreeBSD.org>
AuthorDate: 2026-03-25 10:22:02 +0000
Commit: Baptiste Daroussin <bapt@FreeBSD.org>
CommitDate: 2026-04-06 16:51:46 +0000
diff: prefer posix_spawn over pdfork/execl
MFC After: 1 week
Reviewed by: kib
Differential Revision: https://reviews.freebsd.org/D56076
(cherry picked from commit 6d8b2ac449f34423be9d56492022421db61d920e)
---
usr.bin/diff/pr.c | 62 ++++++++++++++++++++++++++++++++++---------------------
1 file 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);
}