jobs.h
- LONGEST_SIGNAL_DESC: update to 27 (macos SIGPROF). This changes the
test output
+
+ 5/3
+ ---
+builtins/common.h
+ - SEVAL_NOTIFY: new flag for parse_and_execute; means we want job
+ notifications even though we're not interactive at this time and
+ would not satisfy the conditions
+
+builtins/evalstring.c
+ - parse_prologue: if SEVAL_NOTIFY is supplied, unwind-protect
+ want_job_notifications and set it to 1
+
+jobs.c,jobs.h.nojobs.c
+ - want_job_notifications: new global variable, initialized to 0
+
+jobs.c
+ - notify_and_cleanup: notify about dead jobs if want_job_notifications
+ is non-zero
+
+parse.y
+ - execute_variable_command: call parse_and_execute with the SEVAL_NOTIFY
+ flag
+
+eval.c
+ - reader_loop: call notify_and_cleanup before executing $PROMPT_COMMAND
+ if the shell is interactive and prompting
+
+trap.c
+ - run_pending_traps,_run_trap_internal,run_exit_trap: add SEVAL_NOTIFY
+ to the flags for parse_and_execute if the shell is interactive
+
+bashline.c
+ - bash_execute_unix_command: add SEVAL_NOTIFY to the flags for
+ parse_and_execute if the shell is interactive
+ Rest of fix for report by Koichi Murase <myoga.murase@gmail.com>
+ on 11/14/2022
+
+ 5/6
+ ---
+
+execute_cmd.c,shell.c,builtins/evalfile.c,unwind_prot.c
+ - change some translated error messages to make the text more uniform
+ and reduce the number of gettext() calls
eval.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h
eval.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h
eval.o: make_cmd.h subst.h sig.h pathnames.h externs.h parser.h
-eval.o: input.h execute_cmd.h
+eval.o: input.h execute_cmd.h jobs.h
eval.o: $(BASHINCDIR)/unlocked-io.h
eval.o: bashhist.h assoc.h ${BASHINCDIR}/ocache.h ${BASHINCDIR}/chartypes.h
execute_cmd.o: config.h bashtypes.h ${BASHINCDIR}/filecntl.h ${BASHINCDIR}/posixstat.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h
int
bash_execute_unix_command (int count, int key)
{
- int type;
+ int type, pflags;
register int i, r;
intmax_t mi;
sh_parser_state_t ps;
add_unwind_protect (uw_unbind_readline_variables, 0);
add_unwind_protect (uw_restore_parser_state, &ps);
add_unwind_protect (uw_rl_set_signals, 0);
- r = parse_and_execute (savestring (cmd), "bash_execute_unix_command", SEVAL_NOHIST);
+ pflags = interactive_shell ? (SEVAL_NOTIFY|SEVAL_NOHIST) : SEVAL_NOHIST;
+ r = parse_and_execute (savestring (cmd), "bash_execute_unix_command", pflags);
rl_set_signals ();
restore_parser_state (&ps);
#define SEVAL_ONECMD 0x100 /* only allow a single command */
#define SEVAL_NOHISTEXP 0x200 /* inhibit history expansion */
#define SEVAL_NOOPTIMIZE 0x400 /* don't try to set optimization flags */
+#define SEVAL_NOTIFY 0x800 /* want job notifications */
/* Flags for describe_command, shared between type.def and command.def */
#define CDESC_ALL 0x001 /* type -a */
/* evalfile.c - read and evaluate commands from a file or file descriptor */
-/* Copyright (C) 1996-2017,2022-2023 Free Software Foundation, Inc.
+/* Copyright (C) 1996-2017,2022-2024 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
check_binary_file (string, (nr > 80) ? 80 : nr))
{
free (string);
- (*errfunc) (_("%s: cannot execute binary file"), filename);
+ (*errfunc) ("%s: %s", filename, _("cannot execute binary file"));
return ((flags & FEVAL_BUILTIN) ? EX_BINARY_FILE : -1);
}
if ((flags & FEVAL_BUILTIN) && ++nnull > 256)
{
free (string);
- (*errfunc) (_("%s: cannot execute binary file"), filename);
+ (*errfunc) ("%s: %s", filename, _("cannot execute binary file"));
return ((flags & FEVAL_BUILTIN) ? EX_BINARY_FILE : -1);
}
}
unwind_protect_int (builtin_ignoring_errexit);
if (flags & (SEVAL_NONINT|SEVAL_INTERACT))
unwind_protect_int (interactive);
+ if (flags & SEVAL_NOTIFY)
+ unwind_protect_int (want_job_notifications);
#if defined (HISTORY)
if (parse_and_execute_level == 0)
if (flags & (SEVAL_NONINT|SEVAL_INTERACT))
interactive = (flags & SEVAL_NONINT) ? 0 : 1;
+ if (flags & SEVAL_NOTIFY)
+ want_job_notifications = 1;
+
#if defined (HISTORY)
if (flags & SEVAL_NOHIST)
bash_history_disable ();
(flags & SEVAL_RESETLINE) -> reset line_number to 1
(flags & SEVAL_NOHISTEXP) -> history_expansion_inhibited -> 1
(flags & SEVAL_NOOPTIMIZE) -> don't try to turn on optimizing flags
+ (flags & SEVAL_NOTIFY) -> print job status notifications
*/
int
# include "bashhist.h"
#endif
+#if defined (JOB_CONTROL)
+# include "jobs.h"
+#endif
+
static void send_pwd_to_eterm (void);
static sighandler alrm_catcher (int);
actually printed. */
if (interactive && bash_input.type != st_string && parser_expanding_alias() == 0)
{
+#if defined (JOB_CONTROL)
+ notify_and_cleanup ();
+#endif
#if defined (READLINE)
if (no_line_editing || (bash_input.type == st_stdin && parser_will_prompt ()))
#endif
last_command_exit_value = (i == ENOENT) ? EX_NOTFOUND : EX_NOEXEC; /* XXX Posix.2 says that exit status is 126 */
if (file_isdir (command))
#if defined (EISDIR)
- internal_error (_("%s: %s"), command, strerror (EISDIR));
+ internal_error ("%s: %s", command, strerror (EISDIR));
#else
internal_error (_("%s: is a directory"), command);
#endif
interp[ilen] = 'M';
interp[ilen + 1] = '\0';
}
- sys_error (_("%s: %s: bad interpreter"), command, interp);
+ sys_error ("%s: %s: %s", command, interp, _("bad interpreter"));
FREE (interp);
return (EX_NOEXEC);
}
#endif
if (check_binary_file (sample, sample_len))
{
- internal_error (_("%s: cannot execute binary file: %s"), command, strerror (i));
+ internal_error ("%s: %s: %s", command, _("cannot execute binary file"), strerror (i));
errno = i;
return (EX_BINARY_FILE);
}
PROCESS *last_procsub_child = (PROCESS *)NULL;
+/* Set to non-zero if you want to force job notifications even in contexts
+ where the shell would defer them. */
+int want_job_notifications = 0;
+
/* Functions local to this file. */
void debug_print_pgrps (void);
if (jobs_list_frozen > 0)
return;
- if (interactive || interactive_shell == 0 || sourcelevel || (interactive_shell && running_trap))
+ if (want_job_notifications || interactive || interactive_shell == 0 || sourcelevel)
notify_of_job_status ();
if (jobs_list_frozen < 0)
extern pid_t original_pgrp, shell_pgrp, pipeline_pgrp;
extern volatile pid_t last_made_pid, last_asynchronous_pid;
extern int asynchronous_notification;
+extern int want_job_notifications;
extern int already_making_children;
extern int running_in_background;
/* We don't have job control. */
int job_control = 0;
+/* and don't want job notifications */
+int want_job_notifications = 0;
+
int running_in_background = 0; /* can't tell without job control */
/* STATUS and FLAGS are only valid if pid != NO_PID
if (interactive_shell == 0 || SHOULD_PROMPT())
{
#if defined (JOB_CONTROL)
- /* This can cause a problem when reading a command as the result
- of a trap, when the trap is called from flush_child. This call
- had better not cause jobs to disappear from the job table in
- that case, or we will have big trouble. */
+ /* This can cause a problem when reading a command as the result
+ of a trap, when the trap is called from flush_child. This call
+ had better not cause jobs to disappear from the job table in
+ that case, or we will have big trouble. */
notify_and_cleanup ();
#else /* !JOB_CONTROL */
cleanup_dead_jobs ();
save_parser_state (&ps);
last_lastarg = save_lastarg ();
- parse_and_execute (savestring (command), vname, SEVAL_NONINT|SEVAL_NOHIST|SEVAL_NOOPTIMIZE);
+ parse_and_execute (savestring (command), vname, SEVAL_NONINT|SEVAL_NOHIST|SEVAL_NOOPTIMIZE|SEVAL_NOTIFY);
restore_parser_state (&ps);
bind_lastarg (last_lastarg);
}
else if (sample_len > 0 && (check_binary_file (sample, sample_len)))
{
- internal_error (_("%s: cannot execute binary file"), filename);
+ internal_error ("%s: %s", filename, _("cannot execute binary file"));
#if defined (JOB_CONTROL)
end_job_control (); /* just in case we were run as bash -i script */
#endif
}
if (function_code == 0)
- /* XXX is x always last_command_exit_value? */
- x = parse_and_execute (trap_command, "trap", SEVAL_NONINT|SEVAL_NOHIST|SEVAL_RESETLINE|SEVAL_NOOPTIMIZE);
+ {
+ int pflags;
+ pflags = interactive_shell ? SEVAL_NOTIFY : 0;
+ pflags |= SEVAL_NONINT|SEVAL_NOHIST|SEVAL_RESETLINE|SEVAL_NOOPTIMIZE;
+ /* XXX is x always last_command_exit_value? */
+ x = parse_and_execute (trap_command, "trap", pflags);
+ }
else
{
parse_and_execute_cleanup (sig + 1); /* XXX - could use -1 */
if (code == 0 && function_code == 0)
{
+ int pflags;
+ pflags = interactive_shell ? SEVAL_NOTIFY : 0;
+ pflags |= SEVAL_NONINT|SEVAL_NOHIST|SEVAL_RESETLINE|SEVAL_NOOPTIMIZE;
reset_parser ();
- parse_and_execute (trap_command, "exit trap", SEVAL_NONINT|SEVAL_NOHIST|SEVAL_RESETLINE|SEVAL_NOOPTIMIZE);
+ parse_and_execute (trap_command, "exit trap", pflags);
}
else if (code == ERREXIT)
retval = last_command_exit_value;
function_code = setjmp_nosigs (return_catch);
}
- flags = SEVAL_NONINT|SEVAL_NOHIST|SEVAL_NOOPTIMIZE;
+ /* XXX - reconsider this for DEBUG_TRAP, RETURN_TRAP, ERROR_TRAP? */
+ flags = interactive_shell ? SEVAL_NOTIFY : 0;
+ flags |= SEVAL_NONINT|SEVAL_NOHIST|SEVAL_NOOPTIMIZE;
if (sig != DEBUG_TRAP && sig != RETURN_TRAP && sig != ERROR_TRAP)
flags |= SEVAL_RESETLINE;
if (function_code == 0)
}
if (found == 0)
- internal_warning (_("unwind_frame_discard: %s: frame not found"), tag);
+ internal_warning ("unwind_frame_discard: %s: %s", tag, _("frame not found"));
}
/* Restore the value of a variable, based on the contents of SV.
uwpfree (elt);
}
if (tag && found == 0)
- internal_warning (_("unwind_frame_run: %s: frame not found"), tag);
+ internal_warning ("unwind_frame_run: %s: %s", tag, _("frame not found"));
}
static void