From 03224ae3af95e90a99b7c6e08af2fa26407c8d1b Mon Sep 17 00:00:00 2001 From: Johnothan King Date: Thu, 16 Jul 2020 10:56:49 -0700 Subject: [PATCH] Make the 'history' and 'r' commands builtins (#76) With this change no more preset aliases exist, so the preset alias tables can be safely removed. All ksh commands can now be used without 'unalias -a' removing them, even in interactive shells. Additionally, the history and r commands are no longer limited to being used in interactive shells. src/cmd/ksh93/bltins/hist.c: - Implement the history and r commands as builtins. Also guarantee lflag is set to one by avoiding 'lflag++'. src/cmd/ksh93/Makefile, src/cmd/ksh93/Mamfile, src/cmd/ksh93/sh/main.c, src/cmd/ksh93/sh/init.c, src/cmd/ksh93/data/aliases.c: - Remove the table of predefined aliases because the last few have been removed. During init the alias tree is now initialized the same way as the function tree. src/cmd/ksh93/bltins/typeset.c: - Remove the bugfix for unsetting predefined aliases because it is now a no-op. Aliases are no longer able to have the NV_NOFREE attribute. src/cmd/ksh93/tests/alias.sh: - Remove the regression test for unsetting predefined aliases since those no longer exist. src/cmd/ksh93/data/builtins.c: - Update sh_opthist[] for 'hist --man', etc. src/cmd/ksh93/sh.1: - Remove the list of preset aliases since those no longer exist. - Document history and r as builtins instead of preset aliases. Co-authored-by: Martijn Dekker --- NEWS | 8 +++--- src/cmd/ksh93/Makefile | 2 +- src/cmd/ksh93/Mamfile | 12 +-------- src/cmd/ksh93/bltins/hist.c | 9 ++++++- src/cmd/ksh93/bltins/typeset.c | 7 +---- src/cmd/ksh93/data/aliases.c | 45 --------------------------------- src/cmd/ksh93/data/builtins.c | 16 ++++++++---- src/cmd/ksh93/include/shtable.h | 3 --- src/cmd/ksh93/include/version.h | 2 +- src/cmd/ksh93/sh.1 | 27 ++++++++++---------- src/cmd/ksh93/sh/init.c | 11 ++++---- src/cmd/ksh93/sh/main.c | 2 -- src/cmd/ksh93/tests/alias.sh | 3 --- 13 files changed, 47 insertions(+), 100 deletions(-) delete mode 100644 src/cmd/ksh93/data/aliases.c diff --git a/NEWS b/NEWS index 29354db92301..ee3f19fa69c8 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,11 @@ For full details, see the git log at: https://github.com/ksh93/ksh Any uppercase BUG_* names are modernish shell bug IDs. +2020-07-16: + +- The 'history' and 'r' default aliases have been made regular built-ins, + leaving zero default aliases. + 2020-07-15: - The 'autoload', 'compound', 'float', 'functions', 'integer' and 'nameref' @@ -10,9 +15,6 @@ Any uppercase BUG_* names are modernish shell bug IDs. that 'unalias -a' does not remove them. Shell functions can now use these names, which improves compatibility with POSIX shell scripts. -- The two default aliases that are left, 'history' and 'r', are now only - loaded on interactive shells, leaving zero default aliases for scripts. - - The End key escape sequence '^[[F' is now handled in the emacs and vi editing modes. The End key moves the cursor to the end of the line (in contrast to the Home key doing the opposite). diff --git a/src/cmd/ksh93/Makefile b/src/cmd/ksh93/Makefile index be8afc4e3416..bc387d8c11b4 100644 --- a/src/cmd/ksh93/Makefile +++ b/src/cmd/ksh93/Makefile @@ -156,7 +156,7 @@ end $(SH) :: sh.1 pmain.c $(LIBS_req) DATAFILES = limits.c msg.c strdata.c testops.c keywords.c options.c \ - signals.c aliases.c builtins.c variables.c lexstates.c + signals.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 8dbf10306980..fa5246a82a88 100644 --- a/src/cmd/ksh93/Mamfile +++ b/src/cmd/ksh93/Mamfile @@ -1238,16 +1238,6 @@ 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_COSHELL -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 @@ -1329,7 +1319,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 -DSHOPT_COSHELL -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 env.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 - ${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 env.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 - (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 7a2ba44403f7..26a05a422223 100644 --- a/src/cmd/ksh93/bltins/hist.c +++ b/src/cmd/ksh93/bltins/hist.c @@ -58,6 +58,13 @@ 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) { @@ -68,7 +75,7 @@ int b_hist(int argc,char *argv[], Shbltin_t *context) nflag++; break; case 'l': - lflag++; + lflag = 1; break; case 'r': rflag++; diff --git a/src/cmd/ksh93/bltins/typeset.c b/src/cmd/ksh93/bltins/typeset.c index 3fe074f10249..906d0a772a0f 100644 --- a/src/cmd/ksh93/bltins/typeset.c +++ b/src/cmd/ksh93/bltins/typeset.c @@ -1328,12 +1328,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) - { - if(nv_isattr(np, NV_NOFREE)) - nv_delete(np,troot,NV_NOFREE); /* The alias is in read-only memory (shtab_aliases) */ - else - nv_delete(np,troot,0); - } + nv_delete(np,troot,0); #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 deleted file mode 100644 index 1b9bd9779154..000000000000 --- a/src/cmd/ksh93/data/aliases.c +++ /dev/null @@ -1,45 +0,0 @@ -/*********************************************************************** -* * -* 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 -}; - -/* - * Empty table of built-in aliases for non-interactive shells. - */ - -const struct shtable2 shtab_noaliases[] = -{ - "", 0, (char*)0 -}; - diff --git a/src/cmd/ksh93/data/builtins.c b/src/cmd/ksh93/data/builtins.c index 8d4e9ea5419b..86a624c01a61 100644 --- a/src/cmd/ksh93/data/builtins.c +++ b/src/cmd/ksh93/data/builtins.c @@ -94,6 +94,8 @@ 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), @@ -953,11 +955,15 @@ const char sh_opthash[] = ; const char sh_opthist[] = -"[-1cn?@(#)$Id: hist (AT&T Research) 2000-04-02 $\n]" +"[-1cn?@(#)$Id: hist (AT&T Research/ksh93) 2020-07-16 $\n]" USAGE_LICENSE -"[+NAME?\f?\f - process command history list]" -"[+DESCRIPTION?\b\f?\f\b lists, edits, or re-executes, commands " +"[+NAME?fc, hist, history, r - process command history list]" +"[+DESCRIPTION?\bhist\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 " @@ -965,11 +971,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 \b\f?\f\b command that " + "then reexecuted by the current shell. The \bhist\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 \f?\f " + "line variable assignments and redirections affect both the \bhist\b " "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 4575f2e9c82b..a46ee4488fc7 100644 --- a/src/cmd/ksh93/include/shtable.h +++ b/src/cmd/ksh93/include/shtable.h @@ -55,13 +55,10 @@ 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_noaliases[]; 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/include/version.h b/src/cmd/ksh93/include/version.h index 3b21968c7d20..0c64b2f73438 100644 --- a/src/cmd/ksh93/include/version.h +++ b/src/cmd/ksh93/include/version.h @@ -17,4 +17,4 @@ * David Korn * * * ***********************************************************************/ -#define SH_RELEASE "93u+m 2020-07-15" +#define SH_RELEASE "93u+m 2020-07-16" diff --git a/src/cmd/ksh93/sh.1 b/src/cmd/ksh93/sh.1 index 000aad38e39d..18ea1462f63a 100644 --- a/src/cmd/ksh93/sh.1 +++ b/src/cmd/ksh93/sh.1 @@ -777,20 +777,9 @@ not while they are executed. Therefore, for an alias to take effect, the -.B -alias +.B alias definition command has to be executed before the command which references the alias is read. -.PP -The following aliases -are compiled into the shell -but 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. @@ -4367,9 +4356,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 preset alias +For example, with the builtin .BR r , -which is aliased to +which is functionally equivalent to .BR "\(fmhist \-s\(fm" , typing `\f3r bad=good c\fP' @@ -6211,6 +6200,11 @@ after the optional substitution \f2old\^\fP\f3=\fP\f2new\^\fP is performed. .TP +\f3history\fP \*(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 @@ -6624,6 +6618,11 @@ 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 diff --git a/src/cmd/ksh93/sh/init.c b/src/cmd/ksh93/sh/init.c index 1e87fd0fb758..310a2ca12d37 100644 --- a/src/cmd/ksh93/sh/init.c +++ b/src/cmd/ksh93/sh/init.c @@ -217,6 +217,7 @@ static int lctype; static int nbltins; static void env_init(Shell_t*); static Init_t *nv_init(Shell_t*); +static Dt_t *inittree(Shell_t*,const struct shtable2*); static int shlvl; #ifdef _WINIX @@ -1560,7 +1561,7 @@ int sh_reinit(char *argv[]) nv_delete(np,dp,NV_NOFREE); } dtclose(shp->alias_tree); - shp->alias_tree = sh_inittree(shp,shtab_noaliases); + shp->alias_tree = dtopen(&_Nvdisc,Dtoset); shp->last_root = shp->var_tree; shp->inuse_bits = 0; if(shp->userinit) @@ -1759,7 +1760,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 = sh_inittree(shp,shtab_variables); + shp->var_base = shp->var_tree = inittree(shp,shtab_variables); SHLVL->nvalue.ip = &shlvl; ip->IFS_init.hdr.disc = &IFS_disc; ip->PATH_init.disc = &RESTRICTED_disc; @@ -1852,9 +1853,9 @@ static Init_t *nv_init(Shell_t *shp) (MCHKNOD)->nvalue.lp = (&sh_mailchk); (OPTINDNOD)->nvalue.lp = (&shp->st.optindex); /* set up the seconds clock */ - shp->alias_tree = sh_inittree(shp,shtab_noaliases); + shp->alias_tree = dtopen(&_Nvdisc,Dtoset); shp->track_tree = dtopen(&_Nvdisc,Dtset); - shp->bltin_tree = sh_inittree(shp,(const struct shtable2*)shtab_builtins); + shp->bltin_tree = 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)); @@ -1877,7 +1878,7 @@ static Init_t *nv_init(Shell_t *shp) * initialize name-value pairs */ -Dt_t *sh_inittree(Shell_t *shp,const struct shtable2 *name_vals) +static Dt_t *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 037fccda34c6..36650f6cb974 100644 --- a/src/cmd/ksh93/sh/main.c +++ b/src/cmd/ksh93/sh/main.c @@ -176,8 +176,6 @@ int sh_main(int ac, char *av[], Shinit_f userinit) { sh_onoption(SH_BGNICE); sh_onoption(SH_RC); - free(shp->alias_tree); - shp->alias_tree = sh_inittree(shp,shtab_aliases); } if(!sh_isoption(SH_RC) && (sh_isoption(SH_BASH) && !sh_isoption(SH_POSIX) #if SHOPT_REMOTE diff --git a/src/cmd/ksh93/tests/alias.sh b/src/cmd/ksh93/tests/alias.sh index f9d1cf3cf512..a79fc847d3ae 100755 --- a/src/cmd/ksh93/tests/alias.sh +++ b/src/cmd/ksh93/tests/alias.sh @@ -109,8 +109,5 @@ alias foo=bar unalias foo unalias foo && err_exit 'unalias should return non-zero when a previously set alias is unaliased twice' -# Removing a predefined alias should work without an error from free(3) -$SHELL -i -c 'unalias history' 2> /dev/null || err_exit 'removing a predefined alias does not work' - # ====== exit $((Errors<125?Errors:125))