diff options
| author | Bruno Haible <bruno@clisp.org> | 2025-10-30 10:15:09 +0100 |
|---|---|---|
| committer | Pádraig Brady <P@draigBrady.com> | 2025-10-30 18:34:49 +0000 |
| commit | 1cfc35ab4c41c49743c8494bea23f168eccae879 (patch) | |
| tree | 8d415945f27092902a04c60b0713f0f7224c2267 /src/sort.c | |
| parent | sort: fix silent exit upon SIGPIPE from --compress-program (diff) | |
| download | coreutils-1cfc35ab4c41c49743c8494bea23f168eccae879.tar.gz coreutils-1cfc35ab4c41c49743c8494bea23f168eccae879.zip | |
sort: consistently diagnose access issues to --compress-program
* bootstrap.conf (gnulib_modules): Add findprog-in.
* src/sort.c: Include findprog.h.
(pipe_child): Look up the compress_program in $PATH and report errors
such as ENOENT or EACCES before invoking posix_spawnp.
This avoids inconsistency on systems that emulate posix_spawn through
fork/exec, as they would otherwise treat such a failure as a generic
failure and fail the sort, rather than continuing without compression.
Diffstat (limited to '')
| -rw-r--r-- | src/sort.c | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/src/sort.c b/src/sort.c index 78b2f69f9..3bb5cc8dd 100644 --- a/src/sort.c +++ b/src/sort.c @@ -36,6 +36,7 @@ #include "c-ctype.h" #include "fadvise.h" #include "filevercmp.h" +#include "findprog.h" #include "flexmember.h" #include "hard-locale.h" #include "hash.h" @@ -1056,6 +1057,8 @@ static int pipe_child (pid_t *pid, int pipefds[2], int tempfd, bool decompress, size_t tries) { + char const *resolved_compress_program; + char *compress_program_to_free; struct tempnode *saved_temphead; double wait_retry = 0.25; struct cs_status cs; @@ -1063,12 +1066,25 @@ pipe_child (pid_t *pid, int pipefds[2], int tempfd, bool decompress, posix_spawnattr_t attr; posix_spawn_file_actions_t actions; + /* Lookup the program before we spawn, so that we consistently + handle access issues to COMPRESS_PROGRAM, because on some + implementations/emulations of posix_spawn we get only a + generic (fatal) error from the child in that case. */ + resolved_compress_program = + find_in_given_path (compress_program, getenv ("PATH"), NULL, false); + if (resolved_compress_program == NULL) + return errno; + compress_program_to_free = nullptr; + if (resolved_compress_program != compress_program) + compress_program_to_free = (char *) resolved_compress_program; + if ((result = posix_spawnattr_init (&attr))) return result; if ((result = posix_spawnattr_setflags (&attr, POSIX_SPAWN_USEVFORK)) || (result = posix_spawn_file_actions_init (&actions))) { posix_spawnattr_destroy (&attr); + free (compress_program_to_free); return result; } @@ -1077,6 +1093,7 @@ pipe_child (pid_t *pid, int pipefds[2], int tempfd, bool decompress, int saved_errno = errno; posix_spawnattr_destroy (&attr); posix_spawn_file_actions_destroy (&actions); + free (compress_program_to_free); return saved_errno; } @@ -1102,11 +1119,16 @@ pipe_child (pid_t *pid, int pipefds[2], int tempfd, bool decompress, close (pipefds[1]); posix_spawnattr_destroy (&attr); posix_spawn_file_actions_destroy (&actions); + free (compress_program_to_free); return result; } - char const *const argv[] = { compress_program, decompress ? "-d" : nullptr, - nullptr }; + char const *const argv[] = + { + resolved_compress_program, + decompress ? "-d" : nullptr, + nullptr + }; /* At least NMERGE + 1 subprocesses are needed. More could be created, but uncontrolled subprocess generation can hurt performance significantly. @@ -1126,7 +1148,7 @@ pipe_child (pid_t *pid, int pipefds[2], int tempfd, bool decompress, saved_temphead = temphead; temphead = nullptr; - result = posix_spawnp (pid, compress_program, &actions, &attr, + result = posix_spawnp (pid, resolved_compress_program, &actions, &attr, (char * const *) argv, environ); temphead = saved_temphead; @@ -1147,6 +1169,7 @@ pipe_child (pid_t *pid, int pipefds[2], int tempfd, bool decompress, posix_spawnattr_destroy (&attr); posix_spawn_file_actions_destroy (&actions); + free (compress_program_to_free); if (result) { |
