+
9/15/2016
---------
[bash-4.4 released]
builtins/wait.def
- wait_builtin: set pstat.{pid,status} each time through the pid-or-job
loop and for wait without arguments
+
+ 6/4
+ ---
+sig.c
+ - termsig_handler: clean up last_procsub_child before exiting, after
+ unlinking all FIFOs or closing FDs to all the pipes. Might need to
+ send it a SIGTERM too. Fixes issue reported by mwnx <mwnx@gmx.com>
+
+config-top.h
+ - CASEMOD_CAPCASE: no longer defined by default
+
+ 6/5
+ ---
+lib/glob/glob.c
+ - glob_always_skip_dot_and_dotdot: new global variable, if set to
+ a non-zero value, no glob pattern will ever match `.' or `..'.
+ Disabled by default
+
+ 6/7
+ ---
+bashline.c
+ - cmd_xmap: changes to support multiple cmd_xmaps, one per editing
+ mode keymap (one each for vi insert and command modes). Changes from
+ Koichi Murase <myoga.murase@gmail.com>
+
+execute_cmd.c
+ - execute_arith_command: change from expanding the expression using
+ expand_words_no_vars to use expand_arith_string, with the accompanying
+ conversion from a WORD_LIST into a string. This makes it more
+ consistent with other arithmetic expansions. Inspired by a
+ discussion begun by Nils Emmerich <nemmerich@ernw.de>
nojobs.o: config-top.h
execute_cmd.o: config-top.h
variables.o: config-top.h
+subst.o: config-top.h
builtins/command.o: config-top.h
builtins/common.o: config-top.h
+builtins/declare.o: config-top.h
builtins/break.o: config-top.h
builtins/echo.o: config-top.h
builtins/evalstring.o: config-top.h
# define VI_EDITING_MODE 0
#endif
+/* Copied from rldefs.h, since that's not a public readline header file. */
+#ifndef FUNCTION_TO_KEYMAP
+
+#if defined (CRAY)
+# define FUNCTION_TO_KEYMAP(map, key) (Keymap)((int)map[key].function)
+# define KEYMAP_TO_FUNCTION(data) (rl_command_func_t *)((int)(data))
+#else
+# define FUNCTION_TO_KEYMAP(map, key) (Keymap)(map[key].function)
+# define KEYMAP_TO_FUNCTION(data) (rl_command_func_t *)(data)
+#endif
+
+#endif
+
#define RL_BOOLEAN_VARIABLE_VALUE(s) ((s)[0] == 'o' && (s)[1] == 'n' && (s)[2] == '\0')
#if defined (BRACE_COMPLETION)
#else
static int putx __P((int));
#endif
+
+static Keymap get_cmd_xmap_from_edit_mode __P((void));
+static Keymap get_cmd_xmap_from_keymap __P((Keymap));
+
static int bash_execute_unix_command __P((int, int));
static void init_unix_command_map __P((void));
static int isolate_sequence __P((char *, int, int, int *));
return ret;
}
-/* Support for binding readline key sequences to Unix commands. */
-static Keymap cmd_xmap;
+/* Support for binding readline key sequences to Unix commands. Each editing
+ mode has a separate Unix command keymap. */
+
+static Keymap emacs_std_cmd_xmap;
+#if defined (VI_MODE)
+static Keymap vi_insert_cmd_xmap;
+static Keymap vi_movement_cmd_xmap;
+#endif
#ifdef _MINIX
static void
char *cmd, *value, *ce, old_ch;
SHELL_VAR *v;
char ibuf[INT_STRLEN_BOUND(int) + 1];
+ Keymap cmd_xmap;
/* First, we need to find the right command to execute. This is tricky,
because we might have already indirected into another keymap, so we
have to walk cmd_xmap using the entire key sequence. */
+ cmd_xmap = get_cmd_xmap_from_keymap (rl_get_keymap ());
cmd = (char *)rl_function_of_keyseq_len (rl_executing_keyseq, rl_key_sequence_length, cmd_xmap, &type);
if (cmd == 0 || type != ISMACR)
int
print_unix_command_map ()
{
- Keymap save;
+ Keymap save, cmd_xmap;
save = rl_get_keymap ();
+ cmd_xmap = get_cmd_xmap_from_keymap (save);
rl_set_keymap (cmd_xmap);
rl_macro_dumper (1);
rl_set_keymap (save);
static void
init_unix_command_map ()
{
- cmd_xmap = rl_make_bare_keymap ();
+ emacs_std_cmd_xmap = rl_make_bare_keymap ();
+
+ emacs_std_cmd_xmap[CTRL('X')].type = ISKMAP;
+ emacs_std_cmd_xmap[CTRL('X')].function = KEYMAP_TO_FUNCTION (rl_make_bare_keymap ());
+ emacs_std_cmd_xmap[ESC].type = ISKMAP;
+ emacs_std_cmd_xmap[ESC].function = KEYMAP_TO_FUNCTION (rl_make_bare_keymap ());
+
+#if defined (VI_MODE)
+ vi_insert_cmd_xmap = rl_make_bare_keymap ();
+ vi_movement_cmd_xmap = rl_make_bare_keymap ();
+#endif
+}
+
+static Keymap
+get_cmd_xmap_from_edit_mode ()
+{
+ if (emacs_std_cmd_xmap == 0)
+ init_unix_command_map ();
+
+ switch (rl_editing_mode)
+ {
+ case EMACS_EDITING_MODE:
+ return emacs_std_cmd_xmap;
+#if defined (VI_MODE)
+ case VI_EDITING_MODE:
+ return (get_cmd_xmap_from_keymap (rl_get_keymap ()));
+#endif
+ default:
+ return (Keymap)NULL;
+ }
+}
+
+static Keymap
+get_cmd_xmap_from_keymap (kmap)
+ Keymap kmap;
+{
+ if (emacs_std_cmd_xmap == 0)
+ init_unix_command_map ();
+
+ if (kmap == emacs_standard_keymap)
+ return emacs_std_cmd_xmap;
+ else if (kmap == emacs_meta_keymap)
+ return (FUNCTION_TO_KEYMAP (emacs_std_cmd_xmap, ESC));
+ else if (kmap == emacs_ctlx_keymap)
+ return (FUNCTION_TO_KEYMAP (emacs_std_cmd_xmap, CTRL('X')));
+#if defined (VI_MODE)
+ else if (kmap == vi_insertion_keymap)
+ return vi_insert_cmd_xmap;
+ else if (kmap == vi_movement_keymap)
+ return vi_movement_cmd_xmap;
+#endif
+ else
+ return (Keymap)NULL;
}
static int
bind_keyseq_to_unix_command (line)
char *line;
{
- Keymap kmap;
+ Keymap kmap, cmd_xmap;
char *kseq, *value;
int i, kstart;
- if (cmd_xmap == 0)
- init_unix_command_map ();
-
kmap = rl_get_keymap ();
/* We duplicate some of the work done by rl_parse_and_bind here, but
value = substring (line, kstart, i);
/* Save the command to execute and the key sequence in the CMD_XMAP */
+ cmd_xmap = get_cmd_xmap_from_keymap (kmap);
rl_generic_bind (ISMACR, kseq, value, cmd_xmap);
/* and bind the key sequence in the current keymap to a function that
((command->flags & CMD_TIME_PIPELINE) == 0) &&
((command->flags & CMD_INVERT_RETURN) == 0))
{
+itrace("optimize_subshell_command: setting CMD_NO_FOR for simple command");
command->flags |= CMD_NO_FORK;
command->value.Simple->flags |= CMD_NO_FORK;
}
int expok, save_line_number, retval;
intmax_t expresult;
WORD_LIST *new;
- char *exp;
+ char *exp, *t;
expresult = 0;
}
#endif
- new = expand_words_no_vars (arith_command->exp);
+ t = (char *)NULL;
+ new = arith_command->exp;
+ if (new->next)
+ exp = t = string_list (new); /* just in case */
+ else
+ exp = new->word->word;
+
+ exp = expand_arith_string (exp, Q_DOUBLE_QUOTES|Q_ARITH);
/* If we're tracing, make a new word list with `((' at the front and `))'
- at the back and print it. */
+ at the back and print it. Change xtrace_print_arith_cmd to take a string
+ when I change eval_arith_for_expr to use expand_arith_string(). */
if (echo_command_at_execute)
- xtrace_print_arith_cmd (new);
+ {
+ new = make_word_list (make_word (exp ? exp : ""), (WORD_LIST *)NULL);
+ xtrace_print_arith_cmd (new);
+ dispose_words (new);
+ }
- if (new)
+ if (exp)
{
- exp = new->next ? string_list (new) : new->word->word;
expresult = evalexp (exp, EXP_EXPANDED, &expok);
line_number = save_line_number;
- if (exp != new->word->word)
- free (exp);
- dispose_words (new);
+ free (exp);
}
else
{
expresult = 0;
expok = 1;
}
+ FREE (t);
if (expok == 0)
return (EXECUTION_FAILURE);
#endif /* __CYGWIN__ */
#define PATHSEP(c) (ISDIRSEP(c) || (c) == 0)
+#define DOT_OR_DOTDOT(s) (s[0] == '.' && (s[1] == 0 || (s[1] == '.' && s[2] == 0)))
+#if defined (HANDLE_MULTIBYTE)
+#define WDOT_OR_DOTDOT(w) (w[0] == L'.' && (w[1] == L'\0' || (w[1] == L'.' && w[2] == L'\0')))
+#endif
+
#if 0
/* Declarations for functions defined in xmalloc.c */
extern PTR_T xmalloc __P((size_t));
#include <signal.h>
#include "shell.h"
+#include "general.h"
#include "glob.h"
#include "strmatch.h"
is done without regard to case. */
int glob_ignore_case = 0;
+/* Global variable controlling whether globbing ever returns . or ..
+ regardless of the pattern. If set to 1, no glob pattern will ever
+ match `.' or `..'. Disabled by default. */
+int glob_always_skip_dot_and_dotdot = 0;
+
/* Global variable to return to signify an error in globbing. */
char *glob_error_return;
return (extglob_skipname (pat, dname, flags));
#endif
+ if (glob_always_skip_dot_and_dotdot && DOT_OR_DOTDOT (dname))
+ return 1;
+
/* If a leading dot need not be explicitly matched, and the pattern
doesn't start with a `.', don't match `.' or `..' */
if (noglob_dot_filenames == 0 && pat[0] != '.' &&
(pat[0] != '\\' || pat[1] != '.') &&
- (dname[0] == '.' &&
- (dname[1] == '\0' || (dname[1] == '.' && dname[2] == '\0'))))
+ DOT_OR_DOTDOT (dname))
return 1;
/* If a dot must be explicitly matched, check to see if they do. */
wchar_t *pat, *dname;
int flags;
{
+ if (glob_always_skip_dot_and_dotdot && WDOT_OR_DOTDOT (dname))
+ return 1;
+
/* If a leading dot need not be explicitly matched, and the
pattern doesn't start with a `.', don't match `.' or `..' */
if (noglob_dot_filenames == 0 && pat[0] != L'.' &&
(pat[0] != L'\\' || pat[1] != L'.') &&
- (dname[0] == L'.' &&
- (dname[1] == L'\0' || (dname[1] == L'.' && dname[2] == L'\0'))))
+ WDOT_OR_DOTDOT (dname))
return 1;
/* If a leading dot must be explicitly matched, check to see if the
/* sig.c - interface for shell signal handlers and signal initialization. */
-/* Copyright (C) 1994-2018 Free Software Foundation, Inc.
+/* Copyright (C) 1994-2019 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
#if defined (PROCESS_SUBSTITUTION)
unlink_fifo_list ();
+# if defined (JOB_CONTROL)
+ discard_last_procsub_child ();
+# endif
#endif /* PROCESS_SUBSTITUTION */
/* Reset execution context */