]> git.ipfire.org Git - thirdparty/bash.git/commitdiff
allow some job notifications while running $PROMPT_COMMAND; allow notifications while...
authorChet Ramey <chet.ramey@case.edu>
Mon, 6 May 2024 15:25:35 +0000 (11:25 -0400)
committerChet Ramey <chet.ramey@case.edu>
Mon, 6 May 2024 15:25:35 +0000 (11:25 -0400)
15 files changed:
CWRU/CWRU.chlog
Makefile.in
bashline.c
builtins/common.h
builtins/evalfile.c
builtins/evalstring.c
eval.c
execute_cmd.c
jobs.c
jobs.h
nojobs.c
parse.y
shell.c
trap.c
unwind_prot.c

index c4cb56211179edae6a5d7a72bf0d65d51468630f..297916106ddfeadec7d0169f0be005c73f6367f7 100644 (file)
@@ -9327,3 +9327,46 @@ jobs.c
 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
index 8d9ffe19a3ebc09bcda986b1ab413b86cd49562c..51c55bf9bca5860a7b7c3f5e74726c2f002a7baa 100644 (file)
@@ -1103,7 +1103,7 @@ eval.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h $
 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
index 9df37a0ef423d17a47c0e7580613a3c470163f06..b638e0013b6b9a738ac3d7e0f49c2dce1570b474 100644 (file)
@@ -4545,7 +4545,7 @@ uw_unbind_readline_variables (void *ignore)
 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;
@@ -4627,7 +4627,8 @@ bash_execute_unix_command (int count, int key)
   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);
 
index 81ce259d914c6c8882d81df53c5849e229b2ff01..41437a33f9d8a14afa6cff2196cb8b73d114be49 100644 (file)
@@ -52,6 +52,7 @@ do { \
 #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 */
index 17a568a04c0d8fb2a1403e5b18decf0d3a24e811..14a8488c8a7bed1c1c2e5010c5a39fef0663ec4b 100644 (file)
@@ -1,6 +1,6 @@
 /* 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.
 
@@ -185,7 +185,7 @@ file_error_and_exit:
       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);
     }
 
@@ -203,7 +203,7 @@ file_error_and_exit:
            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);
              }
           }
index fedacdfc6209b38c0f36fdc686e1795de88b9fcc..eaa87d3dfb7146916a317cb9081348b42eb0c501 100644 (file)
@@ -247,6 +247,8 @@ parse_prologue (char *string, int flags, char *tag)
   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)
@@ -281,6 +283,9 @@ parse_prologue (char *string, int flags, char *tag)
   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 ();
@@ -302,6 +307,7 @@ parse_prologue (char *string, int flags, char *tag)
        (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
diff --git a/eval.c b/eval.c
index cbf408f0fedd7cace62e99ff1512cc1a4b2bbab0..c8f1116392b3164b226f5d5c464f4fb81c1c20b6 100644 (file)
--- a/eval.c
+++ b/eval.c
 #  include "bashhist.h"
 #endif
 
+#if defined (JOB_CONTROL)
+#  include "jobs.h"
+#endif
+
 static void send_pwd_to_eterm (void);
 static sighandler alrm_catcher (int);
 
@@ -343,6 +347,9 @@ parse_command (void)
      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
index 5a9477a438b89dbeb8db44b1e991cdda1ef9e4ec..8a5e43c3c42954096efe8fcc502aa1e2a5790634 100644 (file)
@@ -6081,7 +6081,7 @@ shell_execve (char *command, char **args, char **env)
       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
@@ -6119,7 +6119,7 @@ shell_execve (char *command, char **args, char **env)
                  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);
            }
@@ -6165,7 +6165,7 @@ shell_execve (char *command, char **args, char **env)
 #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);
        }
diff --git a/jobs.c b/jobs.c
index c0c9cb2b400e5bba9199836d6b7a68a813b1bc08..63082cfec09c05c199f591d791dd498c2e522525 100644 (file)
--- a/jobs.c
+++ b/jobs.c
@@ -231,6 +231,10 @@ int check_window_size = CHECKWINSIZE_DEFAULT;
 
 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);
@@ -3423,7 +3427,7 @@ notify_and_cleanup (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)
diff --git a/jobs.h b/jobs.h
index 31c4fd32d0672f0904878c3639a8a25dbceb3974..3711af2000ae9bb0a2c39d73dc73b9bc7e2c3277 100644 (file)
--- a/jobs.h
+++ b/jobs.h
@@ -222,6 +222,7 @@ extern struct jobstats js;
 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;
index c429b6e3398dbe9409a47491ee817d78e52cc429..3b32d12f3854ecb483f0a64a15b7b142227c9643 100644 (file)
--- a/nojobs.c
+++ b/nojobs.c
@@ -93,6 +93,9 @@ int check_window_size = CHECKWINSIZE_DEFAULT;
 /* 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
diff --git a/parse.y b/parse.y
index b347fbb5ea2c423856756056c505ce4580228e13..d232481d5996e7f60c19256ed9bb3650f432a41a 100644 (file)
--- a/parse.y
+++ b/parse.y
@@ -2461,10 +2461,10 @@ shell_getc (int remove_quoted_newline)
       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 ();
@@ -2951,7 +2951,7 @@ execute_variable_command (const char *command, const char *vname)
   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);
diff --git a/shell.c b/shell.c
index 84ac5c4ed6e9dac7163e8936ebd9b928c6a9b3dd..15e005d6cd7b99d98199919000c3d133bc542c27 100644 (file)
--- a/shell.c
+++ b/shell.c
@@ -1685,7 +1685,7 @@ open_shell_script (char *script_name)
        }
       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
diff --git a/trap.c b/trap.c
index d28791365def9a1679767e767a27d72938d88b62..9acd19739f95500dfe8380047c48f944e99ee9bb 100644 (file)
--- a/trap.c
+++ b/trap.c
@@ -483,8 +483,13 @@ run_pending_traps (void)
                }
 
              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 */
@@ -1049,8 +1054,11 @@ run_exit_trap (void)
 
       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;
@@ -1172,7 +1180,9 @@ _run_trap_internal (int sig, char *tag)
          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)
index 4a5195a649751927c9e07eb395088a7b91e89b9c..fbf5c85f8f9b0964ae67ade2149255686492d51d 100644 (file)
@@ -243,7 +243,7 @@ unwind_frame_discard_internal (char *tag)
     }
 
   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.
@@ -289,7 +289,7 @@ unwind_frame_run_internal (char *tag)
       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