• protect POSIX builtins and utilities from aliases, e.g:

‣ : → \:
  ‣ alias → \alias
    ⇒ except in some internally used cases, where we use \builtin alias
  ‣ command . → \command .
• protect Korn Shell builtins from aliases and functions, e.g:
  ‣ typeset → \builtin typeset
    ⇒ also unravels the “local” alias used
  ‣ print → \builtin print
• protect internally-used things from aliases
  ‣ “let]” is not a valid function name
  ‣ “set” is POSIX so we don’t expect anyone to override it in a function
• use “command -v” instead of “whence -p” (“which”) in most
  places; thanks izabera from #ed on IRC for pointing out
  that “command -v” is POSIX – except, “whence -p” a̲l̲w̲a̲y̲s̲ looks
  for an executable and shows its full pathname; “command -v”
  also resolves to aliases, functions and builtins, so only use
  it where it makes any sense (both never output to stderr)
• make most of dot.mkshrc work in the face of such aliases
  ‣ “ulimit -c” is used; this is not POSIX, and not portable;
    maybe we should make ulimit accept-and-ignore the most
    common limits even if the OS doesn’t use them?
• update list of builtin aliases in the manpage
This commit is contained in:
tg 2015-03-08 22:54:36 +00:00
parent fcc59eee48
commit 8f53c68265
7 changed files with 277 additions and 301 deletions

View File

@ -1,8 +1,8 @@
# $MirOS: src/bin/mksh/check.pl,v 1.37 2014/08/19 07:43:32 tg Exp $
# $MirOS: src/bin/mksh/check.pl,v 1.38 2015/03/08 22:54:31 tg Exp $
# $OpenBSD: th,v 1.1 2013/12/02 20:39:44 millert Exp $
#-
# Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011,
# 2012, 2013, 2014
# 2012, 2013, 2014, 2015
# Thorsten Glaser <tg@mirbsd.org>
#
# Provided that these terms and disclaimer and all copyright notices
@ -568,7 +568,7 @@ run_test
}
push(@argv, $temps) if defined $test{'script'};
#XXX realpathise, use which/whence -p, or sth. like that
#XXX realpathise, use command -v/whence -p/which, or sth. like that
#XXX if !$program_kludge, we get by with not doing it for now tho
$new_env{'__progname'} = $argv[0];

202
check.t
View File

