diff --git a/NEWS b/NEWS index 87a281a46343..1d4e483d383f 100644 --- a/NEWS +++ b/NEWS @@ -17,6 +17,11 @@ Any uppercase BUG_* names are modernish shell bug IDs. b. 'command' can now stop the shell from exiting if a command that it invokes tries to modify a readonly variable (fixing BUG_CMDSPEXIT). +- The 'history' (== 'hist -l') and 'r' (== 'hist -s') interactive shell + history commands have reverted to preset aliases and are now only loaded if + the shell is interactive and not initialised in POSIX mode. This avoids + unneeded conflicts with external commands by these names, particularly 'r'. + 2020-09-09: - Fixed BUG_LOOPRET2 and related bugs. The 'exit' and 'return' commands without diff --git a/src/cmd/ksh93/Makefile b/src/cmd/ksh93/Makefile index 00cee46290e4..4982988f6f2d 100644 --- a/src/cmd/ksh93/Makefile +++ b/src/cmd/ksh93/Makefile @@ -145,7 +145,7 @@ end $(SH) :: sh.1 pmain.c $(LIBS_req) DATAFILES = limits.c msg.c strdata.c testops.c keywords.c options.c \ - signals.c builtins.c variables.c lexstates.c + signals.c aliases.c builtins.c variables.c lexstates.c shell$(RELEASE) $(VERSION) id=shell :LIBRARY: shell.3 nval.3 alarm.c cd_pwd.c cflow.c deparse.c \ enum.c getopts.c hist.c misc.c print.c read.c sleep.c trap.c test.c \ diff --git a/src/cmd/ksh93/Mamfile b/src/cmd/ksh93/Mamfile index c24fa49025b9..0fe4f356635f 100644 --- a/src/cmd/ksh93/Mamfile +++ b/src/cmd/ksh93/Mamfile @@ -1217,6 +1217,16 @@ meta signals.o %.c>%.o data/signals.c signals prev data/signals.c exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -DSHOPT_STATS -DSHOPT_NAMESPACE -DSHOPT_PFSH -DSHOPT_HISTEXPAND -D_BLD_shell -D_API_ast=20100309 -D_PACKAGE_ast -DERROR_CONTEXT_T=Error_context_t -DSHOPT_FIXEDARRAY -DSHOPT_ESH -DSHOPT_MULTIBYTE -c data/signals.c done signals.o generated +make aliases.o +make data/aliases.c +prev FEATURE/dynamic implicit +prev FEATURE/options implicit +prev include/defs.h implicit +done data/aliases.c +meta aliases.o %.c>%.o data/aliases.c aliases +prev data/aliases.c +exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -DSHOPT_DYNAMIC -DSHOPT_MULTIBYTE -D_PACKAGE_ast -DSHOPT_PFSH -DSHOPT_STATS -DSHOPT_NAMESPACE -DSHOPT_COSHELL -DSHOPT_HISTEXPAND -D_BLD_shell -D_API_ast=20100309 -DERROR_CONTEXT_T=Error_context_t -DSHOPT_FIXEDARRAY -DSHOPT_ESH -c data/aliases.c +done aliases.o generated make builtins.o make data/builtins.c prev FEATURE/cmds implicit @@ -1298,7 +1308,7 @@ prev edit/hexpand.c exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -DSHOPT_HISTEXPAND -DSHOPT_EDPREDICT -DSHOPT_MULTIBYTE -DKSHELL -DSHOPT_ESH -DSHOPT_VSH -D_PACKAGE_ast -DSHOPT_PFSH -DSHOPT_STATS -DSHOPT_NAMESPACE -D_BLD_shell -D_API_ast=20100309 -DERROR_CONTEXT_T=Error_context_t -DSHOPT_FIXEDARRAY -c edit/hexpand.c done hexpand.o generated exec - ${AR} rc libshell.a alarm.o cd_pwd.o cflow.o deparse.o enum.o getopts.o hist.o misc.o print.o read.o sleep.o trap.o test.o typeset.o ulimit.o umask.o whence.o main.o nvdisc.o nvtype.o arith.o args.o array.o completion.o defs.o edit.o expand.o regress.o fault.o fcin.o -exec - ${AR} rc libshell.a history.o init.o io.o jobs.o lex.o macro.o name.o nvtree.o parse.o path.o string.o streval.o subshell.o tdump.o timers.o trestore.o waitevent.o xec.o limits.o msg.o strdata.o testops.o keywords.o options.o signals.o builtins.o variables.o lexstates.o emacs.o vi.o hexpand.o +exec - ${AR} rc libshell.a history.o init.o io.o jobs.o lex.o macro.o name.o nvtree.o parse.o path.o string.o streval.o subshell.o tdump.o timers.o trestore.o waitevent.o xec.o limits.o msg.o strdata.o testops.o keywords.o options.o signals.o aliases.o builtins.o variables.o lexstates.o emacs.o vi.o hexpand.o exec - (ranlib libshell.a) >/dev/null 2>&1 || true done libshell.a generated bind -lshell diff --git a/src/cmd/ksh93/bltins/hist.c b/src/cmd/ksh93/bltins/hist.c index 26a05a422223..46ae07758184 100644 --- a/src/cmd/ksh93/bltins/hist.c +++ b/src/cmd/ksh93/bltins/hist.c @@ -58,13 +58,6 @@ int b_hist(int argc,char *argv[], Shbltin_t *context) NOT_USED(argc); if(!sh_histinit((void*)shp)) errormsg(SH_DICT,ERROR_system(1),e_histopen); - - /* 'history' and 'r' builtins */ - if(argv[0][0] == 'r') /* */ - edit = "-"; - else if(argv[0][0] == 'h' && argv[0][4] == 'o') /* histry (argv[0][4] is zero when called as 'hist') */ - lflag = 1; - hp = shp->gd->hist_ptr; while((flag = optget(argv,sh_opthist))) switch(flag) { diff --git a/src/cmd/ksh93/bltins/typeset.c b/src/cmd/ksh93/bltins/typeset.c index d0a31da2a56c..8b91cc20bbc2 100644 --- a/src/cmd/ksh93/bltins/typeset.c +++ b/src/cmd/ksh93/bltins/typeset.c @@ -1311,7 +1311,7 @@ static int unall(int argc, char **argv, register Dt_t *troot, Shell_t* shp) } /* The alias has been unset by call to _nv_unset, remove it from the tree */ else if(troot==shp->alias_tree) - nv_delete(np,troot,0); + nv_delete(np,troot,nv_isattr(np,NV_NOFREE)); #if 0 /* causes unsetting local variable to expose global */ else if(shp->var_tree==troot && shp->var_tree!=shp->var_base && nv_search((char*)np,shp->var_tree,HASH_BUCKET|HASH_NOSCOPE)) diff --git a/src/cmd/ksh93/data/aliases.c b/src/cmd/ksh93/data/aliases.c new file mode 100644 index 000000000000..c212221212d0 --- /dev/null +++ b/src/cmd/ksh93/data/aliases.c @@ -0,0 +1,35 @@ +/*********************************************************************** +* * +* This software is part of the ast package * +* Copyright (c) 1982-2012 AT&T Intellectual Property * +* and is licensed under the * +* Eclipse Public License, Version 1.0 * +* by AT&T Intellectual Property * +* * +* A copy of the License is available at * +* http://www.eclipse.org/org/documents/epl-v10.html * +* (with md5 checksum b35adb5213ca9657e911e9befb180842) * +* * +* Information and Software Systems Research * +* AT&T Research * +* Florham Park NJ * +* * +* David Korn * +* * +***********************************************************************/ +#pragma prototyped +#include "defs.h" +#include +#include "FEATURE/options" +#include "FEATURE/dynamic" + +/* + * Table of built-in aliases for interactive shells. + */ + +const struct shtable2 shtab_aliases[] = +{ + "history", NV_NOFREE, "hist -l", + "r", NV_NOFREE, "hist -s", + "", 0, (char*)0 +}; diff --git a/src/cmd/ksh93/data/builtins.c b/src/cmd/ksh93/data/builtins.c index f203b24fc1f7..291f533f756b 100644 --- a/src/cmd/ksh93/data/builtins.c +++ b/src/cmd/ksh93/data/builtins.c @@ -90,8 +90,6 @@ const struct shtable3 shtab_builtins[] = "exit", NV_BLTIN|BLT_ENV|BLT_SPC, bltin(return), "fc", NV_BLTIN|BLT_ENV|BLT_EXIT, bltin(hist), "hist", NV_BLTIN|BLT_ENV|BLT_EXIT, bltin(hist), - "history", NV_BLTIN|BLT_ENV|BLT_EXIT, bltin(hist), - "r", NV_BLTIN|BLT_ENV|BLT_EXIT, bltin(hist), "readonly", NV_BLTIN|BLT_ENV|BLT_SPC|BLT_DCL,bltin(readonly), "shift", NV_BLTIN|BLT_ENV|BLT_SPC, bltin(shift), "trap", NV_BLTIN|BLT_ENV|BLT_SPC, bltin(trap), @@ -925,15 +923,11 @@ const char sh_opthash[] = ; const char sh_opthist[] = -"[-1cn?@(#)$Id: hist (AT&T Research/ksh93) 2020-07-16 $\n]" +"[-1cn?@(#)$Id: hist (AT&T Research) 2000-04-02 $\n]" USAGE_LICENSE -"[+NAME?fc, hist, history, r - process command history list]" -"[+DESCRIPTION?\bhist\b lists, edits, or re-executes commands " +"[+NAME?\f?\f - process command history list]" +"[+DESCRIPTION?\b\f?\f\b lists, edits, or re-executes, commands " "previously entered into the current shell environment.]" -"[+?The following command equivalents exist: " - "\bfc\b is \bhist\b; " - "\bhistory\b is \bhist -l\b (list history); " - "and \br\b is \bhist -s\b (reexecute command).]" "[+?The command history list references commands by number. The first number " "in the list is selected arbitrarily. The relationship of a number " "to its command does not change during a login session. When the " @@ -941,11 +935,11 @@ USAGE_LICENSE "maintains the ordering.]" "[+?When commands are edited (when the \b-l\b option is not specified), the " "resulting lines will be entered at the end of the history list and " - "then reexecuted by the current shell. The \bhist\b command that " + "then reexecuted by the current shell. The \b\f?\f\b command that " "caused the editing will not be entered into the history list. If the " "editor returns a non-zero exit status, this will suppress the " "entry into the history list and the command reexecution. Command " - "line variable assignments and redirections affect both the \bhist\b " + "line variable assignments and redirections affect both the \f?\f " "command and the commands that are reexecuted.]" "[+?\afirst\a and \alast\a define the range of commands. \afirst\a and " "\alast\a can be one of the following:]{" diff --git a/src/cmd/ksh93/include/shtable.h b/src/cmd/ksh93/include/shtable.h index a46ee4488fc7..91030a9002aa 100644 --- a/src/cmd/ksh93/include/shtable.h +++ b/src/cmd/ksh93/include/shtable.h @@ -55,10 +55,12 @@ extern const Shtable_t shtab_testops[]; extern const Shtable_t shtab_options[]; extern const Shtable_t shtab_attributes[]; extern const struct shtable2 shtab_variables[]; +extern const struct shtable2 shtab_aliases[]; extern const struct shtable2 shtab_signals[]; extern const struct shtable3 shtab_builtins[]; extern const Shtable_t shtab_reserved[]; extern const Shtable_t *sh_locate(const char*, const Shtable_t*, int); extern int sh_lookopt(const char*, int*); +extern Dt_t *sh_inittree(Shell_t*, const struct shtable2*); #endif /* SH_TABLE_H */ diff --git a/src/cmd/ksh93/sh.1 b/src/cmd/ksh93/sh.1 index 9203a7000e5d..1cc3e4a62008 100644 --- a/src/cmd/ksh93/sh.1 +++ b/src/cmd/ksh93/sh.1 @@ -782,6 +782,20 @@ the .B alias definition command has to be executed before the command which references the alias is read. +.PP +The following aliases are automatically preset +when the shell is invoked as an interactive shell, +unless invoked in POSIX compliance mode +(see +.I Invocation\^ +below). +Preset aliases can be unset or redefined. +.RS 20 +.PD 0 +.TP +.B "history=\(fmhist \-l\(fm" +.TP +.B "r=\(fmhist \-s\(fm" .PD .RE .SS Tilde Substitution. @@ -4370,9 +4384,9 @@ to re-execute the command. In this case a substitution parameter of the form \f2old\fP\f3=\fP\f2new\fP can be used to modify the command before execution. -For example, with the builtin +For example, with the preset alias .BR r , -which is functionally equivalent to +which is aliased to .BR "\(fmhist \-s\(fm" , typing `\f3r bad=good c\fP' @@ -6239,11 +6253,6 @@ to start .I num commands back. .TP -\f3history\fP \*(OK \f3\-N\fP \f2num\^\fP \*(CK \*(OK \f3\-nr\^\fP \*(CK \*(OK \f2first\^\fP \*(OK \f2last\^\fP \*(CK \*(CK -Lists commands in the history file. -The same as -.BR hist\ \-l . -.TP \(dd \f3integer\fP \f2vname\fP\*(OK\f3=\fP\f2value\^\fP\*(CK .\|.\|. Declares each \f2vname\fP to be a long integer number. The same as @@ -6659,11 +6668,6 @@ or on the command line determines which method is used. .TP -\f3r\fP \*(OK \f2old\fP\f3\=\fP\f2new\^\fP \*(CK \*(OK \f2command\^\fP \*(CK -Reexecutes a command in the history file. -The same as -.BR hist\ \-s . -.TP \f3read\fP \*(OK \f3\-ACSprsv\^\fP \*(CK \*(OK \f3\-d\fP \f2delim \^\fP\*(CK \*(OK \f3\-n\fP \f2n \^\fP\*(CK \*(OK \*(OK \f3\-N\fP \f2n \^\fP\*(CK \*(OK \f3\-t\fP \f2timeout \^\fP\*(CK \*(OK \f3\-u\fP \f2unit \^\fP\*(CK \*(OK \f2vname\f3?\f2prompt\^\f1 \*(CK \*(OK \f2vname\^\fP .\|.\|. \*(CK The shell input mechanism. One line is read and @@ -7059,6 +7063,7 @@ disables passing exported variables' attributes (such as integer or readonly) to causes file descriptors > 2 to be left open when invoking another program, makes the \fB<>\fR redirection operator default to standard input, causes the \fBcommand\fR utility to disable declaration command properties of any declaration commands it invokes, +skips the initialization of preset aliases upon invoking an interactive shell, disables a hack that makes \fBtest -t\fR (\fB[ -t ]\fR) equivalent to \fBtest -t 1\fR (\fB[ -t 1 ]\fR), enables octal numbers in \fBlet\fR shell arithmetic (see \fBletoctal\fR), and disables the \fB&>\fR redirection shorthand. diff --git a/src/cmd/ksh93/sh/init.c b/src/cmd/ksh93/sh/init.c index ac35b42ccd81..639baf017c7b 100644 --- a/src/cmd/ksh93/sh/init.c +++ b/src/cmd/ksh93/sh/init.c @@ -201,7 +201,6 @@ static int lctype; static int nbltins; static void env_init(Shell_t*,int); static Init_t *nv_init(Shell_t*); -static Dt_t *inittree(Shell_t*,const struct shtable2*); static int shlvl; #ifdef _WINIX @@ -1709,7 +1708,7 @@ static Init_t *nv_init(Shell_t *shp) shp->nvfun.last = (char*)shp; shp->nvfun.nofree = 1; ip->sh = shp; - shp->var_base = shp->var_tree = inittree(shp,shtab_variables); + shp->var_base = shp->var_tree = sh_inittree(shp,shtab_variables); SHLVL->nvalue.ip = &shlvl; ip->IFS_init.hdr.disc = &IFS_disc; ip->PATH_init.disc = &RESTRICTED_disc; @@ -1800,7 +1799,7 @@ static Init_t *nv_init(Shell_t *shp) /* set up the seconds clock */ shp->alias_tree = dtopen(&_Nvdisc,Dtoset); shp->track_tree = dtopen(&_Nvdisc,Dtset); - shp->bltin_tree = inittree(shp,(const struct shtable2*)shtab_builtins); + shp->bltin_tree = sh_inittree(shp,(const struct shtable2*)shtab_builtins); shp->fun_tree = dtopen(&_Nvdisc,Dtoset); dtview(shp->fun_tree,shp->bltin_tree); nv_mount(DOTSHNOD, "type", shp->typedict=dtopen(&_Nvdisc,Dtoset)); @@ -1823,7 +1822,7 @@ static Init_t *nv_init(Shell_t *shp) * initialize name-value pairs */ -static Dt_t *inittree(Shell_t *shp,const struct shtable2 *name_vals) +Dt_t *sh_inittree(Shell_t *shp,const struct shtable2 *name_vals) { register Namval_t *np; register const struct shtable2 *tp; diff --git a/src/cmd/ksh93/sh/main.c b/src/cmd/ksh93/sh/main.c index 8078da34f547..8b7782573f94 100644 --- a/src/cmd/ksh93/sh/main.c +++ b/src/cmd/ksh93/sh/main.c @@ -175,6 +175,12 @@ int sh_main(int ac, char *av[], Shinit_f userinit) { sh_onoption(SH_BGNICE); sh_onoption(SH_RC); + if(!sh_isoption(SH_POSIX)) + { + /* preset aliases for interactive non-POSIX ksh */ + dtclose(shp->alias_tree); + shp->alias_tree = sh_inittree(shp,shtab_aliases); + } } #if SHOPT_REMOTE /* diff --git a/src/cmd/ksh93/tests/alias.sh b/src/cmd/ksh93/tests/alias.sh index afc5c010b62e..be0099f38b9f 100755 --- a/src/cmd/ksh93/tests/alias.sh +++ b/src/cmd/ksh93/tests/alias.sh @@ -109,5 +109,9 @@ alias foo=bar unalias foo unalias foo && err_exit 'unalias should return non-zero when a previously set alias is unaliased twice' +# Removing a preset alias should work without an error from free(3) +err=$(set +x; { "$SHELL" -i -c 'unalias history'; } 2>&1) && [[ -z $err ]] \ +|| err_exit "removing a preset alias does not work (got $(printf %q "$err"))" + # ====== exit $((Errors<125?Errors:125))