From: Chet Ramey Date: Fri, 5 Jun 2015 15:50:38 +0000 (-0400) Subject: commit bash-20150529 snapshot X-Git-Tag: bash-4.4-alpha~8 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ff7c092e19662b4ad089b0a2d75c2daa190ae295;p=thirdparty%2Fbash.git commit bash-20150529 snapshot --- diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index 9c0547f80..775ef12f6 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -8642,3 +8642,85 @@ builtins/shopt.def is enabled, and turns off when extdebug is disabled. The documentation has always said that shopt does this. Report from Peng Yu + + 5/27 + ---- +findcmd.[ch] + - add support for EXECIGNORE shell variable, list of extglob patterns that + prevent matching filenames from being identified as executable files + +variables.c + - EXECIGNORE: arrange for findcmd.c:setup_exec_ignore to be called when + $EXECIGNORE changes + +variables.h + - sv_execignore: extern declaration + +doc/{bash.1,bashref.texi} + - document EXECIGNORE variable + + 5/28 + ---- +lib/readline/callback.c + - rl_callback_sigcleanup: new function, cleans up and unsets any state + rl_callback_read_char uses. Intended to be used after a signal + +lib/readline/signals.c + - _rl_handle_signal: call rl_callback_sigcleanup on SIGINT. Fixes bug + reported to python group by Martin Panter + +lib/readline/isearch.c + - _rl_isearch_cleanup: now a public function so rl_callback_cleanup can + call it + +lib/readline/search.c + - _rl_nsearch_cleanup: now a public function so rl_callback_cleanup can + call it + +lib/readline/rlprivate.h + - _rl_[in]search_cleanup: extern declarations + +lib/readline/readline.h + - rl_callback_sigcleanup: new extern declaration + +lib/readline/doc/rltech.texi + - rl_callback_sigcleanup: documented + +lib/readline/readline.h + - bump readline version to 7.0 due to addition of rl_callback_sigcleanup + + 5/29 + ---- +builtins/declare.def + - declare_internal: if we are trying to change attributes or value for a + nameref variable whose value points to an unset variable, make sure we + create a new variable whose name is the value of the nameref variable. + That is, + + declare -n foo=bar + unset foo # unsets bar + declare -i foo + + should create a (invisible) variable named `bar' with the integer + attribute. Fixes problem reported by Greg Wooledge + + +builtins/set.def + - unset_builtin: if we find a nameref variable when we look it up with + find_variable (the returned variable has a name different from what + we looked up), make sure we use that new name for the rest of the + function rather than rely on unbind_variable to do the same thing as + find_variable. Fixes problem reported by Greg Wooledge + + - unset_builtin: if we try to unset a nameref variable whose value is + not a set variable, make sure we don't try to unset the nameref itself, + but rather the variable it points to. This ensures that the following + always works as it should + + declare -n foo=bar + unset foo # unsets bar and leaves foo unchanged + +lib/readline/funmap.c + - vi-insertion-mode: make sure it maps to rl_vi_insert_mode, which is + actually what the `i' keybinding in vi_movement_keymap maps to. + Cosmetic fix from isabella parakiss diff --git a/MANIFEST b/MANIFEST index c8dc1324c..ef2b5dde1 100644 --- a/MANIFEST +++ b/MANIFEST @@ -1048,6 +1048,7 @@ tests/nameref6.sub f tests/nameref7.sub f tests/nameref8.sub f tests/nameref9.sub f +tests/nameref10.sub f tests/nameref.right f tests/new-exp.tests f tests/new-exp1.sub f diff --git a/builtins/declare.def b/builtins/declare.def index 4c0f514a8..1866d7959 100644 --- a/builtins/declare.def +++ b/builtins/declare.def @@ -340,6 +340,14 @@ declare_internal (list, local_var) assign_error++; NEXT_VARIABLE (); } +#if 0 + if (value && *value && legal_identifier (value) == 0) + { + builtin_error (_("%s: invalid variable name for name reference"), value); + assign_error++; + NEXT_VARIABLE (); + } +#endif } #if defined (ARRAY_VARS) @@ -492,6 +500,26 @@ declare_internal (list, local_var) var = mkglobal ? find_global_variable (nameref_cell (refvar)) : find_variable (nameref_cell (refvar)); } + /* See if we are trying to set flags or value for an existing nameref + that points to a non-existent variable: e.g., + declare -n foo=bar + unset foo # unsets bar + declare -i foo + foo=4+4 + declare -p foo */ + if (var == 0 && (flags_on || flags_off || offset)) + { + refvar = mkglobal ? find_global_variable_last_nameref (name) : find_variable_last_nameref (name); + if (refvar && nameref_p (refvar) == 0) + refvar = 0; + if (refvar) + var = mkglobal ? find_global_variable (nameref_cell (refvar)) : find_variable (nameref_cell (refvar)); + if (refvar && var == 0) + { + free (name); + name = savestring (nameref_cell (refvar)); + } + } if (var == 0) var = mkglobal ? find_global_variable (name) : find_variable (name); @@ -540,6 +568,14 @@ declare_internal (list, local_var) } else if (flags_on & att_nameref) { +#if 0 + if (nameref_p (var) == 0 && var_isset (var) && var_isnull (var) == 0 && legal_identifier (value_cell (var)) == 0) + { + builtin_error (_("%s: invalid variable name for name reference"), value_cell (var)); + any_failed++; + NEXT_VARIABLE (); + } +#endif /* ksh93 compat: turning on nameref attribute turns off -ilu */ VUNSETATTR (var, att_integer|att_uppercase|att_lowercase|att_capcase); } diff --git a/builtins/set.def b/builtins/set.def index e31b017cf..3ec6bb958 100644 --- a/builtins/set.def +++ b/builtins/set.def @@ -877,6 +877,10 @@ unset_builtin (list) NEXT_VARIABLE (); } + /* if we have a nameref we want to use it */ + if (var && unset_function == 0 && nameref == 0 && STREQ (name, name_cell(var)) == 0) + name = name_cell (var); + /* Posix.2 says try variables first, then functions. If we would find a function after unsuccessfully searching for a variable, note that we're acting on a function now as if -f were @@ -911,7 +915,15 @@ unset_builtin (list) } else #endif /* ARRAY_VARS */ - tem = unset_function ? unbind_func (name) : (nameref ? unbind_nameref (name) : unbind_variable (name)); + /* If we're trying to unset a nameref variable whose value isn't a set + variable, make sure we still try to unset the nameref's value */ + if (var == 0 && nameref == 0 && unset_function == 0) + { + var = find_variable_last_nameref (name); + tem = (var && nameref_p (var)) ? unbind_variable (nameref_cell (var)) : unbind_variable (name); + } + else + tem = unset_function ? unbind_func (name) : (nameref ? unbind_nameref (name) : unbind_variable (name)); /* This is what Posix.2 says: ``If neither -f nor -v is specified, the name refers to a variable; if a variable by diff --git a/doc/bash.1 b/doc/bash.1 index 7033a98ad..ff76bfd16 100644 --- a/doc/bash.1 +++ b/doc/bash.1 @@ -5,12 +5,12 @@ .\" Case Western Reserve University .\" chet.ramey@case.edu .\" -.\" Last Change: Fri Apr 10 15:04:46 EDT 2015 +.\" Last Change: Wed May 27 14:55:39 EDT 2015 .\" .\" bash_builtins, strip all but Built-Ins section .if \n(zZ=1 .ig zZ .if \n(zY=1 .ig zY -.TH BASH 1 "2015 April 10" "GNU Bash 4.4" +.TH BASH 1 "2015 May 27" "GNU Bash 4.4" .\" .\" There's some problem with having a `@' .\" in a tagged paragraph with the BSD man macros. @@ -1991,6 +1991,16 @@ Similar to .BR BASH_ENV ; used when the shell is invoked in POSIX mode. .TP +.B EXECIGNORE +A colon-separated list of extended glob patterns (see \fBPattern Matching\fP) +defining the list of filenames to be ignored by command search. +Files whose full pathnames match one of these patterns are not considered +executable files for the purposes of completion and command execution. +This does not affect the behavior of the \fB[\fP, \fBtest\fP, and \fB[[\fP +commands. +Use this variable to ignore shared library files that have the executable +bit set, but are not executable files. +.TP .B FCEDIT The default editor for the .B fc diff --git a/doc/bashref.texi b/doc/bashref.texi index 8cf5e9993..73934af00 100644 --- a/doc/bashref.texi +++ b/doc/bashref.texi @@ -5662,6 +5662,16 @@ Similar to @code{BASH_ENV}; used when the shell is invoked in The numeric effective user id of the current user. This variable is readonly. +@item EXECIGNORE +A colon-separated list of extended glob patterns (@pxref{Pattern Matching}) +defining the list of filenames to be ignored by command search. +Files whose full pathnames match one of these patterns are not considered +executable files for the purposes of completion and command execution. +This does not affect the behavior of the @code{[}, @code{test}, and @code{[[} +commands. +Use this variable to ignore shared library files that have the executable +bit set, but are not executable files. + @item FCEDIT The editor used as a default by the @option{-e} option to the @code{fc} builtin command. diff --git a/doc/version.texi b/doc/version.texi index 997d69f29..afa1e6260 100644 --- a/doc/version.texi +++ b/doc/version.texi @@ -2,10 +2,10 @@ Copyright (C) 1988-2015 Free Software Foundation, Inc. @end ignore -@set LASTCHANGE Fri Apr 10 15:04:14 EDT 2015 +@set LASTCHANGE Wed May 27 14:56:01 EDT 2015 @set EDITION 4.4 @set VERSION 4.4 -@set UPDATED 10 April 2015 -@set UPDATED-MONTH April 2015 +@set UPDATED 27 May 2015 +@set UPDATED-MONTH May 2015 diff --git a/findcmd.c b/findcmd.c index 436a94365..c4f2d06fb 100644 --- a/findcmd.c +++ b/findcmd.c @@ -1,6 +1,6 @@ /* findcmd.c -- Functions to search for commands by name. */ -/* Copyright (C) 1997-2012 Free Software Foundation, Inc. +/* Copyright (C) 1997-2015 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -44,6 +44,8 @@ #include "hashcmd.h" #include "findcmd.h" /* matching prototypes and declarations */ +#include + #if !defined (errno) extern int errno; #endif @@ -77,6 +79,36 @@ int check_hashed_filenames = CHECKHASH_DEFAULT; containing the file of interest. */ int dot_found_in_search = 0; +/* Set up EXECIGNORE; a blacklist of patterns that executable files should not + match. */ +static struct ignorevar execignore = +{ + "EXECIGNORE", + NULL, + 0, + NULL, + NULL +}; + +void +setup_exec_ignore (varname) + char *varname; +{ + setup_ignore_patterns (&execignore); +} + +static int +exec_name_should_ignore (name) + const char *name; +{ + struct ign *p; + + for (p = execignore.ignores; p && p->val; p++) + if (strmatch (p->val, (char *)name, FNM_EXTMATCH|FNM_CASEFOLD) != FNM_NOMATCH) + return 1; + return 0; +} + /* Return some flags based on information about this file. The EXISTS bit is non-zero if the file is found. The EXECABLE bit is non-zero the file is executble. @@ -104,7 +136,7 @@ file_status (name) file access mechanisms into account. eaccess uses the effective user and group IDs, not the real ones. We could use sh_eaccess, but we don't want any special treatment for /dev/fd. */ - if (eaccess (name, X_OK) == 0) + if (exec_name_should_ignore (name) == 0 && eaccess (name, X_OK) == 0) r |= FS_EXECABLE; if (eaccess (name, R_OK) == 0) r |= FS_READABLE; @@ -114,7 +146,7 @@ file_status (name) /* We have to use access(2) to determine access because AFS does not support Unix file system semantics. This may produce wrong answers for non-AFS files when ruid != euid. I hate AFS. */ - if (access (name, X_OK) == 0) + if (exec_name_should_ignore (name) == 0 && access (name, X_OK) == 0) r |= FS_EXECABLE; if (access (name, R_OK) == 0) r |= FS_READABLE; @@ -131,7 +163,7 @@ file_status (name) if (current_user.euid == (uid_t)0) { r |= FS_READABLE; - if (finfo.st_mode & S_IXUGO) + if (exec_name_should_ignore (name) == 0 && (finfo.st_mode & S_IXUGO)) r |= FS_EXECABLE; return r; } @@ -139,7 +171,7 @@ file_status (name) /* If we are the owner of the file, the owner bits apply. */ if (current_user.euid == finfo.st_uid) { - if (finfo.st_mode & S_IXUSR) + if (exec_name_should_ignore (name) == 0 && (finfo.st_mode & S_IXUSR)) r |= FS_EXECABLE; if (finfo.st_mode & S_IRUSR) r |= FS_READABLE; @@ -148,7 +180,7 @@ file_status (name) /* If we are in the owning group, the group permissions apply. */ else if (group_member (finfo.st_gid)) { - if (finfo.st_mode & S_IXGRP) + if (exec_name_should_ignore (name) == 0 && (finfo.st_mode & S_IXGRP)) r |= FS_EXECABLE; if (finfo.st_mode & S_IRGRP) r |= FS_READABLE; diff --git a/findcmd.h b/findcmd.h index 52ad1d0bc..c0f6d781d 100644 --- a/findcmd.h +++ b/findcmd.h @@ -1,6 +1,6 @@ /* findcmd.h - functions from findcmd.c. */ -/* Copyright (C) 1997-2012 Free Software Foundation, Inc. +/* Copyright (C) 1997-2015 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -31,5 +31,6 @@ extern char *find_user_command __P((const char *)); extern char *find_path_file __P((const char *)); extern char *search_for_command __P((const char *, int)); extern char *user_command_matches __P((const char *, int, int)); +extern void setup_exec_ignore __P((char *)); #endif /* _FINDCMD_H_ */ diff --git a/lib/readline/callback.c b/lib/readline/callback.c index b2fe3901e..0fc3f90bc 100644 --- a/lib/readline/callback.c +++ b/lib/readline/callback.c @@ -291,4 +291,27 @@ _rl_callback_data_dispose (arg) xfree (arg); } +/* Make sure that this agrees with cases in rl_callback_read_char */ +void +rl_callback_sigcleanup () +{ + if (RL_ISSTATE (RL_STATE_CALLBACK) == 0) + return; + + if (RL_ISSTATE (RL_STATE_ISEARCH)) + _rl_isearch_cleanup (_rl_iscxt, 0); + else if (RL_ISSTATE (RL_STATE_NSEARCH)) + _rl_nsearch_cleanup (_rl_nscxt, 0); + else if (RL_ISSTATE (RL_STATE_VIMOTION)) + RL_UNSETSTATE (RL_STATE_VIMOTION); + else if (RL_ISSTATE (RL_STATE_NUMERICARG)) + { + _rl_argcxt = 0; + RL_UNSETSTATE (RL_STATE_NUMERICARG); + } + else if (RL_ISSTATE (RL_STATE_MULTIKEY)) + RL_UNSETSTATE (RL_STATE_MULTIKEY); + + _rl_callback_func = 0; +} #endif diff --git a/lib/readline/doc/rltech.texi b/lib/readline/doc/rltech.texi index 2fd0b943d..2fd6f4412 100644 --- a/lib/readline/doc/rltech.texi +++ b/lib/readline/doc/rltech.texi @@ -1328,6 +1328,14 @@ the terminal settings are modified for Readline's use again. @code{NULL} line. @end deftypefun +@deftypefun void rl_callback_sigcleanup (void) +Clean up any internal state the callback interface uses to maintain state +between calls to rl_callback_read_char (e.g., the state of any active +incremental searches). This is intended to be used by applications that +wish to perform their own signal handling; Readline's internal signal handler +calls this when appropriate. +@end deftypefun + @deftypefun void rl_callback_handler_remove (void) Restore the terminal to its initial state and remove the line handler. You may call this function from within a callback as well as independently. diff --git a/lib/readline/doc/version.texi b/lib/readline/doc/version.texi index d7a210194..3f4d36dda 100644 --- a/lib/readline/doc/version.texi +++ b/lib/readline/doc/version.texi @@ -4,7 +4,7 @@ Copyright (C) 1988-2015 Free Software Foundation, Inc. @set EDITION 6.4 @set VERSION 6.4 -@set UPDATED 24 May 2015 +@set UPDATED 28 May 2015 @set UPDATED-MONTH May 2015 -@set LASTCHANGE Sun May 24 18:01:45 EDT 2015 +@set LASTCHANGE Thu May 28 16:58:07 EDT 2015 diff --git a/lib/readline/examples/rl-callbacktest2.c b/lib/readline/examples/rl-callbacktest2.c new file mode 100644 index 000000000..2525b7071 --- /dev/null +++ b/lib/readline/examples/rl-callbacktest2.c @@ -0,0 +1,143 @@ +/* Standard include files. stdio.h is required. */ +#include +#include +#include + +/* Used for select(2) */ +#include +#include +#include + +#include + +#include + +/* Standard readline include files. */ +#if defined (READLINE_LIBRARY) +# include "readline.h" +# include "history.h" +#else +# include +# include +#endif + +static void cb_linehandler (char *); +static void sigint_sighandler (int); +static int sigint_handler (int); + +static int saw_signal = 0; + +int running; +const char *prompt = "rltest$ "; +char *input_string; + +/* Callback function called for each line when accept-line executed, EOF + seen, or EOF character read. This sets a flag and returns; it could + also call exit(3). */ +static void +cb_linehandler (char *line) +{ + if (line && *line) + add_history (line); + printf ("input line: %s\n", line ? line : ""); + input_string = line; + rl_callback_handler_remove (); +} + +static char * +cb_readline () +{ + fd_set fds; + int r, err; + char *not_done = ""; + + /* Install the line handler. */ + rl_callback_handler_install (prompt, cb_linehandler); + +if (RL_ISSTATE (RL_STATE_ISEARCH)) + fprintf(stderr, "cb_readline: after handler install, state (ISEARCH) = %d", rl_readline_state); +else if (RL_ISSTATE (RL_STATE_NSEARCH)) + fprintf(stderr, "cb_readline: after handler install, state (NSEARCH) = %d", rl_readline_state); +/* MULTIKEY VIMOTION NUMERICARG _rl_callback_func */ + + FD_ZERO (&fds); + FD_SET (fileno (rl_instream), &fds); + + input_string = not_done; + + while (input_string == not_done) + { + r = err = 0; + /* Enter a simple event loop. This waits until something is available + to read on readline's input stream (defaults to standard input) and + calls the builtin character read callback to read it. It does not + have to modify the user's terminal settings. */ + while (r == 0) + { + struct timeval timeout = {0, 100000}; + struct timeval *timeoutp = NULL; + + timeoutp = &timeout; + FD_SET (fileno (rl_instream), &fds); + r = select (FD_SETSIZE, &fds, NULL, NULL, timeoutp); + err = errno; + } + + if (saw_signal) + sigint_handler (saw_signal); + + if (r < 0) + { + perror ("rltest: select"); + rl_callback_handler_remove (); + break; + } + + /* if (FD_ISSET (fileno (rl_instream), &fds)) */ + if (r > 0) + rl_callback_read_char (); + } + return input_string; +} + +void +sigint_sighandler (s) + int s; +{ + saw_signal = s; +} + +int +sigint_handler (s) + int s; +{ + rl_free_line_state (); + rl_callback_sigcleanup (); + rl_cleanup_after_signal (); + rl_callback_handler_remove (); + saw_signal = 0; +fprintf(stderr, "sigint_handler: readline state = %d\r\n", rl_readline_state); + return s; +} + +int +main (int c, char **v) +{ + char *p; + + running = 1; + rl_catch_signals = 1; + + rl_bind_key_in_map ('r', rl_history_search_backward, emacs_meta_keymap); + rl_bind_key_in_map ('s', rl_history_search_forward, emacs_meta_keymap); + + signal (SIGINT, sigint_sighandler); + while (running) + { + p = cb_readline (); + if (p == 0 || strcmp (p, "exit") == 0) + break; + } + printf ("rl-callbacktest2: Event loop has exited\n"); + return 0; +} diff --git a/lib/readline/funmap.c b/lib/readline/funmap.c index 64b0e411a..62535bf21 100644 --- a/lib/readline/funmap.c +++ b/lib/readline/funmap.c @@ -178,7 +178,7 @@ static const FUNMAP default_funmap[] = { { "vi-fword", rl_vi_fword }, { "vi-goto-mark", rl_vi_goto_mark }, { "vi-insert-beg", rl_vi_insert_beg }, - { "vi-insertion-mode", rl_vi_insertion_mode }, + { "vi-insertion-mode", rl_vi_insert_mode }, { "vi-match", rl_vi_match }, { "vi-movement-mode", rl_vi_movement_mode }, { "vi-next-word", rl_vi_next_word }, diff --git a/lib/readline/isearch.c b/lib/readline/isearch.c index d768560bd..5bcecc415 100644 --- a/lib/readline/isearch.c +++ b/lib/readline/isearch.c @@ -66,7 +66,6 @@ static int rl_search_history PARAMS((int, int)); static _rl_search_cxt *_rl_isearch_init PARAMS((int)); static void _rl_isearch_fini PARAMS((_rl_search_cxt *)); -static int _rl_isearch_cleanup PARAMS((_rl_search_cxt *, int)); /* Last line found by the current incremental search, so we don't `find' identical lines many times in a row. Now part of isearch context. */ @@ -724,7 +723,7 @@ add_character: return 1; } -static int +int _rl_isearch_cleanup (cxt, r) _rl_search_cxt *cxt; int r; diff --git a/lib/readline/readline.h b/lib/readline/readline.h index a68ecaa0e..cac13d7b9 100644 --- a/lib/readline/readline.h +++ b/lib/readline/readline.h @@ -39,9 +39,9 @@ extern "C" { #endif /* Hex-encoded Readline version number. */ -#define RL_READLINE_VERSION 0x0604 /* Readline 6.4 */ -#define RL_VERSION_MAJOR 6 -#define RL_VERSION_MINOR 4 +#define RL_READLINE_VERSION 0x0700 /* Readline 7.0 */ +#define RL_VERSION_MAJOR 7 +#define RL_VERSION_MINOR 0 /* Readline data structures. */ @@ -220,6 +220,7 @@ extern int rl_insert_close PARAMS((int, int)); extern void rl_callback_handler_install PARAMS((const char *, rl_vcpfunc_t *)); extern void rl_callback_read_char PARAMS((void)); extern void rl_callback_handler_remove PARAMS((void)); +extern void rl_callback_sigcleanup PARAMS((void)); /* Things for vi mode. Not available unless readline is compiled -DVI_MODE. */ /* VI-mode bindable commands. */ diff --git a/lib/readline/rlprivate.h b/lib/readline/rlprivate.h index 15e2809a3..9b859f995 100644 --- a/lib/readline/rlprivate.h +++ b/lib/readline/rlprivate.h @@ -292,6 +292,7 @@ extern void _rl_scxt_dispose PARAMS((_rl_search_cxt *, int)); extern int _rl_isearch_dispatch PARAMS((_rl_search_cxt *, int)); extern int _rl_isearch_callback PARAMS((_rl_search_cxt *)); +extern int _rl_isearch_cleanup PARAMS((_rl_search_cxt *, int)); extern int _rl_search_getchar PARAMS((_rl_search_cxt *)); @@ -346,6 +347,7 @@ extern int _rl_restore_tty_signals PARAMS((void)); /* search.c */ extern int _rl_nsearch_callback PARAMS((_rl_search_cxt *)); +extern int _rl_nsearch_cleanup PARAMS((_rl_search_cxt *, int)); /* signals.c */ extern void _rl_signal_handler PARAMS((int)); diff --git a/lib/readline/search.c b/lib/readline/search.c index 46fb3a65a..c9bc6b1c3 100644 --- a/lib/readline/search.c +++ b/lib/readline/search.c @@ -80,7 +80,6 @@ static int rl_history_search_internal PARAMS((int, int)); static void rl_history_search_reinit PARAMS((int)); static _rl_search_cxt *_rl_nsearch_init PARAMS((int, int)); -static int _rl_nsearch_cleanup PARAMS((_rl_search_cxt *, int)); static void _rl_nsearch_abort PARAMS((_rl_search_cxt *)); static int _rl_nsearch_dispatch PARAMS((_rl_search_cxt *, int)); @@ -224,7 +223,7 @@ _rl_nsearch_init (dir, pchar) return cxt; } -static int +int _rl_nsearch_cleanup (cxt, r) _rl_search_cxt *cxt; int r; diff --git a/lib/readline/signals.c b/lib/readline/signals.c index e4f88f903..61430459c 100644 --- a/lib/readline/signals.c +++ b/lib/readline/signals.c @@ -213,6 +213,10 @@ _rl_handle_signal (sig) case SIGINT: _rl_reset_completion_state (); rl_free_line_state (); +#if defined (READLINE_CALLBACKS) + rl_callback_sigcleanup (); +#endif + /* FALLTHROUGH */ #if defined (SIGTSTP) diff --git a/pathexp.h b/pathexp.h index 601914c8b..183a2124c 100644 --- a/pathexp.h +++ b/pathexp.h @@ -1,6 +1,6 @@ /* pathexp.h -- The shell interface to the globbing library. */ -/* Copyright (C) 1987-2009 Free Software Foundation, Inc. +/* Copyright (C) 1987-2015 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -71,7 +71,7 @@ extern char *quote_globbing_chars __P((const char *)); extern char **shell_glob_filename __P((const char *)); /* Filename completion ignore. Used to implement the "fignore" facility of - tcsh and GLOBIGNORE (like ksh-93 FIGNORE). + tcsh, GLOBIGNORE (like ksh-93 FIGNORE), and EXECIGNORE. It is passed a NULL-terminated array of (char *)'s that must be free()'d if they are deleted. The first element (names[0]) is the @@ -87,7 +87,7 @@ struct ign { typedef int sh_iv_item_func_t __P((struct ign *)); struct ignorevar { - char *varname; /* FIGNORE or GLOBIGNORE */ + char *varname; /* FIGNORE, GLOBIGNORE, or EXECIGNORE */ struct ign *ignores; /* Store the ignore strings here */ int num_ignores; /* How many are there? */ char *last_ignoreval; /* Last value of variable - cached for speed */ diff --git a/tests/RUN-ONE-TEST b/tests/RUN-ONE-TEST index 3efcf32d6..72ec06a2c 100755 --- a/tests/RUN-ONE-TEST +++ b/tests/RUN-ONE-TEST @@ -1,4 +1,4 @@ -BUILD_DIR=/usr/local/build/chet/bash/bash-current +BUILD_DIR=/usr/local/build/bash/bash-current THIS_SH=$BUILD_DIR/bash PATH=$PATH:$BUILD_DIR diff --git a/tests/nameref.right b/tests/nameref.right index c35fac1e3..07eed4b2d 100644 --- a/tests/nameref.right +++ b/tests/nameref.right @@ -133,3 +133,37 @@ idx2 idX2 idx2 idX2 +declare -n foo="x[\$zero]" +42 +declare -a x=([0]="4") +declare -n foo="x[\$(echo 0)]" +4 +comsub +x[i=0] +comsub +4 +comsub +4 +comsub +4 +declare -n foo="somevariable" +./nameref10.sub: line 38: typeset: somevariable: not found +foo = +declare -n foo="somevariable" +declare -A somevariable=([jug]="brown" ) +./nameref10.sub: line 45: warning: foo=([jug]="brown" ): quoted compound array assignment deprecated +declare -n foo="somevariable" +declare -A somevariable=([jug]="brown" ) +declare -n foo="somevariable" +./nameref10.sub: line 49: typeset: somevariable: not found +./nameref10.sub: line 51: typeset: foo: not found +./nameref10.sub: line 51: typeset: somevariable: not found +declare -n foo="bar" +./nameref10.sub: line 55: typeset: bar: not found +declare -n foo="bar" +./nameref10.sub: line 57: typeset: bar: not found +declare -n foo="bar" +declare -i bar="8" +8 +declare -n foo="bar" +./nameref10.sub: line 64: typeset: bar: not found diff --git a/tests/nameref.tests b/tests/nameref.tests index bce8a6806..c20100f23 100644 --- a/tests/nameref.tests +++ b/tests/nameref.tests @@ -124,3 +124,4 @@ ${THIS_SH} ./nameref6.sub ${THIS_SH} ./nameref7.sub ${THIS_SH} ./nameref8.sub ${THIS_SH} ./nameref9.sub +${THIS_SH} ./nameref10.sub diff --git a/tests/nameref10.sub b/tests/nameref10.sub new file mode 100644 index 000000000..2a1ba3599 --- /dev/null +++ b/tests/nameref10.sub @@ -0,0 +1,64 @@ +# testing behavior of command substitution as one of expansions performed by +# array subscripting; should behave the same directly as when done through +# a nameref + +x[0]=42 +zero=0 +f() { typeset -n foo="$1"; declare -p foo; echo "$foo"; } + +f 'x[$zero]' + +x[$(echo 0)]=4 +declare -p x + +f 'x[$(echo 0)]' + +unset -f f +f() +{ + typeset -n foo="$1"; + + echo "x[i=0$(echo comsub >&2)]" + echo "${x[i=0$(echo comsub >&2)]}" + echo "${!1}" + echo "$foo" +} + +f 'x[i=0$(echo comsub >&2)]' + +unset -f f +unset x + +# problems with unset and namerefs pointing to non-existent variables pointed +# out after bash-4.3 released + +typeset -n foo=somevariable +foo=bar +unset foo # unsets somevariable +typeset -p foo somevariable +echo foo = $foo + +typeset -A foo # should create array variable named somevariable +foo["jug"]="brown" + +typeset -p foo somevariable +typeset -A foo='([jug]="brown" )' +typeset -p foo somevariable + +unset foo +typeset -p foo somevariable +unset -n foo +typeset -p foo somevariable + +unset bar +typeset -n foo=bar +typeset -p foo bar +unset foo +typeset -p foo bar +typeset -i foo +foo=4+4 +typeset -p foo bar +echo "$foo" + +unset foo +typeset -p foo bar diff --git a/tests/nameref4.sub b/tests/nameref4.sub index f1e2aef9d..4dd86b2fd 100644 --- a/tests/nameref4.sub +++ b/tests/nameref4.sub @@ -66,7 +66,9 @@ ckval bar hello # XXX -- another self-referencing error? # ksh93 makes this another invalid self-reference -unset foo bar +unset foo +unset -n bar + bar=123 foobar() { @@ -80,14 +82,16 @@ typeset -n short=long short=( a b ) echo "expect " echo ${long[@]} -unset short long +unset long +unset -n short # assignment to a previously-unset variable typeset -n short=long short=foo echo "expect " echo ${long} -unset short long +unset long +unset -n short unset foo bar @@ -110,7 +114,8 @@ barfunc() barfunc bar unset -f foobar -unset foo bar +unset bar +unset -n foo # should ref at global scope survive call to foobar()? unset ref x @@ -151,6 +156,8 @@ echo "expect " recho "${x[@]}" unset ref x +unset -n ref + typeset -n ref ref=x # make sure nameref to a previously-unset variable creates the variable @@ -159,6 +166,8 @@ ckval x 42 # make sure they work inside arithmetic expressions unset foo bar ref x xxx +unset -n ref + typeset -i ivar typeset -n iref=ivar diff --git a/variables.c b/variables.c index bfd16f2a2..312504bf2 100644 --- a/variables.c +++ b/variables.c @@ -4735,6 +4735,8 @@ static struct name_and_function special_vars[] = { { "COMP_WORDBREAKS", sv_comp_wordbreaks }, #endif + { "EXECIGNORE", sv_execignore }, + { "FUNCNEST", sv_funcnest }, { "GLOBIGNORE", sv_globignore }, @@ -4924,6 +4926,14 @@ sv_funcnest (name) funcnest_max = num; } +/* What to do when EXECIGNORE changes. */ +void +sv_execignore (name) + char *name; +{ + setup_exec_ignore (name); +} + /* What to do when GLOBIGNORE changes. */ void sv_globignore (name) @@ -4985,7 +4995,7 @@ sv_winsize (name) return; v = find_variable (name); - if (v == 0 || var_isnull (v)) + if (v == 0 || var_isset (v) == 0) rl_reset_screen_size (); else { diff --git a/variables.h b/variables.h index 4574ca8c6..e16d0cc58 100644 --- a/variables.h +++ b/variables.h @@ -1,6 +1,6 @@ /* variables.h -- data structures for shell variables. */ -/* Copyright (C) 1987-2012 Free Software Foundation, Inc. +/* Copyright (C) 1987-2015 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -156,6 +156,9 @@ typedef struct _vlist { #define tempvar_p(var) ((((var)->attributes) & (att_tempvar))) +/* Variable names: lvalues */ +#define name_cell(var) ((var)->name) + /* Acessing variable values: rvalues */ #define value_cell(var) ((var)->value) #define function_cell(var) (COMMAND *)((var)->value) @@ -165,8 +168,9 @@ typedef struct _vlist { #define NAMEREF_MAX 8 /* only 8 levels of nameref indirection */ -#define var_isnull(var) ((var)->value == 0) #define var_isset(var) ((var)->value != 0) +#define var_isunset(var) ((var)->value == 0) +#define var_isnull(var) ((var)->value && *(var)->value == 0) /* Assigning variable values: lvalues */ #define var_setvalue(var, str) ((var)->value = (str)) @@ -375,6 +379,7 @@ extern void sv_ifs __P((char *)); extern void sv_path __P((char *)); extern void sv_mail __P((char *)); extern void sv_funcnest __P((char *)); +extern void sv_execignore __P((char *)); extern void sv_globignore __P((char *)); extern void sv_ignoreeof __P((char *)); extern void sv_strict_posix __P((char *));