Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/dev' into faster-spawnveg
Browse files Browse the repository at this point in the history
  • Loading branch information
JohnoKing committed Feb 23, 2024
2 parents ad010af + 6b62462 commit 1633d53
Show file tree
Hide file tree
Showing 14 changed files with 256 additions and 41 deletions.
10 changes: 10 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,16 @@ Uppercase BUG_* IDs are shell bug IDs as used by the Modernish shell library.
- Fixed a crash that occurred when starting ksh with no TERM variable in the
environment (e.g., in single user mode on NetBSD and DragonFlyBSD).

- Fixed a regression of 'return' within traps, reintroduced on 2023-12-25
after being fixed on 2020-09-09. The regression caused a 'return' or
'exit' with no arguments to assume the before-trap exit status instead of
that of the last-run command. This broke the shipped 'autocd' function.

- Fixed some integer overflows that could occur when using TMOUT.

- Fixed a crash on Solaris and illumos when cancelling a here-document
with ^C or ^D in an interactive shell.

2024-02-17:

- Fixed a crash that could occur when using 'typeset -T' typed variables
Expand Down
13 changes: 4 additions & 9 deletions bin/package
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ command=${0##*/}
case $(getopts '[-][123:xyz]' opt --xyz 2>/dev/null; echo 0$opt) in
0123) USAGE=$'
[-?
@(#)$Id: '$command$' (ksh 93u+m) 2024-02-17 $
@(#)$Id: '$command$' (ksh 93u+m) 2024-02-22 $
]
[-author?Glenn Fowler <gsf@research.att.com>]
[-author?Contributors to https://github.com/ksh93/ksh]
Expand Down Expand Up @@ -579,7 +579,7 @@ SEE ALSO
pkgadd(1), pkgmk(1), rpm(1), sh(1), tar(1), optget(3)

IMPLEMENTATION
version package (ksh 93u+m) 2024-02-17
version package (ksh 93u+m) 2024-02-22
author Glenn Fowler <gsf@research.att.com>
author Contributors to https://github.com/ksh93/ksh
copyright (c) 1994-2012 AT&T Intellectual Property
Expand Down Expand Up @@ -2138,13 +2138,7 @@ case $x in

# tame the environment

case $action in
use) ;;
*) ENV=
ERROR_OPTIONS=
export ENV ERROR_OPTIONS
;;
esac
unset ERROR_OPTIONS ENV

# finalize the views

Expand Down Expand Up @@ -3320,6 +3314,7 @@ use) # finalize the environment
if test "$KEEP_SHELL" -lt 2 && executable "$INSTALLROOT/bin/ksh"
then SHELL=$INSTALLROOT/bin/ksh
fi
export ENV=$INSTALLROOT/etc/kshrc
x=:..
for d in $(set +o noglob; cd $PACKAGEROOT; ls src/*/Mamfile 2>/dev/null | sed 's,/[^/]*$,,' | sort -u)
do x=$x:$INSTALLROOT/$d
Expand Down
6 changes: 5 additions & 1 deletion src/cmd/ksh93/Mamfile
Original file line number Diff line number Diff line change
Expand Up @@ -1229,7 +1229,7 @@ make install virtual
note *

prev libshell.a
loop DIR bin include/ast lib/lib man/man1 man/man3 fun
loop DIR bin include/ast lib/lib man/man1 man/man3 fun etc
make ${INSTALLROOT}/${DIR}
exec - mkdir -p ${@}
done
Expand Down Expand Up @@ -1272,6 +1272,10 @@ make install virtual
exec - cp -f ${<} ${@} && chmod ugo+x ${@}
done
done
make ${INSTALLROOT}/etc/kshrc
prev kshrc.sh
exec - cp -f ${<} ${@}
done
make announce_build_done notrace virtual
prev ksh
exec - ${<} -c 'print \# KornShell $KSH_VERSION '
Expand Down
7 changes: 5 additions & 2 deletions src/cmd/ksh93/bltins/cflow.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,11 @@ int b_return(int n, char *argv[],Shbltin_t *context)
int r;
intmax_t l = strtoll(*argv, NULL, 10);
if(do_exit)
{
n = (int)(l & SH_EXITMASK); /* exit: apply bitmask before conversion to avoid undefined int overflow */
if (sh.intrap)
sh.intrap_exit_n = 1;
}
else if(r = (int)l, l != (intmax_t)r) /* return: convert to int and check for overflow (should be safe enough) */
{
errormsg(SH_DICT,ERROR_warn(0),"%s: out of range",*argv);
Expand All @@ -79,8 +83,7 @@ int b_return(int n, char *argv[],Shbltin_t *context)
}
else
{
/* no argument: pass down $? (but in a trap action, pass down the pre-trap $?) */
n = sh.intrap ? sh.oldexit : sh.savexit;
n = sh.savexit; /* no argument: pass down $? */
if(do_exit)
n &= SH_EXITMASK;
}
Expand Down
18 changes: 9 additions & 9 deletions src/cmd/ksh93/bltins/read.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,13 @@

