Skip to content

Commit

Permalink
Make the 'history' and 'r' commands builtins (#76)
Browse files Browse the repository at this point in the history
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 <martijn@inlv.org>
  • Loading branch information
JohnoKing and McDutchie committed Jul 16, 2020
1 parent 17f81eb commit 03224ae
Show file tree
Hide file tree
Showing 13 changed files with 47 additions and 100 deletions.
8 changes: 5 additions & 3 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,18 @@ 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'
default aliases have been converted into regular built-in commands, so
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).
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/ksh93/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
12 changes: 1 addition & 11 deletions src/cmd/ksh93/Mamfile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
9 changes: 8 additions & 1 deletion src/cmd/ksh93/bltins/hist.c
Original file line number Diff line number Diff line change
Expand Up @@ -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') /* <r> */
edit = "-";
else if(argv[0][0] == 'h' && argv[0][4] == 'o') /* hist<o>ry (argv[0][4] is zero when called as 'hist') */
lflag = 1;

hp = shp->gd->hist_ptr;
while((flag = optget(argv,sh_opthist))) switch(flag)
{
Expand All @@ -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++;
Expand Down
7 changes: 1 addition & 6 deletions src/cmd/ksh93/bltins/typeset.c
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
45 changes: 0 additions & 45 deletions src/cmd/ksh93/data/aliases.c

This file was deleted.

16 changes: 11 additions & 5 deletions src/cmd/ksh93/data/builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -953,23 +955,27 @@ 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 "
"number reaches 32767 the number wraps around to 1 but "
"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:]{"
Expand Down
3 changes: 0 additions & 3 deletions src/cmd/ksh93/include/shtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
2 changes: 1 addition & 1 deletion src/cmd/ksh93/include/version.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@
* David Korn <dgk@research.att.com> *
* *
***********************************************************************/
#define SH_RELEASE "93u+m 2020-07-15"
#define SH_RELEASE "93u+m 2020-07-16"
27 changes: 13 additions & 14 deletions src/cmd/ksh93/sh.1
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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'
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
11 changes: 6 additions & 5 deletions src/cmd/ksh93/sh/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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));
Expand All @@ -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;
Expand Down
2 changes: 0 additions & 2 deletions src/cmd/ksh93/sh/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 0 additions & 3 deletions src/cmd/ksh93/tests/alias.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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))

0 comments on commit 03224ae

Please sign in to comment.