@ -1,4 +1,4 @@
# $MirOS: src/bin/mksh/check.t,v 1.683 2015/03/07 20:46:26 tg Exp $
# $MirOS: src/bin/mksh/check.t,v 1.684 2015/03/08 22:54:31 tg Exp $
# -*- mode: sh -*-
#-
# Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
@ -30,7 +30,7 @@
# (2013/12/02 20:39:44) http://openbsd.cs.toronto.edu/cgi-bin/cvsweb/src/regress/bin/ksh/?sortby=date
expected-stdout:
@(#)MIRBSD KSH R50 2015/03/07
@(#)MIRBSD KSH R50 2015/03/08
description:
Check version of shell.
stdin:
@ -39,7 +39,7 @@ name: KSH_VERSION
category: shell:legacy-no
---
expected-stdout:
@(#)LEGACY KSH R50 2015/03/07
@(#)LEGACY KSH R50 2015/03/08
description:
Check version of legacy shell.
stdin:
@ -7370,19 +7370,19 @@ stdin:
alias
typeset -f
expected-stdout:
autoload='typeset -fu'
functions='typeset -f'
hash='alias -t'
history='fc -l'
integer='typeset -i'
local=typeset
login='exec login'
nameref='typeset -n'
autoload='\builtin typeset -fu'
functions='\builtin typeset -f'
hash='\builtin alias -t'
history='\builtin fc -l'
integer='\builtin typeset -i'
local='\builtin typeset'
login='\exec login'
nameref='\builtin typeset -n'
nohup='nohup '
r='fc -e -'
source='PATH=$PATH:. command .'
stop='kill -STOP'
type='whence -v'
r='\builtin fc -e -'
source='PATH=$PATH:. \command .'
stop='\kill -STOP'
type='\builtin whence -v'
---
name: aliases-1-hartz4
description:
@ -7392,42 +7392,18 @@ stdin:
alias
typeset -f
expected-stdout:
autoload='typeset -fu'
functions='typeset -f'
hash='alias -t'
history='fc -l'
integer='typeset -i'
local=typeset
login='exec login'
nameref='typeset -n'
autoload='\builtin typeset -fu'
functions='\builtin typeset -f'
hash='\builtin alias -t'
history='\builtin fc -l'
integer='\builtin typeset -i'
local='\builtin typeset'
login='\exec login'
nameref='\builtin typeset -n'
nohup='nohup '
r='fc -e -'
source='PATH=$PATH:. command .'
type='whence -v'
---
name: aliases-2a
description:
Check if set -o sh disables built-in aliases (except a few)
category: disabled
arguments: !-o!sh!
stdin:
alias
typeset -f
expected-stdout:
integer='typeset -i'
local=typeset
---
name: aliases-3a
description:
Check if running as sh disables built-in aliases (except a few)
category: disabled
stdin:
cp "$__progname" sh
./sh -c 'alias; typeset -f'
rm -f sh
expected-stdout:
integer='typeset -i'
local=typeset
r='\builtin fc -e -'
source='PATH=$PATH:. \command .'
type='\builtin whence -v'
---
name: aliases-2b
description:
@ -7438,19 +7414,19 @@ stdin:
alias
typeset -f
expected-stdout:
autoload='typeset -fu'
functions='typeset -f'
hash='alias -t'
history='fc -l'
integer='typeset -i'
local=typeset
login='exec login'
nameref='typeset -n'
autoload='\builtin typeset -fu'
functions='\builtin typeset -f'
hash='\builtin alias -t'
history='\builtin fc -l'
integer='\builtin typeset -i'
local='\builtin typeset'
login='\exec login'
nameref='\builtin typeset -n'
nohup='nohup '
r='fc -e -'
source='PATH=$PATH:. command .'
stop='kill -STOP'
type='whence -v'
r='\builtin fc -e -'
source='PATH=$PATH:. \command .'
stop='\kill -STOP'
type='\builtin whence -v'
---
name: aliases-3b
description:
@ -7461,19 +7437,19 @@ stdin:
./sh -c 'alias; typeset -f'
rm -f sh
expected-stdout:
autoload='typeset -fu'
functions='typeset -f'
hash='alias -t'
history='fc -l'
integer='typeset -i'
local=typeset
login='exec login'
nameref='typeset -n'
autoload='\builtin typeset -fu'
functions='\builtin typeset -f'
hash='\builtin alias -t'
history='\builtin fc -l'
integer='\builtin typeset -i'
local='\builtin typeset'
login='\exec login'
nameref='\builtin typeset -n'
nohup='nohup '
r='fc -e -'
source='PATH=$PATH:. command .'
stop='kill -STOP'
type='whence -v'
r='\builtin fc -e -'
source='PATH=$PATH:. \command .'
stop='\kill -STOP'
type='\builtin whence -v'
---
name: aliases-2b-hartz4
description:
@ -7484,18 +7460,18 @@ stdin:
alias
typeset -f
expected-stdout:
autoload='typeset -fu'
functions='typeset -f'
hash='alias -t'
history='fc -l'
integer='typeset -i'
local=typeset
login='exec login'
nameref='typeset -n'
autoload='\builtin typeset -fu'
functions='\builtin typeset -f'
hash='\builtin alias -t'
history='\builtin fc -l'
integer='\builtin typeset -i'
local='\builtin typeset'
login='\exec login'
nameref='\builtin typeset -n'
nohup='nohup '
r='fc -e -'
source='PATH=$PATH:. command .'
type='whence -v'
r='\builtin fc -e -'
source='PATH=$PATH:. \command .'
type='\builtin whence -v'
---
name: aliases-3b-hartz4
description:
@ -7506,18 +7482,18 @@ stdin:
./sh -c 'alias; typeset -f'
rm -f sh
expected-stdout:
autoload='typeset -fu'
functions='typeset -f'
hash='alias -t'
history='fc -l'
integer='typeset -i'
local=typeset
login='exec login'
nameref='typeset -n'
autoload='\builtin typeset -fu'
functions='\builtin typeset -f'
hash='\builtin alias -t'
history='\builtin fc -l'
integer='\builtin typeset -i'
local='\builtin typeset'
login='\exec login'
nameref='\builtin typeset -n'
nohup='nohup '
r='fc -e -'
source='PATH=$PATH:. command .'
type='whence -v'
r='\builtin fc -e -'
source='PATH=$PATH:. \command .'
type='\builtin whence -v'
---
name: aliases-cmdline
description:
@ -7574,8 +7550,8 @@ stdin:
:|| local() { :; }
alias local
expected-stdout:
local=typeset
local=typeset
local='\builtin typeset'
local='\builtin typeset'
---
name: arrays-1
description:
@ -10177,7 +10153,7 @@ expected-stdout:
}
inline_TWHILE() {
i=1
while let] " i < 10 "
while \let] " i < 10 "
do
echo $i
let ++i
@ -10187,20 +10163,20 @@ expected-stdout:
i=1; while (( i < 10 )); do echo $i; let ++i; done
); }
function comsub_TWHILE {
x=$(i=1 ; while let] " i < 10 " ; do echo $i ; let ++i ; done )
x=$(i=1 ; while \let] " i < 10 " ; do echo $i ; let ++i ; done )
}
function reread_TWHILE { x=$((
i=1; while (( i < 10 )); do echo $i; let ++i; done
)|tr u x); }
function reread_TWHILE {
x=$(( i=1 ; while let] " i < 10 " ; do echo $i ; let ++i ; done ) | tr u x )
x=$(( i=1 ; while \let] " i < 10 " ; do echo $i ; let ++i ; done ) | tr u x )
}
inline_TUNTIL() {
i=10; until (( !--i )) ; do echo $i; done
}
inline_TUNTIL() {
i=10
until let] " !--i "
until \let] " !--i "
do
echo $i
done
@ -10209,13 +10185,13 @@ expected-stdout:
i=10; until (( !--i )) ; do echo $i; done
); }
function comsub_TUNTIL {
x=$(i=10 ; until let] " !--i " ; do echo $i ; done )
x=$(i=10 ; until \let] " !--i " ; do echo $i ; done )
}
function reread_TUNTIL { x=$((
i=10; until (( !--i )) ; do echo $i; done
)|tr u x); }
function reread_TUNTIL {
x=$(( i=10 ; until let] " !--i " ; do echo $i ; done ) | tr u x )
x=$(( i=10 ; until \let] " !--i " ; do echo $i ; done ) | tr u x )
}
inline_TCOPROC() {
cat * |& ls
@ -10591,7 +10567,7 @@ expected-stdout:
case x in
(x)
a+=b
set -A c+ -- d e
\set -A c+ -- d e
;;
esac
}
@ -10601,7 +10577,7 @@ expected-stdout:
esac
); }
function comsub_wdarrassign {
x=$(case x in (x) a+=b ; set -A c+ -- d e ;; esac )
x=$(case x in (x) a+=b ; \set -A c+ -- d e ;; esac )
}
function reread_wdarrassign { x=$((
case x in
@ -10609,7 +10585,7 @@ expected-stdout:
esac
)|tr u x); }
function reread_wdarrassign {
x=$(( case x in (x) a+=b ; set -A c+ -- d e ;; esac ) | tr u x )
x=$(( case x in (x) a+=b ; \set -A c+ -- d e ;; esac ) | tr u x )
}
---
name: comsub-torture-io
@ -10829,7 +10805,7 @@ expected-stdout:
}
inline_TWHILE() {
i=1
while let] " i < 10 " >&3
while \let] " i < 10 " >&3
do
echo $i
let ++i
@ -10839,20 +10815,20 @@ expected-stdout:
i=1; while (( i < 10 )) >&3; do echo $i; let ++i; done >&3
); }
function comsub_TWHILE {
x=$(i=1 ; while let] " i < 10 " >&3 ; do echo $i ; let ++i ; done >&3 )
x=$(i=1 ; while \let] " i < 10 " >&3 ; do echo $i ; let ++i ; done >&3 )
}
function reread_TWHILE { x=$((
i=1; while (( i < 10 )) >&3; do echo $i; let ++i; done >&3
)|tr u x); }
function reread_TWHILE {
x=$(( i=1 ; while let] " i < 10 " >&3 ; do echo $i ; let ++i ; done >&3 ) | tr u x )
x=$(( i=1 ; while \let] " i < 10 " >&3 ; do echo $i ; let ++i ; done >&3 ) | tr u x )
}
inline_TUNTIL() {
i=10; until (( !--i )) >&3 ; do echo $i; done >&3
}
inline_TUNTIL() {
i=10
until let] " !--i " >&3
until \let] " !--i " >&3
do
echo $i
done >&3
@ -10861,13 +10837,13 @@ expected-stdout:
i=10; until (( !--i )) >&3 ; do echo $i; done >&3
); }
function comsub_TUNTIL {
x=$(i=10 ; until let] " !--i " >&3 ; do echo $i ; done >&3 )
x=$(i=10 ; until \let] " !--i " >&3 ; do echo $i ; done >&3 )
}
function reread_TUNTIL { x=$((
i=10; until (( !--i )) >&3 ; do echo $i; done >&3
)|tr u x); }
function reread_TUNTIL {
x=$(( i=10 ; until let] " !--i " >&3 ; do echo $i ; done >&3 ) | tr u x )
x=$(( i=10 ; until \let] " !--i " >&3 ; do echo $i ; done >&3 ) | tr u x )
}
inline_TCOPROC() {
cat * >&3 |& >&3 ls

View File

@ -1,5 +1,5 @@
# $Id$
# $MirOS: src/bin/mksh/dot.mkshrc,v 1.91 2015/01/11 00:23:06 tg Exp $
# $MirOS: src/bin/mksh/dot.mkshrc,v 1.92 2015/03/08 22:54:33 tg Exp $
#-
# Copyright (c) 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010,
# 2011, 2012, 2013, 2014, 2015
@ -25,123 +25,123 @@
# catch non-mksh (including lksh) trying to shell this file
case $KSH_VERSION in
*MIRBSD\ KSH*) ;;
*) return 0 ;;
*) \return 0 ;;
esac
PS1='#'; (( USER_ID )) && PS1='$'; [[ ${HOSTNAME:=$(ulimit -c 0; hostname -s \
2>/dev/null)} = *([ ]|localhost) ]] && HOSTNAME=$(ulimit -c 0; hostname \
2>/dev/null); : ${EDITOR:=/bin/ed} ${HOSTNAME:=nil} ${TERM:=vt100}
: ${MKSH:=$(whence -p mksh)}; PS4='[$EPOCHREALTIME] '; PS1=$'\001\r''${|
local e=$?
PS1='#'; (( USER_ID )) && PS1='$'; [[ ${HOSTNAME:=$(\ulimit -c 0; hostname -s \
2>/dev/null)} = *([ ]|localhost) ]] && HOSTNAME=$(\ulimit -c 0; hostname \
2>/dev/null); \: ${EDITOR:=/bin/ed} ${HOSTNAME:=nil} ${TERM:=vt100}
\: ${MKSH:=$(\builtin whence -p mksh)}; PS4='[$EPOCHREALTIME] '; PS1=$'\001\r''${|
\builtin typeset e=$?
(( e )) && REPLY+="$e|"
REPLY+=${USER:=$(ulimit -c 0; id -un 2>/dev/null || echo \?)}
REPLY+=${USER:=$(\ulimit -c 0; id -un 2>/dev/null || \echo \?)}
REPLY+=@${HOSTNAME%%.*}:
local d=${PWD:-?} p=~; [[ $p = ?(*/) ]] || d=${d/#$p/~}
local m=${%d} n p=...; (( m > 0 )) || m=${#d}
\builtin typeset d=${PWD:-?} p=~; [[ $p = ?(*/) ]] || d=${d/#$p/~}
\builtin typeset m=${%d} n p=...; (( m > 0 )) || m=${#d}
(( m > (n = (COLUMNS/3 < 7 ? 7 : COLUMNS/3)) )) && d=${d:(-n)} || p=
REPLY+=$p$d
return $e
} '"$PS1 "; export EDITOR HOSTNAME MKSH TERM USER
alias ls=ls
unalias ls
alias l='ls -F'
alias la='l -a'
alias ll='l -l'
alias lo='l -alo'
alias doch='sudo mksh -c "$(fc -ln -1)"'
whence -p rot13 >/dev/null || alias rot13='tr \
\return $e
} '"$PS1 "; \export EDITOR HOSTNAME MKSH TERM USER
\alias ls=ls
\unalias ls
\alias l='ls -F'
\alias la='l -a'
\alias ll='l -l'
\alias lo='l -alo'
\alias doch='sudo mksh -c "$(\builtin fc -ln -1)"'
\command -v rot13 >/dev/null || \alias rot13='tr \
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ \
nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM'
if whence -p hd >/dev/null; then :; elif whence -p hexdump >/dev/null; then
if \command -v hd >/dev/null; then \:; elif \command -v hexdump >/dev/null; then
function hd {
hexdump -e '"%08.8_ax " 8/1 "%02X " " - " 8/1 "%02X "' \
-e '" |" "%_p"' -e '"|\n"' "$@"
}
else
function hd {
local -Uui16 -Z11 pos=0
local -Uui16 -Z5 hv=2147483647
local dasc line i
\builtin typeset -Uui16 -Z11 pos=0
\builtin typeset -Uui16 -Z5 hv=2147483647
\builtin typeset dasc line i
cat "$@" | { set +U; if read -arN -1 line; then
typeset -i1 'line[*]'
\cat "$@" | { \set +U; if \read -arN -1 line; then
\builtin typeset -i1 'line[*]'
i=0
while (( i < ${#line[*]} )); do
hv=${line[i++]}
if (( (pos & 15) == 0 )); then
(( pos )) && print -r -- "$dasc|"
print -n "${pos#16#} "
(( pos )) && \builtin print -r -- "$dasc|"
\builtin print -n "${pos#16#} "
dasc=' |'
fi
print -n "${hv#16#} "
\builtin print -n "${hv#16#} "
if (( (hv < 32) || (hv > 126) )); then
dasc+=.
else
dasc+=${line[i-1]#1#}
fi
(( (pos++ & 15) == 7 )) && print -n -- '- '
(( (pos++ & 15) == 7 )) && \builtin print -n -- '- '
done
while (( pos & 15 )); do
print -n ' '
(( (pos++ & 15) == 7 )) && print -n -- '- '
\builtin print -n ' '
(( (pos++ & 15) == 7 )) && \builtin print -n -- '- '
done
(( hv == 2147483647 )) || print -r -- "$dasc|"
(( hv == 2147483647 )) || \builtin print -r -- "$dasc|"
fi; }
}
fi
# Berkeley C shell compatible dirs, popd, and pushd functions
# Z shell compatible chpwd() hook, used to update DIRSTACK[0]
DIRSTACKBASE=$(realpath ~/. 2>/dev/null || print -nr -- "${HOME:-/}")
DIRSTACKBASE=$(\builtin realpath ~/. 2>/dev/null || \builtin print -nr -- "${HOME:-/}")
set -A DIRSTACK
function chpwd {
DIRSTACK[0]=$(realpath . 2>/dev/null || print -r -- "$PWD")
DIRSTACK[0]=$(\builtin realpath . 2>/dev/null || \builtin print -r -- "$PWD")
[[ $DIRSTACKBASE = ?(*/) ]] || \
DIRSTACK[0]=${DIRSTACK[0]/#$DIRSTACKBASE/~}
:
\:
}
chpwd .
\chpwd .
function cd {
builtin cd "$@" || return $?
chpwd "$@"
\builtin cd "$@" || \return $?
\chpwd "$@"
}
function cd_csh {
local d t=${1/#~/$DIRSTACKBASE}
\builtin typeset d t=${1/#~/$DIRSTACKBASE}
if ! d=$(builtin cd "$t" 2>&1); then
print -u2 "${1}: ${d##*cd: $t: }."
return 1
if ! d=$(\builtin cd "$t" 2>&1); then
\builtin print -u2 "${1}: ${d##*cd: $t: }."
\return 1
fi
cd "$t"
\cd "$t"
}
function dirs {
local d dwidth
local -i fl=0 fv=0 fn=0 cpos=0
\builtin typeset d dwidth
\builtin typeset -i fl=0 fv=0 fn=0 cpos=0
while getopts ":lvn" d; do
while \getopts ":lvn" d; do
case $d {
(l) fl=1 ;;
(v) fv=1 ;;
(n) fn=1 ;;
(*) print -u2 'Usage: dirs [-lvn].'
return 1 ;;
(*) \builtin print -u2 'Usage: dirs [-lvn].'
\return 1 ;;
}
done
shift $((OPTIND - 1))
\shift $((OPTIND - 1))
if (( $# > 0 )); then
print -u2 'Usage: dirs [-lvn].'
return 1
\builtin print -u2 'Usage: dirs [-lvn].'
\return 1
fi
if (( fv )); then
fv=0
while (( fv < ${#DIRSTACK[*]} )); do
d=${DIRSTACK[fv]}
(( fl )) && d=${d/#~/$DIRSTACKBASE}
print -r -- "$fv $d"
let fv++
\builtin print -r -- "$fv $d"
\builtin let fv++
done
else
fv=0
@ -151,138 +151,138 @@ function dirs {
(( dwidth = (${%d} > 0 ? ${%d} : ${#d}) ))
if (( fn && (cpos += dwidth + 1) >= 79 && \
dwidth < 80 )); then
print
\builtin print
(( cpos = dwidth + 1 ))
fi
print -nr -- "$d "
let fv++
\builtin print -nr -- "$d "
\builtin let fv++
done
print
\builtin print
fi
return 0
\return 0
}
function popd {
local d fa
local -i n=1
\builtin typeset d fa
\builtin typeset -i n=1
while getopts ":0123456789lvn" d; do
while \getopts ":0123456789lvn" d; do
case $d {
(l|v|n) fa+=" -$d" ;;
(+*) n=2
break ;;
(*) print -u2 'Usage: popd [-lvn] [+<n>].'
return 1 ;;
\break ;;
(*) \builtin print -u2 'Usage: popd [-lvn] [+<n>].'
\return 1 ;;
}
done
shift $((OPTIND - n))
\shift $((OPTIND - n))
n=0
if (( $# > 1 )); then
print -u2 popd: Too many arguments.
return 1
\builtin print -u2 popd: Too many arguments.
\return 1
elif [[ $1 = ++([0-9]) && $1 != +0 ]]; then
if (( (n = ${1#+}) >= ${#DIRSTACK[*]} )); then
print -u2 popd: Directory stack not that deep.
return 1
\builtin print -u2 popd: Directory stack not that deep.
\return 1
fi
elif [[ -n $1 ]]; then
print -u2 popd: Bad directory.
return 1
\builtin print -u2 popd: Bad directory.
\return 1
fi
if (( ${#DIRSTACK[*]} < 2 )); then
print -u2 popd: Directory stack empty.
return 1
\builtin print -u2 popd: Directory stack empty.
\return 1
fi
unset DIRSTACK[n]
set -A DIRSTACK -- "${DIRSTACK[@]}"
cd_csh "${DIRSTACK[0]}" || return 1
dirs $fa
\unset DIRSTACK[n]
\set -A DIRSTACK -- "${DIRSTACK[@]}"
\cd_csh "${DIRSTACK[0]}" || \return 1
\dirs $fa
}
function pushd {
local d fa
local -i n=1
\builtin typeset d fa
\builtin typeset -i n=1
while getopts ":0123456789lvn" d; do
while \getopts ":0123456789lvn" d; do
case $d {
(l|v|n) fa+=" -$d" ;;
(+*) n=2
break ;;
(*) print -u2 'Usage: pushd [-lvn] [<dir>|+<n>].'
return 1 ;;
\break ;;
(*) \builtin print -u2 'Usage: pushd [-lvn] [<dir>|+<n>].'
\return 1 ;;
}
done
shift $((OPTIND - n))
\shift $((OPTIND - n))
if (( $# == 0 )); then
if (( ${#DIRSTACK[*]} < 2 )); then
print -u2 pushd: No other directory.
return 1
\builtin print -u2 pushd: No other directory.
\return 1
fi
d=${DIRSTACK[1]}
DIRSTACK[1]=${DIRSTACK[0]}
cd_csh "$d" || return 1
\cd_csh "$d" || \return 1
elif (( $# > 1 )); then
print -u2 pushd: Too many arguments.
return 1
\builtin print -u2 pushd: Too many arguments.
\return 1
elif [[ $1 = ++([0-9]) && $1 != +0 ]]; then
if (( (n = ${1#+}) >= ${#DIRSTACK[*]} )); then
print -u2 pushd: Directory stack not that deep.
return 1
\builtin print -u2 pushd: Directory stack not that deep.
\return 1
fi
while (( n-- )); do
d=${DIRSTACK[0]}
unset DIRSTACK[0]
set -A DIRSTACK -- "${DIRSTACK[@]}" "$d"
\unset DIRSTACK[0]
\set -A DIRSTACK -- "${DIRSTACK[@]}" "$d"
done
cd_csh "${DIRSTACK[0]}" || return 1
\cd_csh "${DIRSTACK[0]}" || \return 1
else
set -A DIRSTACK -- placeholder "${DIRSTACK[@]}"
cd_csh "$1" || return 1
\set -A DIRSTACK -- placeholder "${DIRSTACK[@]}"
\cd_csh "$1" || \return 1
fi
dirs $fa
\dirs $fa
}
# pager (not control character safe)
function smores {
(
set +m
cat "$@" |&
trap "rv=\$?; kill $! >/dev/null 2>&1; exit \$rv" EXIT
while IFS= read -pr line; do
\set +m
\cat "$@" |&
\trap "rv=\$?; 'kill' $! >/dev/null 2>&1; 'exit' \$rv" EXIT
while IFS= \read -pr line; do
llen=${%line}
(( llen == -1 )) && llen=${#line}
(( llen = llen ? (llen + COLUMNS - 1) / COLUMNS : 1 ))
if (( (curlin += llen) >= LINES )); then
print -n -- '\033[7m--more--\033[0m'
read -u1 || exit $?
[[ $REPLY = [Qq]* ]] && exit 0
\builtin print -n -- '\033[7m--more--\033[0m'
\read -u1 || \exit $?
[[ $REPLY = [Qq]* ]] && \exit 0
curlin=$llen
fi
print -r -- "$line"
\builtin print -r -- "$line"
done
)
}
# base64 encoder and decoder, RFC compliant, NUL safe
function Lb64decode {
[[ -o utf8-mode ]]; local u=$? c s="$*" t
set +U
[[ -n $s ]] || { s=$(cat; print x); s=${s%x}; }
local -i i=0 j=0 n=${#s} p=0 v x
local -i16 o
[[ -o utf8-mode ]]; \builtin typeset u=$? c s="$*" t
\set +U
[[ -n $s ]] || { s=$(\cat; \builtin print x); s=${s%x}; }
\builtin typeset -i i=0 j=0 n=${#s} p=0 v x
\builtin typeset -i16 o
while (( i < n )); do
c=${s:(i++):1}
case $c {
(=) break ;;
(=) \break ;;
([A-Z]) (( v = 1#$c - 65 )) ;;
([a-z]) (( v = 1#$c - 71 )) ;;
([0-9]) (( v = 1#$c + 4 )) ;;
(+) v=62 ;;
(/) v=63 ;;
(*) continue ;;
(*) \continue ;;
}
(( x = (x << 6) | v ))
case $((p++)) {
(0) continue ;;
(0) \continue ;;
(1) (( o = (x >> 4) & 255 )) ;;
(2) (( o = (x >> 2) & 255 )) ;;
(3) (( o = x & 255 ))
@ -290,26 +290,26 @@ function Lb64decode {
;;
}
t+=\\x${o#16#}
(( ++j & 4095 )) && continue
print -n $t
(( ++j & 4095 )) && \continue
\builtin print -n $t
t=
done
print -n $t
(( u )) || set -U
\builtin print -n $t
(( u )) || \set -U
}
set -A Lb64encode_code -- A B C D E F G H I J K L M N O P Q R S T U V W X Y Z \
\set -A Lb64encode_code -- A B C D E F G H I J K L M N O P Q R S T U V W X Y Z \
a b c d e f g h i j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 8 9 + /
function Lb64encode {
[[ -o utf8-mode ]]; local u=$? c s t
set +U
[[ -o utf8-mode ]]; \builtin typeset u=$? c s t
\set +U
if (( $# )); then
read -raN-1 s <<<"$*"
unset s[${#s[*]}-1]
\read -raN-1 s <<<"$*"
\unset s[${#s[*]}-1]
else
read -raN-1 s
\read -raN-1 s
fi
local -i i=0 n=${#s[*]} j v
\builtin typeset -i i=0 n=${#s[*]} j v
while (( i < n )); do
(( v = s[i++] << 16 ))
@ -327,76 +327,76 @@ function Lb64encode {
t+===
fi
if (( ${#t} == 76 || i >= n )); then
print $t
\builtin print $t
t=
fi
done
(( u )) || set -U
(( u )) || \set -U
}
# Better Avalanche for the Jenkins Hash
typeset -Z11 -Uui16 Lbafh_v
\builtin typeset -Z11 -Uui16 Lbafh_v
function Lbafh_init {
Lbafh_v=0
}
function Lbafh_add {
[[ -o utf8-mode ]]; local u=$? s
set +U
[[ -o utf8-mode ]]; \builtin typeset u=$? s
\set +U
if (( $# )); then
read -raN-1 s <<<"$*"
unset s[${#s[*]}-1]
\read -raN-1 s <<<"$*"
\unset s[${#s[*]}-1]
else
read -raN-1 s
\read -raN-1 s
fi
local -i i=0 n=${#s[*]}
\builtin typeset -i i=0 n=${#s[*]}
while (( i < n )); do
((# Lbafh_v = (Lbafh_v + s[i++] + 1) * 1025 ))
((# Lbafh_v ^= Lbafh_v >> 6 ))
done
(( u )) || set -U
(( u )) || \set -U
}
function Lbafh_finish {
local -Ui t
\builtin typeset -Ui t
((# t = (((Lbafh_v >> 7) & 0x01010101) * 0x1B) ^ \
((Lbafh_v << 1) & 0xFEFEFEFE) ))
((# Lbafh_v = t ^ (t >>> 8) ^ (Lbafh_v >>> 8) ^ \
(Lbafh_v >>> 16) ^ (Lbafh_v >>> 24) ))
:
\:
}
# strip comments (and leading/trailing whitespace if IFS is set) from
# any file(s) given as argument, or stdin if none, and spew to stdout
function Lstripcom {
cat "$@" | { set -o noglob; while read _line; do
\cat "$@" | { \set -o noglob; while \read _line; do
_line=${_line%%#*}
[[ -n $_line ]] && print -r -- $_line
[[ -n $_line ]] && \builtin print -r -- $_line
done; }
}
# give MidnightBSD's laffer1 a bit of csh feeling
function setenv {
eval export "\"$1\""'="$2"'
\eval "'export' \"$1\""'="$2"'
}
: place customisations below this line
\: place customisations below this line
for p in ~/.etc/bin ~/bin; do
[[ -d $p/. ]] || continue
[[ -d $p/. ]] || \continue
[[ :$PATH: = *:$p:* ]] || PATH=$p:$PATH
done
export SHELL=$MKSH MANWIDTH=80 LESSHISTFILE=-
alias cls='print -n \\033c'
\export SHELL=$MKSH MANWIDTH=80 LESSHISTFILE=-
\alias cls='\builtin print -n \\033c'
#unset LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_IDENTIFICATION LC_MONETARY \
#\unset LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_IDENTIFICATION LC_MONETARY \
# LC_NAME LC_NUMERIC LC_TELEPHONE LC_TIME
#p=en_GB.UTF-8
#set -U
#export LANG=C LC_CTYPE=$p LC_MEASUREMENT=$p LC_MESSAGES=$p LC_PAPER=$p
#\set -U
#\export LANG=C LC_CTYPE=$p LC_MEASUREMENT=$p LC_MESSAGES=$p LC_PAPER=$p
unset p
\unset p
: place customisations above this line
\: place customisations above this line

26
main.c
View File

@ -34,7 +34,7 @@
#include <locale.h>
#endif
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.288 2015/03/08 21:30:21 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.289 2015/03/08 22:54:33 tg Exp $");
extern char **environ;
@ -66,24 +66,24 @@ static const char *initcoms[] = {
Ttypeset, "-x", "HOME", "PATH", "SHELL", NULL,
Ttypeset, "-i10", "COLUMNS", "LINES", "SECONDS", "TMOUT", NULL,
Talias,
"integer=typeset -i",
Tlocal_typeset,
"integer=\\builtin typeset -i",
"local=\\builtin typeset",
/* not "alias -t --": hash -r needs to work */
"hash=alias -t",
"type=whence -v",
"hash=\\builtin alias -t",
"type=\\builtin whence -v",
#if !defined(ANDROID) && !defined(MKSH_UNEMPLOYED)
/* not in Android for political reasons */
/* not in ARGE mksh due to no job control */
"stop=kill -STOP",
"stop=\\kill -STOP",
#endif
"autoload=typeset -fu",
"functions=typeset -f",
"history=fc -l",
"nameref=typeset -n",
"autoload=\\builtin typeset -fu",
"functions=\\builtin typeset -f",
"history=\\builtin fc -l",
"nameref=\\builtin typeset -n",
"nohup=nohup ",
"r=fc -e -",
"source=PATH=$PATH:. command .",
"login=exec login",
"r=\\builtin fc -e -",
"source=PATH=$PATH:. \\command .",
"login=\\exec login",
NULL,
/* this is what AT&T ksh seems to track, with the addition of emacs */
Talias, "-tU",

29
mksh.1
View File

@ -1,4 +1,4 @@
.\" $MirOS: src/bin/mksh/mksh.1,v 1.352 2015/03/07 20:46:29 tg Exp $
.\" $MirOS: src/bin/mksh/mksh.1,v 1.353 2015/03/08 22:54:34 tg Exp $
.\" $OpenBSD: ksh.1,v 1.156 2015/01/16 15:32:32 schwarze Exp $
.\"-
.\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
@ -74,7 +74,7 @@
.\" with -mandoc, it might implement .Mx itself, but we want to
.\" use our own definition. And .Dd must come *first*, always.
.\"
.Dd $Mdocdate: March 7 2015 $
.Dd $Mdocdate: March 8 2015 $
.\"
.\" Check which macro package we use, and do other -mdoc setup.
.\"
@ -1120,18 +1120,19 @@ also by newline) may be one same parse tree.
.Pp
The following command aliases are defined automatically by the shell:
.Bd -literal -offset indent
autoload=\*(aqtypeset \-fu\*(aq
functions=\*(aqtypeset \-f\*(aq
hash=\*(aqalias \-t\*(aq
history=\*(aqfc \-l\*(aq
integer=\*(aqtypeset \-i\*(aq
local=\*(aqtypeset\*(aq
login=\*(aqexec login\*(aq
nameref=\*(aqtypeset \-n\*(aq
autoload=\*(aq\ebuiltin typeset \-fu\*(aq
functions=\*(aq\ebuiltin typeset \-f\*(aq
hash=\*(aq\ebuiltin alias \-t\*(aq
history=\*(aq\ebuiltin fc \-l\*(aq
integer=\*(aq\ebuiltin typeset \-i\*(aq
local=\*(aq\ebuiltin typeset\*(aq
login=\*(aq\eexec login\*(aq
nameref=\*(aq\ebuiltin typeset \-n\*(aq
nohup=\*(aqnohup \*(aq
r=\*(aqfc \-e \-\*(aq
stop=\*(aqkill \-STOP\*(aq
type=\*(aqwhence \-v\*(aq
r=\*(aq\ebuiltin fc \-e \-\*(aq
source=\*(aqPATH=$PATH:. \ecommand .'
stop=\*(aq\ekill \-STOP\*(aq
type=\*(aq\ebuiltin whence \-v\*(aq
.Ed
.Pp
Tracked aliases allow the shell to remember where it found a particular
@ -6514,7 +6515,7 @@ for the in-memory portion of the history is slow, should use
.Xr memmove 3 .
.Pp
This document attempts to describe
.Nm mksh\ R50f
.Nm mksh\ R51
and up,
.\" with vendor patches from insert-your-name-here,
compiled without any options impacting functionality, such as

9
sh.h
View File

@ -169,9 +169,9 @@
#endif
#ifdef EXTERN
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.716 2015/03/08 21:30:22 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.717 2015/03/08 22:54:35 tg Exp $");
#endif
#define MKSH_VERSION "R50 2015/03/07"
#define MKSH_VERSION "R50 2015/03/08"
/* arithmetic types: C implementation */
#if !HAVE_CAN_INTTYPES
@ -802,9 +802,8 @@ EXTERN const char Toomem[] E_INIT("can't allocate %zu data bytes");
EXTERN const char Tsynerr[] E_INIT("syntax error");
#endif
EXTERN const char Tselect[] E_INIT("select");
EXTERN const char Tlocal_typeset[] E_INIT("local=typeset");
#define T_typeset (Tlocal_typeset + 5) /* "=typeset" */
#define Ttypeset (Tlocal_typeset + 6) /* "typeset" */
EXTERN const char T_typeset[] E_INIT("=typeset");
#define Ttypeset (T_typeset + 1) /* "typeset" */
EXTERN const char Talias[] E_INIT("alias");
EXTERN const char Tunalias[] E_INIT("unalias");
EXTERN const char Tsgset[] E_INIT("*=set");

8
syn.c
View File

@ -2,7 +2,7 @@
/*-
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009,
* 2011, 2012, 2013, 2014
* 2011, 2012, 2013, 2014, 2015
* Thorsten Glaser <tg@mirbsd.org>
*
* Provided that these terms and disclaimer and all copyright notices
@ -23,7 +23,7 @@
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.95 2014/12/15 22:08:55 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.96 2015/03/08 22:54:36 tg Exp $");
struct nesting_state {
int start_token; /* token than began nesting (eg, FOR) */
@ -244,10 +244,10 @@ nested(int type, int smark, int emark)
}
static const char let_cmd[] = {
CHAR, 'l', CHAR, 'e', CHAR, 't', CHAR, ']', EOS
QCHAR, 'l', CHAR, 'e', CHAR, 't', CHAR, ']', EOS
};
static const char setA_cmd0[] = {
CHAR, 's', CHAR, 'e', CHAR, 't', EOS
QCHAR, 's', CHAR, 'e', CHAR, 't', EOS
};
static const char setA_cmd1[] = {
CHAR, '-', CHAR, 'A', EOS