fix small race condition when using lastpipe and adding the last process to the pipeline; fix bug that could cause the shell to exit even if execfail' is enabled if errexit' is enabled and the pathname to exec doesn't exist

This commit is contained in:
Chet Ramey
2026-10-07 10:36:29 -04:00
parent 1c20880e16
commit 7cfdb340d2
10 changed files with 5854 additions and 21 deletions
+23
View File
@@ -13407,3 +13407,26 @@ builtins/help.def
doc/bash.1,doc/bashref.texi
- help: document new -L option
Feature suggestion from https://lists.gnu.org/archive/html/bug-bash/2026-06/msg00064.html
9/24
----
execute_cmd.c
- execute_pipeline: when executing the last element of a pipeline
with `lastpipe' enabled, make sure to block SIGCHLD around the
call to append_process because we are manipulating the job list
and job struct
Report and fix from Markus Wangler <markus@team-wangler.de>
jobs.c
- append_process: rearrange code to further shrink the window when
manipulating the pipeline
9/25
----
error.c
- file_error: most callers do not anticipate this will exit the shell
if `errexit' is enabled, which it does because it calls report_error.
Change to call internal_error instead and audit callers, especially
the `exec' builtin, since the `execfail' shopt is supposed to
inhibit this.
Report from Zev Weiss <zev@bewilderbeest.net>
+2
View File
@@ -633,6 +633,8 @@ po/ko.gmo f
po/ko.po f
po/lt.gmo f
po/lt.po f
po/lv.gmo f
po/lv.po f
po/nl.gmo f
po/nb.po f
po/nb.gmo f
+2 -2
View File
@@ -125,7 +125,7 @@ get_name_for_error (void)
void
file_error (const char *filename)
{
report_error ("%s: %s", filename, strerror (errno));
internal_error ("%s: %s", filename, strerror (errno));
}
void
@@ -163,7 +163,7 @@ programming_error (const char *format, ...)
}
/* Print an error message and, if `set -e' has been executed, exit the
shell. Used in this file by file_error and programming_error. Used
shell. Used in this file by programming_error. Used
outside this file mostly to report substitution and expansion errors,
and for bad invocation options. */
void
+6 -2
View File
@@ -2769,6 +2769,7 @@ execute_pipeline (COMMAND *command, int asynchronous, int pipe_in, int pipe_out,
begin_unwind_frame ("lastpipe-exec");
lstdin = -2; /* -1 is special, meaning fd 0 is closed */
lastpipe_jid = NO_JOB;
/* If the `lastpipe' option is set with shopt, and job control is not
enabled, execute the last element of non-async pipelines in the
current shell environment. */
@@ -2807,7 +2808,8 @@ execute_pipeline (COMMAND *command, int asynchronous, int pipe_in, int pipe_out,
restore_stdin (lstdin);
#if defined (JOB_CONTROL)
UNBLOCK_CHILD (oset);
if (lastpipe_jid == NO_JOB) /* already unblocked above */
UNBLOCK_CHILD (oset);
#endif
QUIT;
@@ -2817,7 +2819,9 @@ execute_pipeline (COMMAND *command, int asynchronous, int pipe_in, int pipe_out,
#if defined (JOB_CONTROL)
if (INVALID_JOB (lastpipe_jid) == 0)
{
BLOCK_CHILD (set, oset);
append_process (savestring (the_printed_command_except_trap), dollar_dollar_pid, exec_result, lastpipe_jid);
UNBLOCK_CHILD (oset);
lstdin = wait_for (lastpid, 0);
}
else
@@ -2893,7 +2897,7 @@ execute_list (COMMAND *command, int asynchronous, int pipe_in, int pipe_out, str
QUIT;
n = count_nodes (command);
/*itrace("execute_list: count_nodes returns %d", n);*/
/*itrace("execute_list: count_nodes returns %d", n);*/
csind = cssize = n + 1;
cstack = (COMMAND **) xreallocarray (NULL, cssize, sizeof (COMMAND *));
+3 -2
View File
@@ -1642,7 +1642,8 @@ add_process (char *name, pid_t pid)
}
/* Create a (dummy) PROCESS with NAME, PID, and STATUS, and make it the last
process in jobs[JID]->pipe. Used by the lastpipe code. */
process in jobs[JID]->pipe. Used by the lastpipe code. Must be called
with SIGCHLD blocked. */
void
append_process (char *name, pid_t pid, int status, int jid)
{
@@ -1658,8 +1659,8 @@ append_process (char *name, pid_t pid, int status, int jid)
for (p = jobs[jid]->pipe; p->next != jobs[jid]->pipe; p = p->next)
;
p->next = t;
t->next = jobs[jid]->pipe;
p->next = t;
}
#if 0
+1 -1
View File
@@ -1,2 +1,2 @@
# Set of available languages.
en@quot en@boldquot af ar bg ca cs da de el eo es et fi fr ga gl hr hu id it ja ka kk ko lt nb nl pl pt pt_BR ro ru sk sl sq sr sv tr uk vi zh_CN zh_TW
en@quot en@boldquot af ar bg ca cs da de el eo es et fi fr ga gl hr hu id it ja ka kk ko lt lv nb nl pl pt pt_BR ro ru sk sl sq sr sv tr uk vi zh_CN zh_TW
BIN
View File
Binary file not shown.
+4 -14
View File
@@ -4552,18 +4552,6 @@ msgstr ""
" Mengembalikan sukses kecuali N adalah negatif atau lebih besar dari $#."
#: builtins.c:1244 builtins.c:1260
#, fuzzy
#| msgid ""
#| "Execute commands from a file in the current shell.\n"
#| " \n"
#| " Read and execute commands from FILENAME in the current shell. The\n"
#| " entries in $PATH are used to find the directory containing FILENAME.\n"
#| " If any ARGUMENTS are supplied, they become the positional parameters\n"
#| " when FILENAME is executed.\n"
#| " \n"
#| " Exit Status:\n"
#| " Returns the status of the last command executed in FILENAME; fails if\n"
#| " FILENAME cannot be read."
msgid ""
"Execute commands from a file in the current shell.\n"
" \n"
@@ -4579,8 +4567,10 @@ msgid ""
msgstr ""
"Jalankan perintah dari sebuah berkas dalam shell sekarang.\n"
" \n"
" Baca dan jalankan perintah dari FILENAME dan kembali. Nama jalur dalam\n"
" $PATH digunakan untuk mencari direktori yang berisi NAMABERKAS. Jika salah satu\n"
" Baca dan jalankan perintah dari FILENAME dalam shell sekarang. Jika\n"
" opsi -p diberikan, argumen PATH dijalankan sebagai sebuah colon-\n"
" daftar terpisah dari direktori untuk mencari untuk FILENAME. Jika -p tidak\n"
" diberikan, $PATH dicari untuk mencari NAMABERKAS. Jika salah satu\n"
" dari ARGUMENTS diberikan, mereka menjadi parameter posisi ketika\n"
" NAMABERKAS dijalankan.\n"
" \n"
BIN
View File
Binary file not shown.
+5813
View File
File diff suppressed because it is too large Load Diff