struct read_save
{
char **argv;
char *prompt;
int fd;
int plen;
int flags;
ssize_t len;
long timeout;
char **argv;
char *prompt;
int fd;
int plen;
int flags;
ssize_t len;
Sflong_t timeout;
};

int b_read(int argc,char *argv[], Shbltin_t *context)
Expand All @@ -66,7 +66,7 @@ int b_read(int argc,char *argv[], Shbltin_t *context)
const char *msg = e_file+4;
int r, flags=0, fd=0;
ssize_t len=0;
long timeout = 1000*sh.st.tmout;
Sflong_t timeout = 1000*(Sflong_t)sh.st.tmout;
int save_prompt, fixargs=context->invariant;
struct read_save *rp;
static char default_prompt[3] = {ESC,ESC};
Expand Down Expand Up @@ -212,7 +212,7 @@ static void timedout(void *handle)
* <flags> is union of -A, -r, -s, and contains delimiter if not '\n'
* <timeout> is the number of milliseconds until timeout
*/
int sh_readline(char **names, volatile int fd, int flags, ssize_t size, long timeout)
int sh_readline(char **names, volatile int fd, int flags, ssize_t size, Sflong_t timeout)
{
ssize_t c;
unsigned char *cp;
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/ksh93/include/defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ extern int sh_outtype(Sfio_t*);
extern char *sh_mactry(char*);
extern int sh_mathstd(const char*);
extern void sh_printopts(Shopt_t,int,Shopt_t*);
extern int sh_readline(char**,volatile int,int,ssize_t,long);
extern int sh_readline(char**,volatile int,int,ssize_t,Sflong_t);
extern Sfio_t *sh_sfeval(char*[]);
extern void sh_setmatch(const char*,int,int,int[],int);
extern void sh_scope(struct argnod*, int);
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/ksh93/include/shell.h
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,6 @@ struct Shell_s
char *comdiv; /* points to sh -c argument */
char *prefix; /* prefix for compound assignment */
sigjmp_buf *jmplist; /* longjmp return stack */
int oldexit; /* saves pre-trap exit status for 'exit' default in trap actions */
pid_t bckpid; /* background process id */
pid_t cpid;
pid_t spid; /* subshell process id */
Expand All @@ -312,6 +311,7 @@ struct Shell_s
int savesig;
unsigned char *sigflag; /* pointer to signal states */
char intrap; /* set while executing a trap action */
char intrap_exit_n; /* set if 'exit n' within trap */
uint32_t srand_upper_bound;
char forked;
char binscript;
Expand Down
184 changes: 184 additions & 0 deletions src/cmd/ksh93/kshrc.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
########################################################################
# #
# This file is part of the ksh 93u+m package #
# Copyright (c) 2022-2024 Contributors to ksh 93u+m #
# and is licensed under the #
# Eclipse Public License, Version 2.0 #
# #
# A copy of the License is available at #
# https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html #
# (with md5 checksum 84283fa8859daf213bdda5a9f8d1be1d) #
# #
# Martijn Dekker <martijn@inlv.org> #
# Johnothan King <johnothanking@protonmail.com> #
# #
########################################################################

# A nice default .kshrc for 'bin/package use'
# Feel free to adapt and use as your own ~/.kshrc
# NOTE: much of this requires ksh 93u+m

# create a namespace for global kshrc stuff
typeset .rc

.rc.me=${0##*/} # a $0 without dir that won't change in functions
.rc.uid=${ id -u; }
.rc.uname=${ id -un; }
.rc.host=${ uname -n; }
.rc.host=${.rc.host%%.*} # remove domain
.rc.tty=${ tty; }
.rc.tty=${.rc.tty##*/} # remove dir

# ANSI foreground colours
.rc.clr=(
[magenta]=$'\E[35m'
[blue]=$'\E[34m'
[cyan]=$'\E[36m'
[red]=$'\E[31m'
)

# Formatting codes
.rc.fmt=(
[ansiprefix]=$'\E['
[reset]=$'\E[0m'
[underline]=$'\E[4m'
[bold]=$'\E[1m'
)

# extend tilde expansion functionality:
# define some nice default shortcuts and add some warnings
function .sh.tilde.get
{
case ${.sh.tilde} in
'~tmp') .sh.value=${XDG_RUNTIME_DIR:-${TMPDIR:-/tmp}} ;;
'~doc') .sh.value=~/Documents ;;
'~ast') [[ -v INSTALLROOT ]] && .sh.value=$INSTALLROOT ;;
'~today')
printf -v .sh.value "%s/Documents/Projects/%(%Y-%m-%d)T" "$HOME" "now"
if [[ ! -d ${.sh.value} && ! -L ${.sh.value} ]]; then
printf '%s: creating directory %q\n' "${.rc.me}" "${.sh.value}" >&2
mkdir -p "${.sh.value}"
fi ;;
\~*[![:alnum:]._-]*)
printf '%s: warning: %s: bad username\n' "${.rc.me}" "${.sh.tilde#\~}" >&2 ;;
\~*) eval ".sh.value=${.sh.tilde}" # perform default expansion
if [[ ${.sh.value} == "${.sh.tilde}" ]]; then
printf '%s: warning: %s: unknown username\n' "${.rc.me}" "${.sh.tilde#\~}" >&2
fi ;;
esac
}

