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
+
+
+
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
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 *);
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);
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,
}
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);
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.
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 ();
/* 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 *);
/* 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;
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);
}
/* Do substring search. */
- if (reverse)
+ if (linedir < 0) /* search backwards from end */
{
size_t ll;
}
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;
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);
}
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);
#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
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);
}
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);