From cdb32d454ae91cf2e468936e745cbeb56ae7770d Mon Sep 17 00:00:00 2001 From: Chet Ramey Date: Sat, 3 Dec 2011 13:50:00 -0500 Subject: [PATCH] commit bash-20050817 snapshot --- CWRU/CWRU.chlog | 59 ++++++++++++++++++++++++++++ CWRU/CWRU.chlog~ | 56 ++++++++++++++++++++++++++- builtins/cd.def | 5 ++- builtins/cd.def~ | 49 ++++++++++++----------- builtins/read.def | 9 +++++ builtins/read.def~ | 12 +++++- doc/bash.1 | 2 +- doc/bash.1~ | 8 +++- doc/bashref.texi | 5 --- execute_cmd.c | 19 +++------ findcmd.c | 75 ++++++++++++++++++++++++------------ general.h | 1 + jobs.c | 20 +++------- jobs.c~ | 31 +++++---------- lib/readline/doc/readline.3 | 4 +- lib/readline/doc/readline.3~ | 13 ++++++- subst.c | 21 ++++------ subst.c~ | 27 +++++++------ tests/exec.right | 2 +- tests/func.tests | 8 ++++ 20 files changed, 279 insertions(+), 147 deletions(-) diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index 640c2b41f..bb67b2fb7 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -11890,3 +11890,62 @@ variables.h lib/readline/display.c - call init_line_structures from rl_redisplay if vis_lbreaks == 0 to avoid consequences of a poorly-timed SIGWINCH + + 8/16 + ---- +subst.c + - fix logic for performing tilde expansion when in posix mode (don't + rely on W_TILDEEXP flag always being set, because it won't be when + expanding the RHS of assignment statement). Use W_TILDEEXP only + when deciding to expand a word marked as W_ASSIGNMENT that doesn't + precede a command name + + 8/17 + ---- +execute_cmd.c + - in execute_function, when subshell == 1, don't short-cut by using + the command contained in the group command -- if you do, any + redirections attached to the group command (function) don't get + executed + +general.h + - new #define, FS_READABLE, indicates file is readable by current + user + +findcmd.c + - rewrote file_status to use S_xxx POSIX file mode bits and to add + support for FS_READABLE (affects ./source and searching $PATH for + scripts whose names are supplied as arguments on the command line) + - change find_path_file to look for readable files -- source requires + it + - change find_in_path_element to do the right thing when FS_READABLE + is supplied as a flag + +doc/bashref.texi + - remove note about posix non-compliance in `.': we now require and + look for readable files when searching $PATH + + 8/20 + ---- +subst.c + - fix setifs to handle case where passed variable is non-zero but + v->value == 0 (as in an unset local variable); treat IFS as unset + in this case + +jobs.c + - in kill_pid, if asked to killpg a process or pgrp whose pgrp is + recorded as the same as the shell's, just call killpg and let the + chips fall where they may -- there may be other processes in that + pgrp that are not children of the shell, so killing each process + in the pipeline will not do a complete job, and killpg'ing each + such process will send too many signals in the majority of cases + +builtins/cd.def + - in posix mode, pwd needs to check that the value it prints and `.' + are the same file + +builtins/read.def + - if reading input from stdin in a non-interactive shell and calling + `read', call sync_buffered_stream to seek backward in the input + stream if necessary (XXX - should we do this for all shell builtins?) + diff --git a/CWRU/CWRU.chlog~ b/CWRU/CWRU.chlog~ index 753517b56..1fb448760 100644 --- a/CWRU/CWRU.chlog~ +++ b/CWRU/CWRU.chlog~ @@ -11888,5 +11888,59 @@ variables.h 8/15 ---- lib/readline/display.c - - call init_line_structures from rl_redisplay if inv_lbreaks == 0 + - call init_line_structures from rl_redisplay if vis_lbreaks == 0 to avoid consequences of a poorly-timed SIGWINCH + + 8/16 + ---- +subst.c + - fix logic for performing tilde expansion when in posix mode (don't + rely on W_TILDEEXP flag always being set, because it won't be when + expanding the RHS of assignment statement). Use W_TILDEEXP only + when deciding to expand a word marked as W_ASSIGNMENT that doesn't + precede a command name + + 8/17 + ---- +execute_cmd.c + - in execute_function, when subshell == 1, don't short-cut by using + the command contained in the group command -- if you do, any + redirections attached to the group command (function) don't get + executed + +general.h + - new #define, FS_READABLE, indicates file is readable by current + user + +findcmd.c + - rewrote file_status to use S_xxx POSIX file mode bits and to add + support for FS_READABLE (affects ./source and searching $PATH for + scripts whose names are supplied as arguments on the command line) + - change find_path_file to look for readable files -- source requires + it + - change find_in_path_element to do the right thing when FS_READABLE + is supplied as a flag + +doc/bashref.texi + - remove note about posix non-compliance in `.': we now require and + look for readable files when searching $PATH + + 8/20 + ---- +subst.c + - fix setifs to handle case where passed variable is non-zero but + v->value == 0 (as in an unset local variable); treat IFS as unset + in this case + +jobs.c + - in kill_pid, if asked to killpg a process or pgrp whose pgrp is + recorded as the same as the shell's, just call killpg and let the + chips fall where they may -- there may be other processes in that + pgrp that are not children of the shell, so killing each process + in the pipeline will not do a complete job, and killpg'ing each + such process will send too many signals in the majority of cases + +builtins/cd.def + - in posix mode, pwd needs to check that the value it prints and `.' + are the same file + diff --git a/builtins/cd.def b/builtins/cd.def index d7bf77054..e9be35ad0 100644 --- a/builtins/cd.def +++ b/builtins/cd.def @@ -315,7 +315,7 @@ cd_builtin (list) $BUILTIN pwd $FUNCTION pwd_builtin -$SHORT_DOC pwd [-PL] +$SHORT_DOC pwd [-LP] Print the current working directory. With the -P option, pwd prints the physical directory, without any symbolic links; the -L option makes pwd follow symbolic links. @@ -360,7 +360,8 @@ pwd_builtin (list) /* Try again using getcwd() if canonicalization fails (for instance, if the file system has changed state underneath bash). */ - if (tcwd && directory == 0) + if ((tcwd && directory == 0) || + (posixly_correct && same_file (".", tcwd, (struct stat *)0, (struct stat *)0) == 0)) directory = resetpwd ("pwd"); #undef tcwd diff --git a/builtins/cd.def~ b/builtins/cd.def~ index e95825408..1dcf626b6 100644 --- a/builtins/cd.def~ +++ b/builtins/cd.def~ @@ -85,6 +85,23 @@ instead of following symbolic links; the -L option forces symbolic links to be followed. $END +/* Just set $PWD, don't change OLDPWD. Used by `pwd -P' in posix mode. */ +static void +setpwd (dirname) + char *dirname; +{ + int old_anm; + SHELL_VAR *tvar; + + old_anm = array_needs_making; + tvar = bind_variable ("PWD", dirname ? dirname : "", 0); + if (old_anm == 0 && array_needs_making && exported_p (tvar)) + { + update_export_env_inplace ("PWD=", 4, dirname ? dirname : ""); + array_needs_making = 0; + } +} + static int bindpwd (no_symlinks) int no_symlinks; @@ -108,12 +125,7 @@ bindpwd (no_symlinks) array_needs_making = 0; } - tvar = bind_variable ("PWD", dirname ? dirname : "", 0); - if (old_anm == 0 && array_needs_making && exported_p (tvar)) - { - update_export_env_inplace ("PWD=", 4, dirname ? dirname : ""); - array_needs_making = 0; - } + setpwd (dirname); if (dirname && dirname != the_current_working_directory) free (dirname); @@ -121,23 +133,6 @@ bindpwd (no_symlinks) return (EXECUTION_SUCCESS); } -/* Just set $PWD, don't change OLDPWD. Used by `pwd -P' in posix mode. */ -static void -setpwd (dirname) - char *dirname; -{ - int old_anm; - SHELL_VAR *tvar; - - old_anm = array_needs_making; - tvar = bind_variable ("PWD", dirname ? dirname : "", 0); - if (old_anm == 0 && array_needs_making && exported_p (tvar)) - { - update_export_env_inplace ("PWD=", 4, dirname ? dirname : ""); - array_needs_making = 0; - } -} - /* Call get_working_directory to reset the value of the_current_working_directory () */ static char * @@ -251,9 +246,13 @@ cd_builtin (list) printf ("%s\n", path); free (temp); +#if 0 /* Posix.2 says that after using CDPATH, the resultant value of $PWD will not contain `.' or `..'. */ return (bindpwd (posixly_correct || no_symlinks)); +#else + return (bindpwd (no_symlinks)); +#endif } else free (temp); @@ -316,7 +315,7 @@ cd_builtin (list) $BUILTIN pwd $FUNCTION pwd_builtin -$SHORT_DOC pwd [-PL] +$SHORT_DOC pwd [-LP] Print the current working directory. With the -P option, pwd prints the physical directory, without any symbolic links; the -L option makes pwd follow symbolic links. @@ -361,7 +360,7 @@ pwd_builtin (list) /* Try again using getcwd() if canonicalization fails (for instance, if the file system has changed state underneath bash). */ - if (tcwd && directory == 0) + if ((tcwd && directory == 0) || (posixly_correct && file_isdir (tcwd) == 0)) directory = resetpwd ("pwd"); #undef tcwd diff --git a/builtins/read.def b/builtins/read.def index 4f980a825..914ebd7d0 100644 --- a/builtins/read.def +++ b/builtins/read.def @@ -79,6 +79,10 @@ $END #include #endif +#if defined (BUFFERED_INPUT) +# include "input.h" +#endif + #if !defined(errno) extern int errno; #endif @@ -273,6 +277,11 @@ read_builtin (list) begin_unwind_frame ("read_builtin"); +#if defined (BUFFERED_INPUT) + if (interactive == 0 && default_buffered_input >= 0 && fd_is_bash_input (fd)) + sync_buffered_stream (default_buffered_input); +#endif + input_is_tty = isatty (fd); if (input_is_tty == 0) #ifndef __CYGWIN__ diff --git a/builtins/read.def~ b/builtins/read.def~ index c7319d41b..914ebd7d0 100644 --- a/builtins/read.def~ +++ b/builtins/read.def~ @@ -79,6 +79,10 @@ $END #include #endif +#if defined (BUFFERED_INPUT) +# include "input.h" +#endif + #if !defined(errno) extern int errno; #endif @@ -273,6 +277,11 @@ read_builtin (list) begin_unwind_frame ("read_builtin"); +#if defined (BUFFERED_INPUT) + if (interactive == 0 && default_buffered_input >= 0 && fd_is_bash_input (fd)) + sync_buffered_stream (default_buffered_input); +#endif + input_is_tty = isatty (fd); if (input_is_tty == 0) #ifndef __CYGWIN__ @@ -664,7 +673,6 @@ add_char: return (retval); } -/* XXX - should we call stupidly_hack_special_variables here? */ static SHELL_VAR * bind_read_variable (name, value) char *name, *value; @@ -689,7 +697,7 @@ edit_line (p) char *ret; int len; - if (!bash_readline_initialized) + if (bash_readline_initialized == 0) initialize_readline (); old_attempted_completion_function = rl_attempted_completion_function; rl_attempted_completion_function = (rl_completion_func_t *)NULL; diff --git a/doc/bash.1 b/doc/bash.1 index fc1318b09..4b7843dcc 100644 --- a/doc/bash.1 +++ b/doc/bash.1 @@ -4634,7 +4634,7 @@ arrow keys. If set to \fBon\fP, tilde expansion is performed when readline attempts word completion. .TP -.B history-preserve-point +.B history\-preserve\-point (Off) If set to \fBon\fP, the history code attempts to place point at the same location on each history line retrieved with \fBprevious-history\fP or \fBnext-history\fP. diff --git a/doc/bash.1~ b/doc/bash.1~ index 8c9f6045f..fc1318b09 100644 --- a/doc/bash.1~ +++ b/doc/bash.1~ @@ -6,12 +6,12 @@ .\" Case Western Reserve University .\" chet@po.CWRU.Edu .\" -.\" Last Change: Sat Apr 30 19:09:18 EDT 2005 +.\" Last Change: Fri Jul 15 23:15:01 EDT 2005 .\" .\" bash_builtins, strip all but Built-Ins section .if \n(zZ=1 .ig zZ .if \n(zY=1 .ig zY -.TH BASH 1 "2005 Apr 30" "GNU Bash-3.1-devel" +.TH BASH 1 "2005 Jul 15" "GNU Bash-3.1-devel" .\" .\" There's some problem with having a `@' .\" in a tagged paragraph with the BSD man macros. @@ -1986,6 +1986,10 @@ number of seconds to wait for input after issuing the primary prompt. terminates after waiting for that number of seconds if input does not arrive. .TP +.B TMPDIR +If set, \fBBash\fP uses its value as the name of a directory in which +\fBBash\fP creates temporary files for the shell's use. +.TP .B auto_resume This variable controls how the shell interacts with the user and job control. If this variable is set, single word simple diff --git a/doc/bashref.texi b/doc/bashref.texi index e3f2d8ac5..a0870b6b7 100644 --- a/doc/bashref.texi +++ b/doc/bashref.texi @@ -6090,11 +6090,6 @@ but without a leading @samp{#!}, Bash sets @code{$0} to the full pathname of the script as found by searching @code{$PATH}, rather than the command as typed by the user. -@item -When using @samp{.} to source a shell script found in @code{$PATH}, bash -checks execute permission bits rather than read permission bits, just as -if it were searching for a command. - @end enumerate @node Job Control diff --git a/execute_cmd.c b/execute_cmd.c index 0c81fff19..63da5a97c 100644 --- a/execute_cmd.c +++ b/execute_cmd.c @@ -3050,12 +3050,9 @@ execute_builtin (builtin, words, flags, subshell) /* The temporary environment for a builtin is supposed to apply to all commands executed by that builtin. Currently, this is a - problem only with the `source' and `eval' builtins. */ -#if 0 - isbltinenv = (builtin == source_builtin || builtin == eval_builtin); -#else + problem only with the `unset', `source' and `eval' builtins. */ + isbltinenv = (builtin == source_builtin || builtin == eval_builtin || builtin == unset_builtin); -#endif if (isbltinenv) { @@ -3227,18 +3224,12 @@ execute_function (var, words, flags, fds_to_close, async, subshell) /* Number of the line on which the function body starts. */ line_number = function_line_number = tc->line; - if (subshell) - { #if defined (JOB_CONTROL) - stop_pipeline (async, (COMMAND *)NULL); + if (subshell) + stop_pipeline (async, (COMMAND *)NULL); #endif - fc = (tc->type == cm_group) ? tc->value.Group->command : tc; - if (fc && (flags & CMD_IGNORE_RETURN)) - fc->flags |= CMD_IGNORE_RETURN; - } - else - fc = tc; + fc = tc; return_catch_flag++; return_val = setjmp (return_catch); diff --git a/findcmd.c b/findcmd.c index 09ad2fadc..6f5ff8584 100644 --- a/findcmd.c +++ b/findcmd.c @@ -72,11 +72,6 @@ int check_hashed_filenames; containing the file of interest. */ int dot_found_in_search = 0; -#define u_mode_bits(x) (((x) & 0000700) >> 6) -#define g_mode_bits(x) (((x) & 0000070) >> 3) -#define o_mode_bits(x) (((x) & 0000007) >> 0) -#define X_BIT(x) ((x) & 1) - /* 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. @@ -86,6 +81,7 @@ file_status (name) const char *name; { struct stat finfo; + int r; /* Determine whether this file exists or not. */ if (stat (name, &finfo) < 0) @@ -96,41 +92,62 @@ file_status (name) if (S_ISDIR (finfo.st_mode)) return (FS_EXISTS|FS_DIRECTORY); + r = FS_EXISTS; + #if defined (AFS) /* 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. */ - return ((access (name, X_OK) == 0) ? (FS_EXISTS|FS_EXECABLE) : FS_EXISTS); + if (access (name, X_OK) == 0) + r |= FS_EXECABLE; + if (access (name, R_OK) == 0) + r |= FS_READABLE; + + return r; #else /* !AFS */ /* Find out if the file is actually executable. By definition, the only other criteria is that the file has an execute bit set that - we can use. */ + we can use. The same with whether or not a file is readable. */ /* Root only requires execute permission for any of owner, group or - others to be able to exec a file. */ + others to be able to exec a file, and can read any file. */ if (current_user.euid == (uid_t)0) { - int bits; - - bits = (u_mode_bits (finfo.st_mode) | - g_mode_bits (finfo.st_mode) | - o_mode_bits (finfo.st_mode)); - - return ((X_BIT (bits)) ? (FS_EXISTS | FS_EXECABLE) : FS_EXISTS); + r |= FS_READABLE; + if (finfo.st_mode & S_IXUGO) + r |= FS_EXECABLE; + return r; } - /* If we are the owner of the file, the owner execute bit applies. */ + /* If we are the owner of the file, the owner bits apply. */ if (current_user.euid == finfo.st_uid) - return ((X_BIT (u_mode_bits (finfo.st_mode))) ? (FS_EXISTS | FS_EXECABLE) : FS_EXISTS); + { + if (finfo.st_mode & S_IXUSR) + r |= FS_EXECABLE; + if (finfo.st_mode & S_IRUSR) + r |= FS_READABLE; + } /* If we are in the owning group, the group permissions apply. */ else if (group_member (finfo.st_gid)) - return ((X_BIT (g_mode_bits (finfo.st_mode))) ? (FS_EXISTS | FS_EXECABLE) : FS_EXISTS); + { + if (finfo.st_mode & S_IXGRP) + r |= FS_EXECABLE; + if (finfo.st_mode & S_IRGRP) + r |= FS_READABLE; + } /* Else we check whether `others' have permission to execute the file */ else - return ((X_BIT (o_mode_bits (finfo.st_mode))) ? (FS_EXISTS | FS_EXECABLE) : FS_EXISTS); + { + if (finfo.st_mode & S_IXOTH) + r |= FS_EXECABLE; + if (finfo.st_mode & S_IROTH) + r |= FS_READABLE; + } + + return r; #endif /* !AFS */ } @@ -180,12 +197,13 @@ find_user_command (name) /* Locate the file referenced by NAME, searching along the contents of the shell PATH variable. Return a new string which is the full pathname to the file, or NULL if the file couldn't be found. This - returns the first file found. */ + returns the first readable file found; designed to be used to look + for shell scripts or files to source. */ char * find_path_file (name) const char *name; { - return (find_user_command_internal (name, FS_EXISTS)); + return (find_user_command_internal (name, FS_READABLE)); } static char * @@ -460,9 +478,14 @@ find_in_path_element (name, path, flags, name_len, dotinfop) if (flags & FS_EXISTS) return (full_path); + /* If we have a readable file, and the caller wants a readable file, this + is it. */ + if ((flags & FS_READABLE) && (status & FS_READABLE)) + return (full_path); + /* If the file is executable, then it satisfies the cases of EXEC_ONLY and EXEC_PREFERRED. Return this file unconditionally. */ - if ((status & FS_EXECABLE) && + if ((status & FS_EXECABLE) && (flags & (FS_EXEC_ONLY|FS_EXEC_PREFERRED)) && (((flags & FS_NODIRS) == 0) || ((status & FS_DIRECTORY) == 0))) { FREE (file_to_lose_on); @@ -477,9 +500,11 @@ find_in_path_element (name, path, flags, name_len, dotinfop) file_to_lose_on = savestring (full_path); /* If we want only executable files, or we don't want directories and - this file is a directory, fail. */ - if ((flags & FS_EXEC_ONLY) || (flags & FS_EXEC_PREFERRED) || - ((flags & FS_NODIRS) && (status & FS_DIRECTORY))) + this file is a directory, or we want a readable file and this file + isn't readable, fail. */ + if ((flags & (FS_EXEC_ONLY|FS_EXEC_PREFERRED)) || + ((flags & FS_NODIRS) && (status & FS_DIRECTORY)) || + ((flags & FS_READABLE) && (status & FS_READABLE) == 0)) { free (full_path); return ((char *)NULL); diff --git a/general.h b/general.h index 46273547f..9e73e624c 100644 --- a/general.h +++ b/general.h @@ -232,6 +232,7 @@ typedef int sh_builtin_func_t __P((WORD_LIST *)); /* sh_wlist_func_t */ #define FS_EXEC_ONLY 0x8 #define FS_DIRECTORY 0x10 #define FS_NODIRS 0x20 +#define FS_READABLE 0x40 /* Default maximum for move_to_high_fd */ #define HIGH_FD_MAX 256 diff --git a/jobs.c b/jobs.c index 3f84ad0cc..5e8b53d30 100644 --- a/jobs.c +++ b/jobs.c @@ -1984,6 +1984,10 @@ wait_for_single_pid (pid) jobs[job]->flags |= J_NOTIFIED; UNBLOCK_CHILD (oset); + /* If running in posix mode, remove the job from the jobs table immediately */ + if (posixly_correct) + cleanup_dead_jobs (); + return r; } @@ -2759,21 +2763,7 @@ kill_pid (pid, sig, group) /* Kill process in backquotes or one started without job control? */ if (jobs[job]->pgrp == shell_pgrp) - { - p = jobs[job]->pipe; - - do - { - if (PALIVE (p) == 0) - continue; /* avoid pid recycling problems */ - - kill (p->pid, sig); - if (PEXITED (p) && (sig == SIGTERM || sig == SIGHUP)) - kill (p->pid, SIGCONT); - p = p->next; - } - while (p != jobs[job]->pipe); - } + result = killpg (pid, sig); else { result = killpg (jobs[job]->pgrp, sig); diff --git a/jobs.c~ b/jobs.c~ index b9d03b186..a7b3f917c 100644 --- a/jobs.c~ +++ b/jobs.c~ @@ -2759,21 +2759,7 @@ kill_pid (pid, sig, group) /* Kill process in backquotes or one started without job control? */ if (jobs[job]->pgrp == shell_pgrp) - { - p = jobs[job]->pipe; - - do - { - if (PALIVE (p) == 0) - continue; /* avoid pid recycling problems */ - - kill (p->pid, sig); - if (PEXITED (p) && (sig == SIGTERM || sig == SIGHUP)) - kill (p->pid, SIGCONT); - p = p->next; - } - while (p != jobs[job]->pipe); - } + result = killpg (pid, sig); else { result = killpg (jobs[job]->pgrp, sig); @@ -3104,10 +3090,10 @@ set_job_status_and_cleanup (job) if (temp_handler == trap_handler && signal_is_trapped (SIGINT) == 0) temp_handler = trap_to_sighandler (SIGINT); restore_sigint_handler (); - if (temp_handler == SIG_DFL) - termination_unwind_protect (SIGINT); - else if (temp_handler != SIG_IGN) - (*temp_handler) (SIGINT); + if (temp_handler == SIG_DFL) + termination_unwind_protect (SIGINT); + else if (temp_handler != SIG_IGN) + (*temp_handler) (SIGINT); } } } @@ -3225,9 +3211,10 @@ notify_of_job_status () /* POSIX.2 says we have to hang onto the statuses of at most the last CHILD_MAX background processes if the shell is running a - script. If the shell is not interactive, don't print anything - unless the job was killed by a signal. */ - if (startup_state == 0 && WIFSIGNALED (s) == 0 && job_control == 0 && + script. If the shell is running a script, either from a file + or standard input, don't print anything unless the job was + killed by a signal. */ + if (startup_state == 0 && WIFSIGNALED (s) == 0 && ((DEADJOB (job) && IS_FOREGROUND (job) == 0) || STOPPED (job))) continue; diff --git a/lib/readline/doc/readline.3 b/lib/readline/doc/readline.3 index 3bdf6e1aa..e86922d7a 100644 --- a/lib/readline/doc/readline.3 +++ b/lib/readline/doc/readline.3 @@ -396,9 +396,9 @@ arrow keys. If set to \fBon\fP, tilde expansion is performed when readline attempts word completion. .TP -.B history-preserve-point +.B history\-preserve\-point (Off) If set to \fBon\fP, the history code attempts to place point at the -same location on each history line retrived with \fBprevious-history\fP +same location on each history line retrieved with \fBprevious-history\fP or \fBnext-history\fP. .TP .B horizontal\-scroll\-mode (Off) diff --git a/lib/readline/doc/readline.3~ b/lib/readline/doc/readline.3~ index 560bbe72b..3bdf6e1aa 100644 --- a/lib/readline/doc/readline.3~ +++ b/lib/readline/doc/readline.3~ @@ -6,9 +6,9 @@ .\" Case Western Reserve University .\" chet@ins.CWRU.Edu .\" -.\" Last Change: Wed Jan 28 15:43:53 EST 2004 +.\" Last Change: Mon Nov 22 11:10:14 EST 2004 .\" -.TH READLINE 3 "2004 January 28" "GNU Readline 5.0" +.TH READLINE 3 "2004 Nov 22" "GNU Readline 5.1-devel" .\" .\" File Name macro. This used to be `.PN', for Path Name, .\" but Sun doesn't seem to like that very much. @@ -338,6 +338,11 @@ If set to \fBnone\fP, readline never rings the bell. If set to \fBvisible\fP, readline uses a visible bell if one is available. If set to \fBaudible\fP, readline attempts to ring the terminal's bell. .TP +.B bind\-tty\-special\-chars (On) +If set to \fBOn\fP, readline attempts to bind the control characters +treated specially by the kernel's terminal driver to their readline +equivalents. +.TP .B comment\-begin (``#'') The string that is inserted in \fBvi\fP mode when the .B insert\-comment @@ -691,6 +696,8 @@ With an argument insert the \fIn\fPth word from the previous command (the words in the previous command begin with word 0). A negative argument inserts the \fIn\fPth word from the end of the previous command. +Once the argument \fIn\fP is computed, the argument is extracted +as if the "!\fIn\fP" history expansion had been specified. .TP .B yank\-last\-arg (M\-.\^, M\-_\^) @@ -699,6 +706,8 @@ the previous history entry). With an argument, behave exactly like \fByank\-nth\-arg\fP. Successive calls to \fByank\-last\-arg\fP move back through the history list, inserting the last argument of each line in turn. +The history expansion facilities are used to extract the last argument, +as if the "!$" history expansion had been specified. .PD .SS Commands for Changing Text .PP diff --git a/subst.c b/subst.c index 7a8207fdd..02c7a8f69 100644 --- a/subst.c +++ b/subst.c @@ -3816,13 +3816,8 @@ list_remove_pattern (list, pattern, patspec, itype, quoted) for (new = (WORD_LIST *)NULL, l = list; l; l = l->next) { tword = remove_pattern (l->word->word, pattern, patspec); -#if 0 - w = make_bare_word (tword); - FREE (tword); -#else w = alloc_word_desc (); w->word = tword ? tword : savestring (""); -#endif new = make_word_list (w, new); } @@ -5615,13 +5610,8 @@ pos_params_pat_subst (string, pat, rep, mflags) for ( ; params; params = params->next) { ret = pat_subst (params->word->word, pat, rep, mflags); -#if 0 - w = make_bare_word (ret); - FREE (ret); -#else w = alloc_word_desc (); w->word = ret ? ret : savestring (""); -#endif dispose_word (params->word); params->word = w; } @@ -6759,8 +6749,8 @@ add_string: case ':': if (word->flags & W_NOTILDE) goto add_character; - if ((word->flags & (W_ASSIGNMENT|W_ASSIGNRHS)) && - (posixly_correct == 0 || (word->flags & W_TILDEEXP)) && + + if ((word->flags & (W_ASSIGNMENT|W_ASSIGNRHS|W_TILDEEXP)) && string[sindex+1] == '~') word->flags |= W_ITILDE; goto add_character; @@ -6779,8 +6769,7 @@ add_string: if (word->flags & W_ASSIGNRHS) tflag = 2; - else if ((word->flags & W_ASSIGNMENT) && - (posixly_correct == 0 || (word->flags & W_TILDEEXP))) + else if (word->flags & (W_ASSIGNMENT|W_TILDEEXP)) tflag = 1; else tflag = 0; @@ -7372,7 +7361,11 @@ setifs (v) unsigned char uc; ifs_var = v; +#if 0 ifs_value = v ? value_cell (v) : " \t\n"; +#else + ifs_value = (v && value_cell (v)) ? value_cell (v) : " \t\n"; +#endif /* Should really merge ifs_cmap with sh_syntaxtab. XXX - doesn't yet handle multibyte chars in IFS */ diff --git a/subst.c~ b/subst.c~ index b24e9c04d..869944303 100644 --- a/subst.c~ +++ b/subst.c~ @@ -3816,13 +3816,8 @@ list_remove_pattern (list, pattern, patspec, itype, quoted) for (new = (WORD_LIST *)NULL, l = list; l; l = l->next) { tword = remove_pattern (l->word->word, pattern, patspec); -#if 0 - w = make_bare_word (tword); - FREE (tword); -#else w = alloc_word_desc (); w->word = tword ? tword : savestring (""); -#endif new = make_word_list (w, new); } @@ -5615,13 +5610,8 @@ pos_params_pat_subst (string, pat, rep, mflags) for ( ; params; params = params->next) { ret = pat_subst (params->word->word, pat, rep, mflags); -#if 0 - w = make_bare_word (ret); - FREE (ret); -#else w = alloc_word_desc (); w->word = ret ? ret : savestring (""); -#endif dispose_word (params->word); params->word = w; } @@ -6759,8 +6749,8 @@ add_string: case ':': if (word->flags & W_NOTILDE) goto add_character; - if ((word->flags & (W_ASSIGNMENT|W_ASSIGNRHS)) && - (posixly_correct == 0 || (word->flags & W_TILDEEXP)) && + + if ((word->flags & (W_ASSIGNMENT|W_ASSIGNRHS|W_TILDEEXP)) && string[sindex+1] == '~') word->flags |= W_ITILDE; goto add_character; @@ -6779,8 +6769,7 @@ add_string: if (word->flags & W_ASSIGNRHS) tflag = 2; - else if ((word->flags & W_ASSIGNMENT) && - (posixly_correct == 0 || (word->flags & W_TILDEEXP))) + else if (word->flags & (W_ASSIGNMENT|W_TILDEEXP)) tflag = 1; else tflag = 0; @@ -7046,7 +7035,11 @@ add_twochars: /* break; */ case '\'': +#if 0 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || (word->flags & W_DQUOTE)) +#else + if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))) +#endif goto add_character; t_index = ++sindex; @@ -7368,7 +7361,13 @@ setifs (v) unsigned char uc; ifs_var = v; +#if 0 ifs_value = v ? value_cell (v) : " \t\n"; +#else + ifs_value = v ? value_cell (v) : (char *)0; + if (ifs_value == 0) + ifs_value = " \t\n"; +#endif /* Should really merge ifs_cmap with sh_syntaxtab. XXX - doesn't yet handle multibyte chars in IFS */ diff --git a/tests/exec.right b/tests/exec.right index c7d42dd01..d65b89df6 100644 --- a/tests/exec.right +++ b/tests/exec.right @@ -12,7 +12,7 @@ after exec1.sub without args: 0 126 ./execscript: line 39: /: is a directory 126 -/: /: cannot execute binary file +/: /: is a directory 126 ./execscript: line 46: .: /: is a directory 1 diff --git a/tests/func.tests b/tests/func.tests index 2095f2499..063f4e0b8 100644 --- a/tests/func.tests +++ b/tests/func.tests @@ -157,4 +157,12 @@ ${THIS_SH} ./func2.sub # test for some posix-specific function behavior ${THIS_SH} ./func3.sub +unset -f myfunction +myfunction() { + echo "bad shell function redirection" +} >> /dev/null + +myfunction +myfunction | cat + exit 0 -- 2.47.3