# RELPWD expands to relative current working directory with ~ support
# and configurable number of pathname components kept
function RELPWD.get
{
typeset del ellip=$'\u2026' v=$PWD keep=${RELPWD.keep}
((${#ellip}==1)) || ellip='...'
[[ ($v == "$HOME" || $v == "$HOME"/*) && $HOME != / ]] && v=\~${v#"$HOME"}
if [[ -n $keep ]]
then del=${v%/$keep}/
[[ $v == /*/$keep ]] && v=$ellip/${v#"$del"}
[[ $v == \~/*/$keep ]] && v=\~/$ellip/${v#"$del"}
fi
.sh.value=$v
}
# convert <=1 to *, 2 to */*, 3 to */*/*, etc.
function RELPWD.keep.set
{
typeset -si i n
let "(n=${.sh.value}) ? 1 : 1" 2>/dev/null || n=2
((n>64)) && n=64 # sanity check
((n<1)) && .sh.value='' && return
.sh.value='*'
for ((i=2; i <= n; i++))
do .sh.value+='/*'
done
}
# change this anytime to set number of pathname components kept
# set to 0 to keep all (but still change your home directory to ~)
RELPWD.keep=3

# get the current git branch
function GITBRANCH.get
{
command -v git >/dev/null || return
.sh.value=${ git branch --show-current 2>/dev/null; } && return
# fallback for old git versions without --show-current:
.sh.value=${ git branch 2>/dev/null; }
case $'\n'${.sh.value} in
*$'\n* '*)
.sh.value=$'\n'${.sh.value}
.sh.value=${.sh.value#*$'\n* '}
.sh.value=${.sh.value%%$'\n'*}
;;
*) .sh.value=''
;;
esac
}

# the regular (PS1) and line continuation (PS2) prompts

typeset -sui .rc.ps2_lineno=0
case ${.rc.uid} in
0) .rc.clr1=${.rc.clr[magenta]} .rc.clr2=${.rc.clr[red]} .rc.char='#' ;;
*) .rc.clr1=${.rc.clr[blue]} .rc.clr2=${.rc.clr[cyan]} .rc.char='$' ;;
esac

# use single quotes to avoid expanding variables now, because PS1 is special:
# it expands variables in its value even without a discipline function.
# Also, '!' expands to the history file number (see 'man fc').
PS1='${.rc.fmt[ansiprefix]}$((${?}?31:32))m$?${.rc.fmt[reset]}<${.rc.clr1}!${.rc.fmt[reset]}'
PS1+=':${.rc.clr2}${RELPWD}${GITBRANCH:+${.rc.clr1}[${GITBRANCH}]}${.rc.fmt[reset]} ${.rc.char} '

function PS1.get
{
# reset PS2 counter whenever PS1 is shown
.rc.ps2_lineno=0
}

# PS2 (like normal variables) does not expand anything by itself,
# but we can use a discipline function to make it act dynamically
function PS2.get
{
typeset clr1 clr2 char
case ${.rc.uid} in
0) clr1=${.rc.clr[magenta]} clr2=${.rc.clr[red]} ;;
*) clr1=${.rc.clr[blue]} clr2=${.rc.clr[cyan]} ;;
esac
char=$'\u22d7' # greater-than with dot (UTF-8)
((${#char}==1)) || char='>'
((.rc.ps2_lineno++))
printf -v .sh.value ' %s%s%02d%s%s %c%s ' \
"$clr1" \
"${.rc.fmt[underline]}" \
.rc.ps2_lineno \
"${.rc.fmt[reset]}" \
"$clr2" \
"$char" \
"${.rc.fmt[reset]}"
}

# stuff for when this is run from 'bin/package use'
if [[ -v INSTALLROOT ]]
then
# make shipped functions available
case $FPATH: in
"$INSTALLROOT"/fun:*)
;;
*) FPATH=$INSTALLROOT/fun${FPATH:+:$FPATH} ;;
esac
export FPATH
autoload autocd cd dirs man mcd popd pushd
# do not intefere with the regular ksh history
[[ -d $INSTALLROOT/var ]] || mkdir -p "$INSTALLROOT/var"
HISTFILE=$INSTALLROOT/var/sh_history_${.rc.tty}

# Print welcome message
set -- ${.sh.version}
print -r "${.rc.fmt[bold]}Welcome to ksh ${.rc.clr[red]}$3 ${.rc.clr[blue]}$4${.rc.fmt[reset]} on ${.rc.fmt[bold]}${.rc.host} (${.rc.tty})${.rc.fmt[reset]}"
set --
print -r -- "- Have a look at ${.rc.fmt[bold]}~ast/etc/kshrc${.rc.fmt[reset]} to see all the cool stuff activated here"
print -r -- "- Type '${.rc.fmt[bold]}builtin${.rc.fmt[reset]}' for a list of built-in commands (with and without path)"
print -r -- "- Get help: use '${.rc.fmt[bold]}man${.rc.fmt[reset]} ${.rc.fmt[underline]}commandname${.rc.fmt[reset]}' for everything, even built-in commands"
print -r -- "- Autoloadable functions have been activated. Check them out in ${.rc.fmt[bold]}~ast/fun${.rc.fmt[reset]}"
fi
11 changes: 4 additions & 7 deletions src/cmd/ksh93/sh/fault.c
Original file line number Diff line number Diff line change
Expand Up @@ -528,11 +528,7 @@ int sh_trap(const char *trap, int mode)
if(jmpval==SH_JMPSCRIPT)
indone=0;
else
{
if(jmpval==SH_JMPEXIT)
savxit = sh.exitval;
jmpval=SH_JMPTRAP;
}
}
sh_popcontext(&buff);
/* re-allow last-command exec optimisation unless the command we executed set a trap */
Expand All @@ -541,8 +537,10 @@ int sh_trap(const char *trap, int mode)
sh.intrap--;
sfsync(sh.outpool);
savxit_return = sh.exitval;
if(jmpval!=SH_JMPEXIT && jmpval!=SH_JMPFUN)
sh.exitval=savxit;
if(sh.intrap_exit_n)
sh.intrap_exit_n = 0;
else
sh.exitval = savxit;
stkset(sh.stk,savptr,staktop);
fcrestore(&savefc);
if(was_history)
Expand Down Expand Up @@ -666,7 +664,6 @@ noreturn void sh_done(int sig)
if(t=sh.st.trapcom[0])
{
sh.st.trapcom[0]=0; /* should free but not long */
sh.oldexit = savxit;
sh_trap(t,0);
savxit = sh.exitval;
}
Expand Down
Loading

0 comments on commit 1633d53

Please sign in to comment.