]> git.ipfire.org Git - thirdparty/bash.git/commitdiff
optimize asynchronous function invocations; fix for running return from trap while...
authorChet Ramey <chet.ramey@case.edu>
Thu, 15 Aug 2024 20:37:54 +0000 (16:37 -0400)
committerChet Ramey <chet.ramey@case.edu>
Thu, 15 Aug 2024 20:37:54 +0000 (16:37 -0400)
12 files changed:
CWRU/CWRU.chlog
MANIFEST
builtins/common.h
builtins/evalstring.c
execute_cmd.c
lib/readline/histexpand.c
lib/readline/histlib.h
lib/readline/histsearch.c
lib/readline/search.c
lib/readline/signals.c
parse.y
trap.c

index 835f24733aa4d37d27d505c2349531ba0e1a7e87..e87dec7330d2a99bff8ea6af6376d5cf2af34c36 100644 (file)
@@ -9929,3 +9929,65 @@ builtins/read.def
          zungetc to push the delimiter back, adjust mbchar, and return what
          we read so far to be added as single bytes
          From a report by Kerin Millar <kfm@plushkava.net>
+
+                                   8/7
+                                   ---
+builtins/evalstring.c
+       - can_optimize_connection: only check bash_input.location.string if
+         bash_input.type == st_string, in case we want to use this in other
+         contexts. If we do, the caller *must* make sure it's the last
+         command in the calling context
+
+execute_cmd.c
+       - execute_subshell_builtin_or_function: if this is an async function
+         call, try to optimize away the fork before the last simple command
+         in the function body by calling optimize_shell_function
+       - execute_command_internal: if we have a simple command for which
+         CMD_TRY_OPTIMIZING is set in a SUBSHELL_ASYNC subshell environment,
+         try to set CMD_NO_FORK by checking via should_optimize_fork
+
+                                   8/9
+                                   ---
+parse.y
+       - yy_readline_get: before calling readline, call rl_clear_signals to
+         reset the signal handling disposition to a known state. Most of the
+         time it's a no-op
+
+lib/readline/signals.c
+       - _rl_handle_signal: make the call to sigprocmask(SIG_UNBLOCK,...
+         more symmetric with the corresponding call to SIG_BLOCK
+
+trap.c
+       - run_pending_traps: before calling run_interrupt_trap, restore
+         running_trap and trap_return_context, since _run_trap_internal
+         will save and restore them, too
+
+builtins/read.def
+       - read_builtin: if -e is supplied, make sure to install unwind-protects
+         to reset the attempted completion function and the event hook even
+         if the timeout is not supplied.
+         Report from Oguz <oguzismailuysal@gmail.com>
+
+                                  8/12
+                                  ----
+lib/readline/histsearch.c,lib/readline/histlib.h
+       - history_search_internal: takes a new argument, LINEDIR, saying which
+         direction to perform the substring/pattern search in the line,
+         decoupling it from the direction through the history list; changed
+         all callers (history_search, history_search_prefix, _hs_history_search,
+         _hs_history_patsearch)
+       - _hs_history_search,_hs_history_patsearch: takes the same new LINEDIR
+         argument, just passes it to history_search_internal; changed all
+         callers (noninc_search_from_pos)
+
+lib/readline/search.c
+       - noninc_search_from_pos: changed calls to _hs_history_search and
+         _hs_history_patsearch
+
+lib/readline/histexpand.c
+       - get_history_event: instead of using function pointers to a history
+         search function, set the right flags and just call _hs_history_search
+         with those flags using -1 for list direction and line direction
+
+
+
index 55a3c41a444b34c5d3e4f3fe9ccfa003836dfc71..2d8b4311019e88c260f7fca2838b1724a390dadf 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -622,6 +622,8 @@ po/it.gmo           f
 po/it.po               f
 po/ja.gmo              f
 po/ja.po               f
+po/ka.gmo              f
+po/ka.po               f
 po/ko.gmo              f
 po/ko.po               f
 po/lt.gmo              f
index 41437a33f9d8a14afa6cff2196cb8b73d114be49..99684920459e6074fb27348ed351f9c1172be4a0 100644 (file)
@@ -216,6 +216,7 @@ extern int parse_and_execute (char *, const char *, int);
 extern int evalstring (char *, const char *, int);
 extern void parse_and_execute_cleanup (int);
 extern int parse_string (char *, const char *, int, COMMAND **, char **);
+extern int should_optimize_fork (COMMAND *, int);
 extern int should_suppress_fork (COMMAND *);
 extern int can_optimize_connection (COMMAND *);
 extern int can_optimize_cat_file (COMMAND *);
index 2ea4016207cac8496be25a2c32746497b431fcdf..8a9cf2d731e148534c7f54028c91b4ecb67f90f0 100644 (file)
@@ -138,7 +138,7 @@ should_suppress_fork (COMMAND *command)
 int
 can_optimize_connection (COMMAND *command)
 {
-  return (*bash_input.location.string == '\0' &&
+  return ((bash_input.type != st_string || *bash_input.location.string == '\0') &&
          parser_expanding_alias () == 0 &&
          (command->value.Connection->connector == AND_AND || command->value.Connection->connector == OR_OR || command->value.Connection->connector == ';') &&
          command->value.Connection->second->type == cm_simple);
index 6fd69602e1cdfeca09f462724da2019f82c530ea..cda73a788cae1b1e3dc8c3df59111c0af58d702e 100644 (file)
@@ -913,6 +913,18 @@ execute_command_internal (COMMAND *command, int asynchronous, int pipe_in, int p
        begin_unwind_frame ("simple_lineno");
        add_unwind_protect (uw_restore_lineno, (void *) (intptr_t) save_line_number);
 
+       /* Limit the scope of this attempted optimization for now: async
+          commands for which TRY_OPTIMIZING is set (see call to optimize_shell_function
+          for async functions in execute_subshell_builtin_or_function below)
+          in interactive and script shells. */
+       if ((command->flags & CMD_TRY_OPTIMIZING) &&
+           (subshell_environment & SUBSHELL_ASYNC) && startup_state < 2 &&
+           should_optimize_fork (command, 0))
+         {
+           command->flags |= CMD_NO_FORK;
+           command->value.Simple->flags |= CMD_NO_FORK;
+         }
+
        SET_LINE_NUMBER (command->value.Simple->line);
        exec_result =
          execute_simple_command (command->value.Simple, pipe_in, pipe_out,
@@ -5523,6 +5535,8 @@ execute_subshell_builtin_or_function (WORD_LIST *words, REDIRECT *redirects,
     }
   else
     {
+      if (async)
+       optimize_shell_function (function_cell (var));
       r = execute_function (var, words, flags, fds_to_close, async, 1);
       fflush (stdout);
       subshell_exit (r);
index 21185f9dc098ca633ae5e05b76d1f260b0c311de..db9aa185b81dd27d650e8c43e7e1cf8d65dd7c3e 100644 (file)
@@ -141,7 +141,7 @@ get_history_event (const char *string, int *caller_index, int delimiting_quote)
   register char c;
   HIST_ENTRY *entry;
   int which, sign, local_index, substring_okay;
-  _hist_search_func_t *search_func;
+  int search_flags;
   char *temp;
 
   /* The event can be specified in a number of ways.
@@ -269,10 +269,10 @@ get_history_event (const char *string, int *caller_index, int delimiting_quote)
         FAIL_SEARCH ();
     }
 
-  search_func = substring_okay ? history_search : history_search_prefix;
+  search_flags = substring_okay ? NON_ANCHORED_SEARCH : ANCHORED_SEARCH;
   while (1)
     {
-      local_index = (*search_func) (temp, -1);
+      local_index = _hs_history_search (temp, -1, -1, search_flags);
 
       if (local_index < 0)
        FAIL_SEARCH ();
index da8e6533dd5fd78ff013d746b2d659b8289d0252..d41b4ea12c62d0af404c483affa15640d871d8ff 100644 (file)
@@ -83,8 +83,8 @@
 /* internal extern function declarations used by other parts of the library */
 
 /* histsearch.c */
-extern int _hs_history_patsearch (const char *, int, int);
-extern int _hs_history_search (const char *, int, int);
+extern int _hs_history_patsearch (const char *, int, int, int);
+extern int _hs_history_search (const char *, int, int, int);
 
 /* history.c */
 extern void _hs_replace_history_data (int, histdata_t *, histdata_t *);
index b43ead1ffea461311419d8666b78fe0a4c904827..36c469963c994ef998ccdb570946321136305c52 100644 (file)
@@ -1,6 +1,6 @@
 /* histsearch.c -- searching the history list. */
 
-/* Copyright (C) 1989, 1992-2009,2017,2021,2023 Free Software Foundation, Inc.
+/* Copyright (C) 1989, 1992-2009,2017,2021-2024 Free Software Foundation, Inc.
 
    This file contains the GNU History Library (History), a set of
    routines for managing the text of previously typed lines.
    string. */
 char *history_search_delimiter_chars = (char *)NULL;
 
-static int history_search_internal (const char *, int, int);
+static int history_search_internal (const char *, int, int, int);
 
 /* Search the history for STRING, starting at history_offset.
-   If DIRECTION < 0, then the search is through previous entries, else
-   through subsequent.  If ANCHORED is non-zero, the string must
+   If LISTDIR < 0, then the search is through previous entries, else
+   through subsequent. If ANCHORED is non-zero, the string must
    appear at the beginning of a history line, otherwise, the string
-   may appear anywhere in the line.  If PATSEARCH is non-zero, and fnmatch(3)
-   is available, fnmatch is used to match the string instead of a simple
-   string comparison. If IGNORECASE is set, the string comparison is
-   performed case-insensitively. If the string is found, then
+   may appear anywhere in the line. If the search is not anchored, LINEDIR
+   determines how the line is searched: if it is < 0, the search proceeds
+   from the end of the line to the beginning, otherwise the substring search
+   starts at the beginning of each history entry. If PATSEARCH is non-zero,
+   and fnmatch(3) is available, fnmatch is used to match the string instead
+   of a simple string comparison. If IGNORECASE is set, the string comparison
+   is performed case-insensitively. If the string is found, then
    current_history () is the history entry, and the value of this
-   function is the offset in the line of that history entry that the
-   string was found in.  Otherwise, nothing is changed, and a -1 is
-   returned. */
+   function is the offset in the line of that history entry in which the
+   string was found. Otherwise, nothing is changed, and a -1 is returned. */
 
 static int
-history_search_internal (const char *string, int direction, int flags)
+history_search_internal (const char *string, int listdir, int linedir, int flags)
 {
   int i, reverse;
   char *line;
@@ -80,7 +82,7 @@ history_search_internal (const char *string, int direction, int flags)
   HIST_ENTRY **the_history;    /* local */
 
   i = history_offset;
-  reverse = (direction < 0);
+  reverse = (listdir < 0);
   anchored = (flags & ANCHORED_SEARCH);
 #if defined (HAVE_FNMATCH)
   patsearch = (flags & PATTERN_SEARCH);
@@ -157,7 +159,7 @@ history_search_internal (const char *string, int direction, int flags)
        }
 
       /* Do substring search. */
-      if (reverse)
+      if (linedir < 0)         /* search backwards from end */
        {
          size_t ll;
 
@@ -240,7 +242,7 @@ history_search_internal (const char *string, int direction, int flags)
 }
 
 int
-_hs_history_patsearch (const char *string, int direction, int flags)
+_hs_history_patsearch (const char *string, int listdir, int linedir, int flags)
 {
   char *pat;
   size_t len, start;
@@ -289,45 +291,48 @@ _hs_history_patsearch (const char *string, int direction, int flags)
   pat = string;
 #endif
 
-  ret = history_search_internal (pat, direction, flags|PATTERN_SEARCH);
+  ret = history_search_internal (pat, listdir, linedir, flags|PATTERN_SEARCH);
 
   if (pat != string)
     xfree (pat);
   return ret;
 }
        
-/* Do a non-anchored search for STRING through the history in DIRECTION. */
+/* Do a non-anchored search for STRING through the history list in direction
+   LISTDIR. */
 int
-history_search (const char *string, int direction)
+history_search (const char *string, int listdir)
 {
-  return (history_search_internal (string, direction, NON_ANCHORED_SEARCH));
+  return (history_search_internal (string, listdir, listdir, NON_ANCHORED_SEARCH));
 }
 
-/* Do an anchored search for string through the history in DIRECTION. */
+/* Do an anchored search for string through the history list in direction
+   LISTDIR. */
 int
-history_search_prefix (const char *string, int direction)
+history_search_prefix (const char *string, int listdir)
 {
-  return (history_search_internal (string, direction, ANCHORED_SEARCH));
+  return (history_search_internal (string, listdir, listdir, ANCHORED_SEARCH));
 }
 
-/* At some point, make this public for users of the history library. */
+/* Perform a history search for STRING, letting the caller specify the flags.
+   At some point, make this public for users of the history library. */
 int
-_hs_history_search (const char *string, int direction, int flags)
+_hs_history_search (const char *string, int listdir, int linedir, int flags)
 {
-  return (history_search_internal (string, direction, flags));
+  return (history_search_internal (string, listdir, linedir, flags));
 }
 
-/* Search for STRING in the history list.  DIR is < 0 for searching
-   backwards.  POS is an absolute index into the history list at
-   which point to begin searching. */
+/* Search for STRING in the history list.  LISTDIR is < 0 for searching
+   backwards through the list.  POS is an absolute index into the history
+   list where the search should begin. */
 int
-history_search_pos (const char *string, int dir, int pos)
+history_search_pos (const char *string, int listdir, int pos)
 {
   int ret, old;
 
   old = where_history ();
   history_set_pos (pos);
-  if (history_search (string, dir) == -1)
+  if (history_search (string, listdir) == -1)
     {
       history_set_pos (old);
       return (-1);
index 96bb83a5fda242979dcc73779be48b63c7a1d453..d7a441e23a6c438bf77f41d300c00cfbaa97f82b 100644 (file)
@@ -174,12 +174,12 @@ noninc_search_from_pos (char *string, int pos, int dir, int flags, int *ncp)
     }
 
   if (flags & SF_PATTERN)
-    ret = _hs_history_patsearch (s, dir, sflags);
+    ret = _hs_history_patsearch (s, dir, dir, sflags);
   else
     {
       if (_rl_search_case_fold)
        sflags |= CASEFOLD_SEARCH;
-      ret = _hs_history_search (s, dir, sflags);
+      ret = _hs_history_search (s, dir, dir, sflags);
     }
   RL_UNSETSTATE(RL_STATE_SEARCH);
 
index 706035e9f415cbafee90512979bdad8959735571..a67f62146d7076b02aeedc806b2f1159598201a0 100644 (file)
@@ -279,7 +279,7 @@ _rl_handle_signal (int sig)
 #if defined (HAVE_POSIX_SIGNALS)
       /* Unblock any signal(s) blocked above */
       if (block_sig)
-       sigprocmask (SIG_UNBLOCK, &oset, (sigset_t *)NULL);
+       sigprocmask (SIG_UNBLOCK, &set, &oset);
 #endif
 
       /* We don't have to bother unblocking the signal because we are not
diff --git a/parse.y b/parse.y
index 1f7527a520282cee42f0214ea659b75241c123a1..7e9e013e2d052ba2d060ed47d406d1aac1bcd62b 100644 (file)
--- a/parse.y
+++ b/parse.y
@@ -1621,6 +1621,7 @@ yy_readline_get (void)
       old_sigint = IMPOSSIBLE_TRAP_HANDLER;
       if (signal_is_ignored (SIGINT) == 0)
        {
+         rl_clear_signals ();          /* reset to known state, usually a no-op */
          old_sigint = (SigHandler *)set_signal_handler (SIGINT, sigint_sighandler);
        }
 
diff --git a/trap.c b/trap.c
index 32880b7775e55982fe66853aed2f12c870eacef6..ae761508edf8e8dfcaa13498b879ea4fb739bcb5 100644 (file)
--- a/trap.c
+++ b/trap.c
@@ -387,6 +387,11 @@ run_pending_traps (void)
          if (sig == SIGINT)
            {
              pending_traps[sig] = 0;   /* XXX */
+             /* _run_trap_internal saves and restores these, so want
+                the original values. */
+             running_trap = old_running;
+             trap_return_context = old_context;
+             /* XXX - bash_trapsig()? */
              /* We don't modify evalnest here, since run_interrupt_trap() calls
                 _run_trap_internal, which does. */
              run_interrupt_trap (0);