diff -ru orig/bash-master/builtins/set.def new/bash-master/builtins/set.def --- orig/bash-master/builtins/set.def 2022-01-05 00:03:45.000000000 +0200 +++ new/bash-master/builtins/set.def 2022-07-05 11:54:31.545828400 +0300 @@ -76,6 +76,8 @@ emacs use an emacs-style line editing interface #endif /* READLINE */ errexit same as -e + errfail execution of command lists will stop whenever + a single command return non-zero status errtrace same as -E functrace same as -T hashall same as -h @@ -196,6 +198,7 @@ { "emacs", '\0', (int *)NULL, set_edit_mode, get_edit_mode }, #endif { "errexit", 'e', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, + { "errfail", '\0', &errfail_opt, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, { "errtrace", 'E', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, { "functrace", 'T', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, { "hashall", 'h', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, @@ -655,6 +658,7 @@ { pipefail_opt = 0; ignoreeof = 0; +/* errfail_opt = 0 ; errfail IS inherit by sub-shells */ #if defined (STRICT_POSIX) posixly_correct = 1; diff -ru orig/bash-master/execute_cmd.c new/bash-master/execute_cmd.c --- orig/bash-master/execute_cmd.c 2022-01-05 00:03:45.000000000 +0200 +++ new/bash-master/execute_cmd.c 2022-07-05 13:03:18.379533800 +0300 @@ -2706,7 +2706,7 @@ QUIT; #if 1 - execute_command (command->value.Connection->first); + exec_result = execute_command (command->value.Connection->first); #else execute_command_internal (command->value.Connection->first, asynchronous, pipe_in, pipe_out, @@ -2714,10 +2714,15 @@ #endif QUIT; - optimize_fork (command); /* XXX */ - exec_result = execute_command_internal (command->value.Connection->second, + + /* With errfail, the ';' is similar to '&&' */ + /* Execute the second part, only if first part was OK */ + if ( !errfail_opt || exec_result == EXECUTION_SUCCESS ) { + optimize_fork (command); /* XXX */ + exec_result = execute_command_internal (command->value.Connection->second, asynchronous, pipe_in, pipe_out, fds_to_close); + } ; executing_list--; break; diff -ru orig/bash-master/flags.c new/bash-master/flags.c --- orig/bash-master/flags.c 2022-01-05 00:03:45.000000000 +0200 +++ new/bash-master/flags.c 2022-07-05 13:42:12.287799400 +0300 @@ -156,6 +156,12 @@ with a 0 status, the status of the pipeline is 0. */ int pipefail_opt = 0; +/* Non-zero means that when executing connected commands (';' or new lines) + the sequence will be stopped when any individual commands return a non-zero + status. Similar to '&&'. Used for improved error handling */ + +int errfail_opt = 0; + /* **************************************************************** */ /* */ /* The Flags ALIST. */ diff -ru orig/bash-master/flags.h new/bash-master/flags.h --- orig/bash-master/flags.h 2022-01-05 00:03:45.000000000 +0200 +++ new/bash-master/flags.h 2022-07-05 11:25:14.515741700 +0300 @@ -48,7 +48,7 @@ echo_command_at_execute, noclobber, hashing_enabled, forced_interactive, privileged_mode, jobs_m_flag, asynchronous_notification, interactive_comments, no_symbolic_links, - function_trace_mode, error_trace_mode, pipefail_opt; + function_trace_mode, error_trace_mode, pipefail_opt, errfail_opt; /* -c, -s invocation options -- not really flags, but they show up in $- */ extern int want_pending_command, read_from_stdin;