Merge remote-tracking branch 'mksh/master'

Conflicts:
    check.t
    exec.c
    sh.h
This commit is contained in:
KO Myung-Hun
2015-10-11 19:42:38 +09:00
19 changed files with 336 additions and 429 deletions

View File

@ -1,9 +1,9 @@
#!/bin/sh #!/bin/sh
srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.690 2015/09/05 19:18:59 tg Exp $' srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.691 2015/10/05 17:58:55 tg Exp $'
#- #-
# Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
# 2011, 2012, 2013, 2014, 2015 # 2011, 2012, 2013, 2014, 2015
# mirabilos <tg@mirbsd.org> # mirabilos <m@mirbsd.org>
# #
# Provided that these terms and disclaimer and all copyright notices # Provided that these terms and disclaimer and all copyright notices
# are retained or reproduced in an accompanying document, permission # are retained or reproduced in an accompanying document, permission
@ -1920,11 +1920,6 @@ ac_test gettimeofday <<-'EOF'
int main(void) { struct timeval tv; return (gettimeofday(&tv, NULL)); } int main(void) { struct timeval tv; return (gettimeofday(&tv, NULL)); }
EOF EOF
ac_test issetugid <<-'EOF'
#include <unistd.h>
int main(void) { return (issetugid()); }
EOF
ac_test killpg <<-'EOF' ac_test killpg <<-'EOF'
#include <signal.h> #include <signal.h>
int main(int ac, char *av[]) { return (av[0][killpg(123, ac)]); } int main(int ac, char *av[]) { return (av[0][killpg(123, ac)]); }

View File

@ -1,8 +1,8 @@
# $MirOS: src/bin/mksh/Makefile,v 1.143 2015/09/05 19:19:00 tg Exp $ # $MirOS: src/bin/mksh/Makefile,v 1.144 2015/10/05 17:58:56 tg Exp $
#- #-
# Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
# 2011, 2012, 2013, 2014, 2015 # 2011, 2012, 2013, 2014, 2015
# mirabilos <tg@mirbsd.org> # mirabilos <m@mirbsd.org>
# #
# Provided that these terms and disclaimer and all copyright notices # Provided that these terms and disclaimer and all copyright notices
# are retained or reproduced in an accompanying document, permission # are retained or reproduced in an accompanying document, permission
@ -51,12 +51,11 @@ CPPFLAGS+= -DMKSH_ASSUME_UTF8 -DMKSH_DISABLE_DEPRECATED \
-DHAVE_SIG_T=1 -DHAVE_SYS_ERRLIST=1 -DHAVE_SYS_SIGNAME=1 \ -DHAVE_SIG_T=1 -DHAVE_SYS_ERRLIST=1 -DHAVE_SYS_SIGNAME=1 \
-DHAVE_SYS_SIGLIST=1 -DHAVE_FLOCK=1 -DHAVE_LOCK_FCNTL=1 \ -DHAVE_SYS_SIGLIST=1 -DHAVE_FLOCK=1 -DHAVE_LOCK_FCNTL=1 \
-DHAVE_GETRUSAGE=1 -DHAVE_GETSID=1 -DHAVE_GETTIMEOFDAY=1 \ -DHAVE_GETRUSAGE=1 -DHAVE_GETSID=1 -DHAVE_GETTIMEOFDAY=1 \
-DHAVE_ISSETUGID=1 -DHAVE_KILLPG=1 -DHAVE_MEMMOVE=1 \ -DHAVE_KILLPG=1 -DHAVE_MEMMOVE=1 -DHAVE_MKNOD=0 -DHAVE_MMAP=1 \
-DHAVE_MKNOD=0 -DHAVE_MMAP=1 -DHAVE_NICE=1 -DHAVE_REVOKE=1 \ -DHAVE_NICE=1 -DHAVE_REVOKE=1 -DHAVE_SETLOCALE_CTYPE=0 \
-DHAVE_SETLOCALE_CTYPE=0 -DHAVE_LANGINFO_CODESET=0 \ -DHAVE_LANGINFO_CODESET=0 -DHAVE_SELECT=1 -DHAVE_SETRESUGID=1 \
-DHAVE_SELECT=1 -DHAVE_SETRESUGID=1 -DHAVE_SETGROUPS=1 \ -DHAVE_SETGROUPS=1 -DHAVE_STRERROR=0 -DHAVE_STRSIGNAL=0 \
-DHAVE_STRERROR=0 -DHAVE_STRSIGNAL=0 -DHAVE_STRLCPY=1 \ -DHAVE_STRLCPY=1 -DHAVE_FLOCK_DECL=1 -DHAVE_REVOKE_DECL=1 \
-DHAVE_FLOCK_DECL=1 -DHAVE_REVOKE_DECL=1 \
-DHAVE_SYS_ERRLIST_DECL=1 -DHAVE_SYS_SIGLIST_DECL=1 \ -DHAVE_SYS_ERRLIST_DECL=1 -DHAVE_SYS_SIGLIST_DECL=1 \
-DHAVE_PERSISTENT_HISTORY=1 -DMKSH_BUILD_R=511 -DHAVE_PERSISTENT_HISTORY=1 -DMKSH_BUILD_R=511
CPPFLAGS+= -D${${PROG:L}_tf:C/(Mir${MAN:E}{0,1}){2}/4/:S/x/mksh_BUILD/:U} CPPFLAGS+= -D${${PROG:L}_tf:C/(Mir${MAN:E}{0,1}){2}/4/:S/x/mksh_BUILD/:U}

164
check.t
View File

@ -1,9 +1,9 @@
# $MirOS: src/bin/mksh/check.t,v 1.707 2015/09/06 19:46:56 tg Exp $ # $MirOS: src/bin/mksh/check.t,v 1.710 2015/10/09 21:36:52 tg Exp $
# -*- mode: sh -*- # -*- mode: sh -*-
#- #-
# Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
# 2011, 2012, 2013, 2014, 2015 # 2011, 2012, 2013, 2014, 2015
# mirabilos <tg@mirbsd.org> # mirabilos <m@mirbsd.org>
# #
# Provided that these terms and disclaimer and all copyright notices # Provided that these terms and disclaimer and all copyright notices
# are retained or reproduced in an accompanying document, permission # are retained or reproduced in an accompanying document, permission
@ -30,7 +30,7 @@
# (2013/12/02 20:39:44) http://openbsd.cs.toronto.edu/cgi-bin/cvsweb/src/regress/bin/ksh/?sortby=date # (2013/12/02 20:39:44) http://openbsd.cs.toronto.edu/cgi-bin/cvsweb/src/regress/bin/ksh/?sortby=date
expected-stdout: expected-stdout:
@(#)MIRBSD KSH R51 2015/09/06 @(#)MIRBSD KSH R51 2015/10/09
description: description:
Check version of shell. Check version of shell.
stdin: stdin:
@ -39,7 +39,7 @@ name: KSH_VERSION
category: shell:legacy-no category: shell:legacy-no
--- ---
expected-stdout: expected-stdout:
@(#)LEGACY KSH R51 2015/09/06 @(#)LEGACY KSH R51 2015/10/09
description: description:
Check version of legacy shell. Check version of legacy shell.
stdin: stdin:
@ -6505,18 +6505,13 @@ name: xxx-param-subst-qmark-1
description: description:
Check suppresion of error message with null string. According to Check suppresion of error message with null string. According to
POSIX, it shouldn't print the error as 'word' isn't ommitted. POSIX, it shouldn't print the error as 'word' isn't ommitted.
ksh88/93, Solaris /bin/sh and /usr/xpg4/bin/sh all print the error, ksh88/93, Solaris /bin/sh and /usr/xpg4/bin/sh all print the error.
that's why the condition is reversed.
stdin: stdin:
unset foo unset foo
x= x=
echo x${foo?$x} echo x${foo?$x}
expected-exit: 1 expected-exit: 1
# POSIX expected-stderr-pattern: !/not set/
#expected-fail: yes
#expected-stderr-pattern: !/not set/
# common use
expected-stderr-pattern: /parameter null or not set/
--- ---
name: xxx-param-_-1 name: xxx-param-_-1
# fails due to weirdness of execv stuff # fails due to weirdness of execv stuff
@ -6532,7 +6527,7 @@ description:
env-setup: !HOME=/sweet! env-setup: !HOME=/sweet!
stdin: stdin:
echo ${A=a=}~ b=~ c=d~ ~ echo ${A=a=}~ b=~ c=d~ ~
set +o braceexpand set -o posix
unset A unset A
echo ${A=a=}~ b=~ c=d~ ~ echo ${A=a=}~ b=~ c=d~ ~
expected-stdout: expected-stdout:
@ -7496,7 +7491,6 @@ expected-stdout:
name: aliases-1 name: aliases-1
description: description:
Check if built-in shell aliases are okay Check if built-in shell aliases are okay
category: !android,!arge,!os:os2
stdin: stdin:
alias alias
typeset -f typeset -f
@ -7511,56 +7505,11 @@ expected-stdout:
nameref='\typeset -n' nameref='\typeset -n'
nohup='nohup ' nohup='nohup '
r='\builtin fc -e -' r='\builtin fc -e -'
source='PATH=$PATH:. \command .'
stop='\kill -STOP'
type='\builtin whence -v'
---
name: aliases-1-hartz4
description:
Check if built-in shell aliases are okay
category: android,arge,!os:os2
stdin:
alias
typeset -f
expected-stdout:
autoload='\typeset -fu'
functions='\typeset -f'
hash='\builtin alias -t'
history='\builtin fc -l'
integer='\typeset -i'
local='\typeset'
login='\exec login'
nameref='\typeset -n'
nohup='nohup '
r='\builtin fc -e -'
source='PATH=$PATH:. \command .'
type='\builtin whence -v'
---
name: aliases-1-os2
description:
Check if built-in shell aliases are okay
category: os:os2
stdin:
alias
typeset -f
expected-stdout:
autoload='\typeset -fu'
functions='\typeset -f'
hash='\builtin alias -t'
history='\builtin fc -l'
integer='\typeset -i'
local='\typeset'
login='\exec login'
nameref='\typeset -n'
nohup='nohup '
r='\builtin fc -e -'
source='PATH=$PATH\;. \command .'
type='\builtin whence -v' type='\builtin whence -v'
--- ---
name: aliases-2b name: aliases-2b
description: description:
Check if “set -o sh” does not influence built-in aliases Check if “set -o sh” does not influence built-in aliases
category: !android,!arge,!os:os2
arguments: !-o!sh! arguments: !-o!sh!
stdin: stdin:
alias alias
@ -7576,14 +7525,11 @@ expected-stdout:
nameref='\typeset -n' nameref='\typeset -n'
nohup='nohup ' nohup='nohup '
r='\builtin fc -e -' r='\builtin fc -e -'
source='PATH=$PATH:. \command .'
stop='\kill -STOP'
type='\builtin whence -v' type='\builtin whence -v'
--- ---
name: aliases-3b name: aliases-3b
description: description:
Check if running as sh does not influence built-in aliases Check if running as sh does not influence built-in aliases
category: !android,!arge,!os:os2
stdin: stdin:
cp "$__progname" sh cp "$__progname" sh
./sh -c 'alias; typeset -f' ./sh -c 'alias; typeset -f'
@ -7599,96 +7545,6 @@ expected-stdout:
nameref='\typeset -n' nameref='\typeset -n'
nohup='nohup ' nohup='nohup '
r='\builtin fc -e -' r='\builtin fc -e -'
source='PATH=$PATH:. \command .'
stop='\kill -STOP'
type='\builtin whence -v'
---
name: aliases-2b-hartz4
description:
Check if “set -o sh” does not influence built-in aliases
category: android,arge,!os:os2
arguments: !-o!sh!
stdin:
alias
typeset -f
expected-stdout:
autoload='\typeset -fu'
functions='\typeset -f'
hash='\builtin alias -t'
history='\builtin fc -l'
integer='\typeset -i'
local='\typeset'
login='\exec login'
nameref='\typeset -n'
nohup='nohup '
r='\builtin fc -e -'
source='PATH=$PATH:. \command .'
type='\builtin whence -v'
---
name: aliases-3b-hartz4
description:
Check if running as sh does not influence built-in aliases
category: android,arge,!os:os2
stdin:
cp "$__progname" sh
./sh -c 'alias; typeset -f'
rm -f sh
expected-stdout:
autoload='\typeset -fu'
functions='\typeset -f'
hash='\builtin alias -t'
history='\builtin fc -l'
integer='\typeset -i'
local='\typeset'
login='\exec login'
nameref='\typeset -n'
nohup='nohup '
r='\builtin fc -e -'
source='PATH=$PATH:. \command .'
type='\builtin whence -v'
---
name: aliases-2b-os2
description:
Check if “set -o sh” does not influence built-in aliases
category: os:os2
arguments: !-o!sh!
stdin:
alias
typeset -f
expected-stdout:
autoload='\typeset -fu'
functions='\typeset -f'
hash='\builtin alias -t'
history='\builtin fc -l'
integer='\typeset -i'
local='\typeset'
login='\exec login'
nameref='\typeset -n'
nohup='nohup '
r='\builtin fc -e -'
source='PATH=$PATH\;. \command .'
type='\builtin whence -v'
---
name: aliases-3b-os2
description:
Check if running as sh does not influence built-in aliases
category: os:os2
stdin:
cp "$__progname" sh
./sh -c 'alias; typeset -f'
rm -f sh
expected-stdout:
autoload='\typeset -fu'
functions='\typeset -f'
hash='\builtin alias -t'
history='\builtin fc -l'
integer='\typeset -i'
local='\typeset'
login='\exec login'
nameref='\typeset -n'
nohup='nohup '
r='\builtin fc -e -'
source='PATH=$PATH\;. \command .'
type='\builtin whence -v' type='\builtin whence -v'
--- ---
name: aliases-cmdline name: aliases-cmdline
@ -8960,7 +8816,7 @@ stdin:
7 . 7 .
--- ---
name: dot-needs-argument name: dot-needs-argument
description: description:
check Debian #415167 solution: '.' without arguments should fail check Debian #415167 solution: '.' without arguments should fail
stdin: stdin:
"$__progname" -c . "$__progname" -c .
@ -9059,20 +8915,16 @@ stdin:
mk() { mk() {
echo '#!'"$__progname" echo '#!'"$__progname"
echo "$1 {" echo "$1 {"
echo ' echo "bar='\''$0'\'\"
echo '}'
echo ' echo "bar='\''$0'\'\" echo ' echo "bar='\''$0'\'\"
echo '}' echo '}'
print -r -- "${2:-foo}" print -r -- "${2:-foo}"
} }
mk 'function foo' >f-korn mk 'function foo' >f-korn
mk 'foo ()' >f-dash mk 'foo ()' >f-dash
mk 'function stop ()' '\stop' >f-stop
mk 'function foo ()' >f-bash mk 'function foo ()' >f-bash
print '#!'"$__progname"'\nprint -r -- "${0%/f-argh}"' >f-argh print '#!'"$__progname"'\nprint -r -- "${0%/f-argh}"' >f-argh
chmod +x f-* chmod +x f-*
u=$(./f-argh) u=$(./f-argh)
x="dash: $(./f-dash)"; echo "${x/@("$u")/.}"
x="korn: $(./f-korn)"; echo "${x/@("$u")/.}" x="korn: $(./f-korn)"; echo "${x/@("$u")/.}"
x="dash: $(./f-dash)"; echo "${x/@("$u")/.}" x="dash: $(./f-dash)"; echo "${x/@("$u")/.}"
x="bash: $(./f-bash)"; echo "${x/@("$u")/.}" x="bash: $(./f-bash)"; echo "${x/@("$u")/.}"

View File

@ -1,9 +1,9 @@
# $Id$ # $Id$
# $MirOS: src/bin/mksh/dot.mkshrc,v 1.101 2015/07/18 23:03:24 tg Exp $ # $MirOS: src/bin/mksh/dot.mkshrc,v 1.102 2015/10/09 21:36:54 tg Exp $
#- #-
# Copyright (c) 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, # Copyright (c) 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010,
# 2011, 2012, 2013, 2014, 2015 # 2011, 2012, 2013, 2014, 2015
# mirabilos <tg@mirbsd.org> # mirabilos <m@mirbsd.org>
# #
# Provided that these terms and disclaimer and all copyright notices # Provided that these terms and disclaimer and all copyright notices
# are retained or reproduced in an accompanying document, permission # are retained or reproduced in an accompanying document, permission
@ -410,9 +410,6 @@ function enable {
i_alias[nalias]=nameref; b_alias[nalias++]='\typeset -n' i_alias[nalias]=nameref; b_alias[nalias++]='\typeset -n'
i_alias[nalias]=nohup; b_alias[nalias++]='nohup ' i_alias[nalias]=nohup; b_alias[nalias++]='nohup '
i_alias[nalias]=r; b_alias[nalias++]='\builtin fc -e -' i_alias[nalias]=r; b_alias[nalias++]='\builtin fc -e -'
#XXX OS/2
i_alias[nalias]=source; b_alias[nalias++]='PATH=$PATH:. \command .'
i_alias[nalias]=stop; b_alias[nalias++]='\kill -STOP'
i_alias[nalias]=type; b_alias[nalias++]='\builtin whence -v' i_alias[nalias]=type; b_alias[nalias++]='\builtin whence -v'
# accumulate mksh built-in utilities, in definition order, even ifndef # accumulate mksh built-in utilities, in definition order, even ifndef
@ -449,6 +446,7 @@ function enable {
i_func[nfunc++]=return i_func[nfunc++]=return
i_func[nfunc++]=set i_func[nfunc++]=set
i_func[nfunc++]=shift i_func[nfunc++]=shift
i_func[nfunc++]=source
i_func[nfunc++]=suspend i_func[nfunc++]=suspend
i_func[nfunc++]=test i_func[nfunc++]=test
i_func[nfunc++]=times i_func[nfunc++]=times
@ -468,6 +466,7 @@ function enable {
i_func[nfunc++]=printf i_func[nfunc++]=printf
i_func[nfunc++]=sleep i_func[nfunc++]=sleep
i_func[nfunc++]=domainname i_func[nfunc++]=domainname
i_func[nfunc++]=extproc
# accumulate aliases from dot.mkshrc, in definition order # accumulate aliases from dot.mkshrc, in definition order
i_alias[nalias]=l; b_alias[nalias++]='ls -F' i_alias[nalias]=l; b_alias[nalias++]='ls -F'

8
edit.c
View File

@ -1,12 +1,12 @@
/* $OpenBSD: edit.c,v 1.41 2015/09/01 13:12:31 tedu Exp $ */ /* $OpenBSD: edit.c,v 1.41 2015/09/01 13:12:31 tedu Exp $ */
/* $OpenBSD: edit.h,v 1.9 2011/05/30 17:14:35 martynas Exp $ */ /* $OpenBSD: edit.h,v 1.9 2011/05/30 17:14:35 martynas Exp $ */
/* $OpenBSD: emacs.c,v 1.51 2015/09/01 13:12:31 tedu Exp $ */ /* $OpenBSD: emacs.c,v 1.52 2015/09/10 22:48:58 nicm Exp $ */
/* $OpenBSD: vi.c,v 1.29 2015/09/01 13:12:31 tedu Exp $ */ /* $OpenBSD: vi.c,v 1.30 2015/09/10 22:48:58 nicm Exp $ */
/*- /*-
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
* 2011, 2012, 2013, 2014, 2015 * 2011, 2012, 2013, 2014, 2015
* mirabilos <tg@mirbsd.org> * mirabilos <m@mirbsd.org>
* *
* Provided that these terms and disclaimer and all copyright notices * Provided that these terms and disclaimer and all copyright notices
* are retained or reproduced in an accompanying document, permission * are retained or reproduced in an accompanying document, permission
@ -28,7 +28,7 @@
#ifndef MKSH_NO_CMDLINE_EDITING #ifndef MKSH_NO_CMDLINE_EDITING
__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.291 2015/09/05 19:19:01 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/edit.c,v 1.292 2015/10/09 16:11:13 tg Exp $");
/* /*
* in later versions we might use libtermcap for this, but since external * in later versions we might use libtermcap for this, but since external

28
eval.c
View File

@ -3,7 +3,7 @@
/*- /*-
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
* 2011, 2012, 2013, 2014, 2015 * 2011, 2012, 2013, 2014, 2015
* mirabilos <tg@mirbsd.org> * mirabilos <m@mirbsd.org>
* *
* Provided that these terms and disclaimer and all copyright notices * Provided that these terms and disclaimer and all copyright notices
* are retained or reproduced in an accompanying document, permission * are retained or reproduced in an accompanying document, permission
@ -23,7 +23,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.172 2015/09/06 19:46:59 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/eval.c,v 1.174 2015/10/09 19:29:47 tg Exp $");
/* /*
* string expansion * string expansion
@ -648,6 +648,9 @@ expand(
tilde_ok = 1; tilde_ok = 1;
break; break;
case '?': case '?':
if (*sp == CSUBST)
errorf("%s: parameter null or not set",
st->var->name);
f &= ~DOBLANK; f &= ~DOBLANK;
f |= DOTEMP; f |= DOTEMP;
/* FALLTHROUGH */ /* FALLTHROUGH */
@ -743,14 +746,12 @@ expand(
st = st->prev; st = st->prev;
word = quote || (!*x.str && (f & DOSCALAR)) ? IFS_WORD : IFS_IWS; word = quote || (!*x.str && (f & DOSCALAR)) ? IFS_WORD : IFS_IWS;
continue; continue;
case '?': { case '?':
char *s = Xrestpos(ds, dp, st->base); dp = Xrestpos(ds, dp, st->base);
errorf("%s: %s", st->var->name, errorf("%s: %s", st->var->name,
dp == s ? debunk(dp, dp, strlen(dp) + 1));
"parameter null or not set" : break;
(debunk(s, s, strlen(s) + 1), s));
}
case '0': case '0':
case '/': case '/':
case 0x100 | '#': case 0x100 | '#':
@ -1001,9 +1002,8 @@ expand(
break; break;
case '=': case '=':
/* Note first unquoted = for ~ */ /* Note first unquoted = for ~ */
if (!(f & DOTEMP) && !saw_eq && if (!(f & DOTEMP) && (!Flag(FPOSIX) ||
(Flag(FBRACEEXPAND) || (f & DOASNTILDE)) && !saw_eq) {
(f & DOASNTILDE))) {
saw_eq = true; saw_eq = true;
tilde_ok = 1; tilde_ok = 1;
} }
@ -1287,7 +1287,7 @@ varsub(Expand *xp, const char *sp, const char *word,
c = stype & 0x7F; c = stype & 0x7F;
/* test the compiler's code generator */ /* test the compiler's code generator */
if (((stype < 0x100) && (ctype(c, C_SUBOP2) || c == '/' || if (((stype < 0x100) && (ctype(c, C_SUBOP2) || c == '/' ||
(((stype&0x80) ? *xp->str=='\0' : xp->str==null) ? /* undef? */ (((stype & 0x80) ? *xp->str == '\0' : xp->str == null) ?
c == '=' || c == '-' || c == '?' : c == '+'))) || c == '=' || c == '-' || c == '?' : c == '+'))) ||
stype == (0x80 | '0') || stype == (0x100 | '#') || stype == (0x80 | '0') || stype == (0x100 | '#') ||
stype == (0x100 | 'Q')) stype == (0x100 | 'Q'))
@ -1334,8 +1334,8 @@ comsub(Expand *xp, const char *cp, int fn MKSH_A_UNUSED)
if ((io->ioflag & IOTYPE) != IOREAD) if ((io->ioflag & IOTYPE) != IOREAD)
errorf("%s: %s", "funny $() command", errorf("%s: %s", "funny $() command",
snptreef(NULL, 32, "%R", io)); snptreef(NULL, 32, "%R", io));
shf = shf_open(name = evalstr(io->name, DOTILDE), O_RDONLY, 0, shf = shf_open(name = evalstr(io->ioname, DOTILDE), O_RDONLY,
SHF_MAPHI|SHF_CLEXEC); 0, SHF_MAPHI | SHF_CLEXEC);
if (shf == NULL) if (shf == NULL)
warningf(!Flag(FTALKING), "%s: %s %s: %s", name, warningf(!Flag(FTALKING), "%s: %s %s: %s", name,
"can't open", "$(<...) input", cstrerror(errno)); "can't open", "$(<...) input", cstrerror(errno));

33
exec.c
View File

@ -1,9 +1,9 @@
/* $OpenBSD: exec.c,v 1.51 2015/04/18 18:28:36 deraadt Exp $ */ /* $OpenBSD: exec.c,v 1.52 2015/09/10 22:48:58 nicm Exp $ */
/*- /*-
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
* 2011, 2012, 2013, 2014, 2015 * 2011, 2012, 2013, 2014, 2015
* mirabilos <tg@mirbsd.org> * mirabilos <m@mirbsd.org>
* *
* Provided that these terms and disclaimer and all copyright notices * Provided that these terms and disclaimer and all copyright notices
* are retained or reproduced in an accompanying document, permission * are retained or reproduced in an accompanying document, permission
@ -23,7 +23,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.163 2015/09/06 19:46:59 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/exec.c,v 1.168 2015/10/09 21:36:55 tg Exp $");
#ifndef MKSH_DEFAULT_EXECSHELL #ifndef MKSH_DEFAULT_EXECSHELL
#define MKSH_DEFAULT_EXECSHELL MKSH_UNIXROOT "/bin/sh" #define MKSH_DEFAULT_EXECSHELL MKSH_UNIXROOT "/bin/sh"
@ -39,7 +39,6 @@ static const char *do_selectargs(const char **, bool);
static Test_op dbteste_isa(Test_env *, Test_meta); static Test_op dbteste_isa(Test_env *, Test_meta);
static const char *dbteste_getopnd(Test_env *, Test_op, bool); static const char *dbteste_getopnd(Test_env *, Test_op, bool);
static void dbteste_error(Test_env *, int, const char *); static void dbteste_error(Test_env *, int, const char *);
static int search_access(const char *, int);
/* XXX: horrible kludge to fit within the framework */ /* XXX: horrible kludge to fit within the framework */
static void plain_fmt_entry(char *, size_t, unsigned int, const void *); static void plain_fmt_entry(char *, size_t, unsigned int, const void *);
static void select_fmt_entry(char *, size_t, unsigned int, const void *); static void select_fmt_entry(char *, size_t, unsigned int, const void *);
@ -1092,14 +1091,6 @@ define(const char *name, struct op *t)
nhash = hash(name); nhash = hash(name);
#ifdef MKSH_LEGACY_MODE
if (t != NULL && !tobool(t->u.ksh_func)) {
/* drop same-name aliases for POSIX functions */
if ((tp = ktsearch(&aliases, name, nhash)))
ktdelete(tp);
}
#endif
while (/* CONSTCOND */ 1) { while (/* CONSTCOND */ 1) {
tp = findfunc(name, nhash, true); tp = findfunc(name, nhash, true);
@ -1284,7 +1275,7 @@ flushcom(bool all)
} }
/* check if path is something we want to find */ /* check if path is something we want to find */
static int int
search_access(const char *fn, int mode) search_access(const char *fn, int mode)
{ {
struct stat sb; struct stat sb;
@ -1293,9 +1284,13 @@ search_access(const char *fn, int mode)
/* file does not exist */ /* file does not exist */
return (ENOENT); return (ENOENT);
/* LINTED use of access */ /* LINTED use of access */
if (access(fn, mode) < 0) if (access(fn, mode) < 0) {
/* file exists, but we can't access it */ /* file exists, but we can't access it */
return (errno); int eno;
eno = errno;
return (eno ? eno : EACCES);
}
#ifdef __OS2__ #ifdef __OS2__
/* Treat all the files as executables on OS/2 */ /* Treat all the files as executables on OS/2 */
sb.st_mode |= S_IXUSR | S_IXGRP | S_IXOTH; sb.st_mode |= S_IXUSR | S_IXGRP | S_IXOTH;
@ -1386,7 +1381,9 @@ call_builtin(struct tbl *tp, const char **wp, const char *where, bool resetspec)
if (!tp) if (!tp)
internal_errorf("%s: %s", where, wp[0]); internal_errorf("%s: %s", where, wp[0]);
builtin_argv0 = wp[0]; builtin_argv0 = wp[0];
builtin_spec = tobool(!resetspec && (tp->flag & SPEC_BI)); builtin_spec = tobool(!resetspec &&
/*XXX odd use of KEEPASN */
((tp->flag & SPEC_BI) || (Flag(FPOSIX) && (tp->flag & KEEPASN))));
shf_reopen(1, SHF_WR, shl_stdout); shf_reopen(1, SHF_WR, shl_stdout);
shl_stdout_ok = true; shl_stdout_ok = true;
ksh_getopt_reset(&builtin_opt, GF_ERROR); ksh_getopt_reset(&builtin_opt, GF_ERROR);
@ -1405,7 +1402,7 @@ static int
iosetup(struct ioword *iop, struct tbl *tp) iosetup(struct ioword *iop, struct tbl *tp)
{ {
int u = -1; int u = -1;
char *cp = iop->name; char *cp = iop->ioname;
int iotype = iop->ioflag & IOTYPE; int iotype = iop->ioflag & IOTYPE;
bool do_open = true, do_close = false; bool do_open = true, do_close = false;
int flags = 0; int flags = 0;
@ -1417,7 +1414,7 @@ iosetup(struct ioword *iop, struct tbl *tp)
/* Used for tracing and error messages to print expanded cp */ /* Used for tracing and error messages to print expanded cp */
iotmp = *iop; iotmp = *iop;
iotmp.name = (iotype == IOHERE) ? NULL : cp; iotmp.ioname = (iotype == IOHERE) ? NULL : cp;
iotmp.ioflag |= IONAMEXP; iotmp.ioflag |= IONAMEXP;
if (Flag(FXTRACE)) { if (Flag(FXTRACE)) {

26
funcs.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: c_ksh.c,v 1.35 2015/09/01 13:12:31 tedu Exp $ */ /* $OpenBSD: c_ksh.c,v 1.37 2015/09/10 22:48:58 nicm Exp $ */
/* $OpenBSD: c_sh.c,v 1.46 2015/07/20 20:46:24 guenther Exp $ */ /* $OpenBSD: c_sh.c,v 1.46 2015/07/20 20:46:24 guenther Exp $ */
/* $OpenBSD: c_test.c,v 1.18 2009/03/01 20:11:06 otto Exp $ */ /* $OpenBSD: c_test.c,v 1.18 2009/03/01 20:11:06 otto Exp $ */
/* $OpenBSD: c_ulimit.c,v 1.19 2013/11/28 10:33:37 sobrado Exp $ */ /* $OpenBSD: c_ulimit.c,v 1.19 2013/11/28 10:33:37 sobrado Exp $ */
@ -6,7 +6,7 @@
/*- /*-
* Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
* 2010, 2011, 2012, 2013, 2014, 2015 * 2010, 2011, 2012, 2013, 2014, 2015
* mirabilos <tg@mirbsd.org> * mirabilos <m@mirbsd.org>
* *
* Provided that these terms and disclaimer and all copyright notices * Provided that these terms and disclaimer and all copyright notices
* are retained or reproduced in an accompanying document, permission * are retained or reproduced in an accompanying document, permission
@ -38,7 +38,7 @@
#endif #endif
#endif #endif
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.283 2015/09/05 19:19:04 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.286 2015/10/09 21:36:55 tg Exp $");
#if HAVE_KILLPG #if HAVE_KILLPG
/* /*
@ -127,6 +127,7 @@ const struct builtin mkshbuiltins[] = {
{"*=return", c_exitreturn}, {"*=return", c_exitreturn},
{Tsgset, c_set}, {Tsgset, c_set},
{"*=shift", c_shift}, {"*=shift", c_shift},
{"=source", c_dot},
#if !defined(MKSH_UNEMPLOYED) && HAVE_GETSID #if !defined(MKSH_UNEMPLOYED) && HAVE_GETSID
{"suspend", c_suspend}, {"suspend", c_suspend},
#endif #endif
@ -1305,7 +1306,8 @@ c_fgbg(const char **wp)
rv = j_resume(*wp, bg); rv = j_resume(*wp, bg);
else else
rv = j_resume("%%", bg); rv = j_resume("%%", bg);
return (bg ? 0 : rv); /* fg returns $? of the job unless POSIX */
return ((bg | Flag(FPOSIX)) ? 0 : rv);
} }
#endif #endif
@ -1383,6 +1385,13 @@ c_kill(const char **wp)
else else
shprintf("%d\n", n); shprintf("%d\n", n);
} }
} else if (Flag(FPOSIX)) {
n = 1;
while (n < ksh_NSIG) {
shf_puts(sigtraps[n].name, shl_stdout);
shf_putc(++n == ksh_NSIG ? '\n' : ' ',
shl_stdout);
}
} else { } else {
ssize_t w, mess_cols = 0, mess_octs = 0; ssize_t w, mess_cols = 0, mess_octs = 0;
int j = ksh_NSIG - 1; int j = ksh_NSIG - 1;
@ -1436,7 +1445,8 @@ void
getopts_reset(int val) getopts_reset(int val)
{ {
if (val >= 1) { if (val >= 1) {
ksh_getopt_reset(&user_opt, GF_NONAME | GF_PLUSOPT); ksh_getopt_reset(&user_opt, GF_NONAME |
(Flag(FPOSIX) ? 0 : GF_PLUSOPT));
user_opt.optind = user_opt.uoptind = val; user_opt.optind = user_opt.uoptind = val;
} }
} }
@ -1777,7 +1787,11 @@ c_dot(const char **wp)
bi_errorf("missing argument"); bi_errorf("missing argument");
return (1); return (1);
} }
if ((file = search_path(cp, path, R_OK, &errcode)) == NULL) { file = search_path(cp, path, R_OK, &errcode);
if (!file && errcode == ENOENT && wp[0][0] == 's' &&
search_access(cp, R_OK) == 0)
file = cp;
if (!file) {
bi_errorf("%s: %s", cp, cstrerror(errcode)); bi_errorf("%s: %s", cp, cstrerror(errcode));
return (1); return (1);
} }

10
jobs.c
View File

@ -1,9 +1,9 @@
/* $OpenBSD: jobs.c,v 1.41 2015/04/18 18:28:36 deraadt Exp $ */ /* $OpenBSD: jobs.c,v 1.43 2015/09/10 22:48:58 nicm Exp $ */
/*- /*-
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011, * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011,
* 2012, 2013, 2014, 2015 * 2012, 2013, 2014, 2015
* mirabilos <tg@mirbsd.org> * mirabilos <m@mirbsd.org>
* *
* Provided that these terms and disclaimer and all copyright notices * Provided that these terms and disclaimer and all copyright notices
* are retained or reproduced in an accompanying document, permission * are retained or reproduced in an accompanying document, permission
@ -23,7 +23,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/jobs.c,v 1.115 2015/09/05 19:19:05 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/jobs.c,v 1.116 2015/10/09 16:11:15 tg Exp $");
#if HAVE_KILLPG #if HAVE_KILLPG
#define mksh_killpg killpg #define mksh_killpg killpg
@ -86,7 +86,7 @@ struct job {
int flags; /* see JF_* */ int flags; /* see JF_* */
volatile int state; /* job state */ volatile int state; /* job state */
int status; /* exit status of last process */ int status; /* exit status of last process */
int32_t age; /* number of jobs started */ int age; /* number of jobs started */
Coproc_id coproc_id; /* 0 or id of coprocess output pipe */ Coproc_id coproc_id; /* 0 or id of coprocess output pipe */
#ifndef MKSH_UNEMPLOYED #ifndef MKSH_UNEMPLOYED
mksh_ttyst ttystat; /* saved tty state for stopped jobs */ mksh_ttyst ttystat; /* saved tty state for stopped jobs */
@ -118,7 +118,7 @@ static Job *async_job;
static pid_t async_pid; static pid_t async_pid;
static int nzombie; /* # of zombies owned by this process */ static int nzombie; /* # of zombies owned by this process */
static int32_t njobs; /* # of jobs started */ static int njobs; /* # of jobs started */
#ifndef CHILD_MAX #ifndef CHILD_MAX
#define CHILD_MAX 25 #define CHILD_MAX 25

58
lex.c
View File

@ -1,9 +1,9 @@
/* $OpenBSD: lex.c,v 1.50 2015/07/30 14:59:12 zhuk Exp $ */ /* $OpenBSD: lex.c,v 1.51 2015/09/10 22:48:58 nicm Exp $ */
/*- /*-
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
* 2011, 2012, 2013, 2014, 2015 * 2011, 2012, 2013, 2014, 2015
* mirabilos <tg@mirbsd.org> * mirabilos <m@mirbsd.org>
* *
* Provided that these terms and disclaimer and all copyright notices * Provided that these terms and disclaimer and all copyright notices
* are retained or reproduced in an accompanying document, permission * are retained or reproduced in an accompanying document, permission
@ -23,7 +23,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.209 2015/09/06 19:47:00 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/lex.c,v 1.212 2015/10/09 19:29:48 tg Exp $");
/* /*
* states while lexing word * states while lexing word
@ -234,7 +234,9 @@ yylex(int cf)
if (source->flags & SF_ALIAS) { if (source->flags & SF_ALIAS) {
/* trailing ' ' in alias definition */ /* trailing ' ' in alias definition */
source->flags &= ~SF_ALIAS; source->flags &= ~SF_ALIAS;
cf |= ALIAS; /* POSIX: trailing space only counts if parsing simple cmd */
if (!Flag(FPOSIX) || (cf & CMDWORD))
cf |= ALIAS;
} }
/* Initial state: one of SWORD SLETPAREN SHEREDELIM SBASE */ /* Initial state: one of SWORD SLETPAREN SHEREDELIM SBASE */
@ -524,27 +526,32 @@ yylex(int cf)
PUSH_STATE(SBQUOTE); PUSH_STATE(SBQUOTE);
*wp++ = COMSUB; *wp++ = COMSUB;
/* /*
* Need to know if we are inside double quotes * We need to know whether we are within double
* since sh/AT&T-ksh translate the \" to " in * quotes, since most shells translate \" to "
* "`...\"...`". * within "…`…\"…`…". This is not done in POSIX
* This is not done in POSIX mode (section * mode (§2.2.3 Double-Quotes: “The backquote
* 3.2.3, Double Quotes: "The backquote shall * shall retain its special meaning introducing
* retain its special meaning introducing the * the other form of command substitution (see
* other form of command substitution (see * Command Substitution). The portion of the
* 3.6.3). The portion of the quoted string * quoted string from the initial backquote and
* from the initial backquote and the * the characters up to the next backquote that
* characters up to the next backquote that * is not preceded by a <backslash>, having
* is not preceded by a backslash (having * escape characters removed, defines that
* escape characters removed) defines that * command whose output replaces "`...`" when
* command whose output replaces `...` when * the word is expanded.”; §2.6.3 Command
* the word is expanded." * Substitution: “Within the backquoted style
* Section 3.6.3, Command Substitution: * of command substitution, <backslash> shall
* "Within the backquoted style of command * retain its literal meaning, except when
* substitution, backslash shall retain its * followed by: '$', '`', or <backslash>. The
* literal meaning, except when followed by * search for the matching backquote shall be
* $ ` \."). * satisfied by the first unquoted non-escaped
* backquote; during this search, if a
* non-escaped backquote is encountered[…],
* undefined results occur.”).
*/ */
statep->ls_bool = false; statep->ls_bool = false;
if (Flag(FPOSIX))
break;
s2 = statep; s2 = statep;
base = state_info.base; base = state_info.base;
while (/* CONSTCOND */ 1) { while (/* CONSTCOND */ 1) {
@ -732,8 +739,9 @@ yylex(int cf)
case 0: case 0:
/* trailing \ is lost */ /* trailing \ is lost */
break; break;
case '$':
case '`':
case '\\': case '\\':
case '$': case '`':
*wp++ = c; *wp++ = c;
break; break;
case '"': case '"':
@ -943,7 +951,7 @@ yylex(int cf)
ungetsc(c2); ungetsc(c2);
} }
iop->name = NULL; iop->ioname = NULL;
iop->delim = NULL; iop->delim = NULL;
iop->heredoc = NULL; iop->heredoc = NULL;
/* free word */ /* free word */

71
lksh.1
View File

@ -1,7 +1,7 @@
.\" $MirOS: src/bin/mksh/lksh.1,v 1.11 2015/09/05 19:19:06 tg Exp $ .\" $MirOS: src/bin/mksh/lksh.1,v 1.15 2015/10/09 21:36:56 tg Exp $
.\"- .\"-
.\" Copyright (c) 2008, 2009, 2010, 2012, 2013, 2015 .\" Copyright (c) 2008, 2009, 2010, 2012, 2013, 2015
.\" mirabilos <tg@mirbsd.org> .\" mirabilos <m@mirbsd.org>
.\" .\"
.\" Provided that these terms and disclaimer and all copyright notices .\" Provided that these terms and disclaimer and all copyright notices
.\" are retained or reproduced in an accompanying document, permission .\" are retained or reproduced in an accompanying document, permission
@ -72,7 +72,7 @@
.\" with -mandoc, it might implement .Mx itself, but we want to .\" with -mandoc, it might implement .Mx itself, but we want to
.\" use our own definition. And .Dd must come *first*, always. .\" use our own definition. And .Dd must come *first*, always.
.\" .\"
.Dd $Mdocdate: September 5 2015 $ .Dd $Mdocdate: October 9 2015 $
.\" .\"
.\" Check which macro package we use, and do other -mdoc setup. .\" Check which macro package we use, and do other -mdoc setup.
.\" .\"
@ -173,12 +173,27 @@ It is recommended to port scripts to
.Nm mksh .Nm mksh
instead of relying on legacy or idiotic POSIX-mandated behaviour, instead of relying on legacy or idiotic POSIX-mandated behaviour,
since the MirBSD Korn Shell scripting language is much more consistent. since the MirBSD Korn Shell scripting language is much more consistent.
.Pp
Note that it's strongly recommended to invoke
.Nm
with at least the
.Fl o Ic posix
option, if not both that
.Em and Fl o Ic sh ,
to fully enjoy better compatibility to the
.Tn POSIX
standard (which is probably why you use
.Nm
over
.Nm mksh
in the first place) or legacy scripts, respectively.
.Sh LEGACY MODE .Sh LEGACY MODE
.Nm .Nm
currently has the following differences from currently has the following differences from
.Nm mksh : .Nm mksh :
.Bl -bullet .Bl -bullet
.It .It
.\"XXX TODO: remove (some systems may wish to have lksh as ksh)
There is no explicit support for interactive use, There is no explicit support for interactive use,
nor any command line editing or history code. nor any command line editing or history code.
Hence, Hence,
@ -202,33 +217,44 @@ change between versions; see the accompanying manual page
for the versions this document applies to. for the versions this document applies to.
.It .It
.Nm .Nm
only offers the traditional ten file descriptors to scripts.
.It
.Nm
uses uses
.Tn POSIX .Tn POSIX
arithmetics, which has quite a few implications: arithmetics, which has quite a few implications:
The data type for arithmetics is the host ISO C The data type for arithmetics is the host
.Tn ISO
C
.Vt long .Vt long
data type. data type.
Signed integer wraparound is Undefined Behaviour. Signed integer wraparound is Undefined Behaviour; this means that...
.Bd -literal -offset indent
$ echo $((2147483647 + 1))
.Ed
.Pp
\&... is permitted to, e.g. delete all files on your system
(the figure differs for non-32-bit systems, the rule doesn't).
The sign of the result of a modulo operation with at least one The sign of the result of a modulo operation with at least one
negative operand is unspecified. negative operand is unspecified.
Shift operations on negative numbers are unspecified. Shift operations on negative numbers are unspecified.
Division of the largest negative number by \-1 is Undefined Behaviour. Division of the largest negative number by \-1 is Undefined Behaviour.
The compiler is permitted to delete all data and crash the system The compiler is permitted to delete all data and crash the system
if Undefined Behaviour occurs. if Undefined Behaviour occurs (see above for an example).
.It .It
.Nm
only offers the traditional ten file descriptors to scripts.
.It
.\"XXX TODO: move this to FPOSIX
The rotation arithmetic operators are not available. The rotation arithmetic operators are not available.
.It .It
The shift arithmetic operators take all bits of the second operand into The shift arithmetic operators take all bits of the second operand into
account; if they exceed permitted precision, the result is unspecified. account; if they exceed permitted precision, the result is unspecified.
.It .It
.\"XXX TODO: move this to FPOSIX
The The
.Tn GNU .Tn GNU
.Nm bash .Nm bash
extension &\*(Gt to redirect stdout and stderr in one go is not parsed. extension &\*(Gt to redirect stdout and stderr in one go is not parsed.
.It .It
.\"XXX TODO: drop along with allowing interactivity
The The
.Nm mksh .Nm mksh
command line option command line option
@ -250,6 +276,7 @@ passes through the errorlevel from the
.Xr getopt 1 .Xr getopt 1
command. command.
.It .It
.\"XXX TODO: move to FPOSIX/FSH
Unlike Unlike
.At .At
.Nm ksh , .Nm ksh ,
@ -262,17 +289,6 @@ mode and
.Nm lksh .Nm lksh
do not keep file descriptors \*(Gt 2 private from sub-processes. do not keep file descriptors \*(Gt 2 private from sub-processes.
.It .It
.Nm lksh
undefines an alias when a
.Tn POSIX
function with the same name is defined,
to make that function immediately callable.
In
.Nm mksh ,
aliases have precedence; the name must be quoted or
.Ic unalias Ns ed
to access it.
.It
Functions defined with the Functions defined with the
.Ic function .Ic function
reserved word share the shell options reserved word share the shell options
@ -292,7 +308,18 @@ as
.Pa /bin/sh , .Pa /bin/sh ,
compilation to enable compilation to enable
.Ic set -o posix .Ic set -o posix
by default is highly recommended for better standards compliance. by default if called as
.Nm sh
is highly recommended for better standards compliance.
For better compatibility with legacy scripts, such as many
.Tn Debian
maintainer scripts, Upstart and SYSV init scripts, and other
unfixed scripts, using the compile-time options for enabling
.Em both
.Ic set -o posix -o sh
when the shell is run as
.Nm sh
is recommended.
.Pp .Pp
.Nm .Nm
tries to make a cross between a legacy bourne/posix compatibl-ish tries to make a cross between a legacy bourne/posix compatibl-ish
@ -302,7 +329,7 @@ is not exactly specified.
.Pp .Pp
The The
.Ic set .Ic set
built-in command does not have all options one would expect built-in command does not currently have all options one would expect
from a full-blown from a full-blown
.Nm mksh .Nm mksh
or or

25
main.c
View File

@ -1,12 +1,12 @@
/* $OpenBSD: main.c,v 1.56 2015/09/01 17:46:31 tedu Exp $ */ /* $OpenBSD: main.c,v 1.57 2015/09/10 22:48:58 nicm Exp $ */
/* $OpenBSD: tty.c,v 1.10 2014/08/10 02:44:26 guenther Exp $ */ /* $OpenBSD: tty.c,v 1.10 2014/08/10 02:44:26 guenther Exp $ */
/* $OpenBSD: io.c,v 1.25 2014/08/11 20:28:47 guenther Exp $ */ /* $OpenBSD: io.c,v 1.26 2015/09/11 08:00:27 guenther Exp $ */
/* $OpenBSD: table.c,v 1.16 2015/09/01 13:12:31 tedu Exp $ */ /* $OpenBSD: table.c,v 1.16 2015/09/01 13:12:31 tedu Exp $ */
/*- /*-
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
* 2011, 2012, 2013, 2014, 2015 * 2011, 2012, 2013, 2014, 2015
* mirabilos <tg@mirbsd.org> * mirabilos <m@mirbsd.org>
* *
* Provided that these terms and disclaimer and all copyright notices * Provided that these terms and disclaimer and all copyright notices
* are retained or reproduced in an accompanying document, permission * are retained or reproduced in an accompanying document, permission
@ -34,7 +34,7 @@
#include <locale.h> #include <locale.h>
#endif #endif
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.302 2015/09/05 19:19:06 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/main.c,v 1.306 2015/10/09 21:36:57 tg Exp $");
extern char **environ; extern char **environ;
@ -71,18 +71,12 @@ static const char *initcoms[] = {
/* not "alias -t --": hash -r needs to work */ /* not "alias -t --": hash -r needs to work */
"hash=\\builtin alias -t", "hash=\\builtin alias -t",
"type=\\builtin whence -v", "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",
#endif
"autoload=\\typeset -fu", "autoload=\\typeset -fu",
"functions=\\typeset -f", "functions=\\typeset -f",
"history=\\builtin fc -l", "history=\\builtin fc -l",
"nameref=\\typeset -n", "nameref=\\typeset -n",
"nohup=nohup ", "nohup=nohup ",
"r=\\builtin fc -e -", "r=\\builtin fc -e -",
"source=PATH=$PATH" MKSH_PATHSEPE ". \\command .",
"login=\\exec login", "login=\\exec login",
NULL, NULL,
/* this is what AT&T ksh seems to track, with the addition of emacs */ /* this is what AT&T ksh seems to track, with the addition of emacs */
@ -255,7 +249,7 @@ main_init(int argc, const char *argv[], Source **sp, struct block **lp)
/* define built-in commands and see if we were called as one */ /* define built-in commands and see if we were called as one */
ktinit(APERM, &builtins, ktinit(APERM, &builtins,
/* currently up to 51 builtins: 75% of 128 = 2^7 */ /* currently up to 54 builtins: 75% of 128 = 2^7 */
7); 7);
for (i = 0; mkshbuiltins[i].name != NULL; i++) for (i = 0; mkshbuiltins[i].name != NULL; i++)
if (!strcmp(ccp, builtin(mkshbuiltins[i].name, if (!strcmp(ccp, builtin(mkshbuiltins[i].name,
@ -416,11 +410,7 @@ main_init(int argc, const char *argv[], Source **sp, struct block **lp)
setint_n((vp_pipest = global("PIPESTATUS")), 0, 10); setint_n((vp_pipest = global("PIPESTATUS")), 0, 10);
/* Set this before parsing arguments */ /* Set this before parsing arguments */
Flag(FPRIVILEGED) = ( Flag(FPRIVILEGED) = (kshuid != ksheuid || kshgid != kshegid) ? 2 : 0;
#if HAVE_ISSETUGID
issetugid() ||
#endif
kshuid != ksheuid || kshgid != kshegid) ? 2 : 0;
/* this to note if monitor is set on command line (see below) */ /* this to note if monitor is set on command line (see below) */
#ifndef MKSH_UNEMPLOYED #ifndef MKSH_UNEMPLOYED
@ -1273,8 +1263,7 @@ bi_errorf(const char *fmt, ...)
/* /*
* POSIX special builtins and ksh special builtins cause * POSIX special builtins and ksh special builtins cause
* non-interactive shells to exit. * non-interactive shells to exit. XXX may not want LERROR here
* XXX odd use of KEEPASN; also may not want LERROR here
*/ */
if (builtin_spec) { if (builtin_spec) {
builtin_argv0 = NULL; builtin_argv0 = NULL;

6
misc.c
View File

@ -1,10 +1,10 @@
/* $OpenBSD: misc.c,v 1.40 2015/03/18 15:12:36 tedu Exp $ */ /* $OpenBSD: misc.c,v 1.41 2015/09/10 22:48:58 nicm Exp $ */
/* $OpenBSD: path.c,v 1.13 2015/09/05 09:47:08 jsg Exp $ */ /* $OpenBSD: path.c,v 1.13 2015/09/05 09:47:08 jsg Exp $ */
/*- /*-
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
* 2011, 2012, 2013, 2014, 2015 * 2011, 2012, 2013, 2014, 2015
* mirabilos <tg@mirbsd.org> * mirabilos <m@mirbsd.org>
* *
* Provided that these terms and disclaimer and all copyright notices * Provided that these terms and disclaimer and all copyright notices
* are retained or reproduced in an accompanying document, permission * are retained or reproduced in an accompanying document, permission
@ -30,7 +30,7 @@
#include <grp.h> #include <grp.h>
#endif #endif
__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.239 2015/09/05 19:19:07 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/misc.c,v 1.240 2015/10/09 16:11:17 tg Exp $");
#define KSH_CHVT_FLAG #define KSH_CHVT_FLAG
#ifdef MKSH_SMALL #ifdef MKSH_SMALL

217
mksh.1
View File

@ -1,9 +1,9 @@
.\" $MirOS: src/bin/mksh/mksh.1,v 1.380 2015/09/05 19:19:08 tg Exp $ .\" $MirOS: src/bin/mksh/mksh.1,v 1.382 2015/10/09 21:36:57 tg Exp $
.\" $OpenBSD: ksh.1,v 1.160 2015/07/04 13:27:04 feinerer Exp $ .\" $OpenBSD: ksh.1,v 1.160 2015/07/04 13:27:04 feinerer Exp $
.\"- .\"-
.\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, .\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
.\" 2010, 2011, 2012, 2013, 2014, 2015 .\" 2010, 2011, 2012, 2013, 2014, 2015
.\" mirabilos <tg@mirbsd.org> .\" mirabilos <m@mirbsd.org>
.\" .\"
.\" Provided that these terms and disclaimer and all copyright notices .\" Provided that these terms and disclaimer and all copyright notices
.\" are retained or reproduced in an accompanying document, permission .\" are retained or reproduced in an accompanying document, permission
@ -74,7 +74,7 @@
.\" with -mandoc, it might implement .Mx itself, but we want to .\" with -mandoc, it might implement .Mx itself, but we want to
.\" use our own definition. And .Dd must come *first*, always. .\" use our own definition. And .Dd must come *first*, always.
.\" .\"
.Dd $Mdocdate: September 5 2015 $ .Dd $Mdocdate: October 9 2015 $
.\" .\"
.\" Check which macro package we use, and do other -mdoc setup. .\" Check which macro package we use, and do other -mdoc setup.
.\" .\"
@ -1130,8 +1130,6 @@ login=\*(aq\eexec login\*(aq
nameref=\*(aq\etypeset \-n\*(aq nameref=\*(aq\etypeset \-n\*(aq
nohup=\*(aqnohup \*(aq nohup=\*(aqnohup \*(aq
r=\*(aq\ebuiltin fc \-e \-\*(aq r=\*(aq\ebuiltin fc \-e \-\*(aq
source=\*(aqPATH=$PATH:. \ecommand .\*(aq
stop=\*(aq\ekill \-STOP\*(aq
type=\*(aq\ebuiltin whence \-v\*(aq type=\*(aq\ebuiltin whence \-v\*(aq
.Ed .Ed
.Pp .Pp
@ -2336,7 +2334,7 @@ input is initially set to be from
.Pa /dev/null , .Pa /dev/null ,
and commands for which any of the following redirections have been specified: and commands for which any of the following redirections have been specified:
.Bl -tag -width XXxxmarker .Bl -tag -width XXxxmarker
.It \*(Gt Ar file .It \*(Gt Ns Ar file
Standard output is redirected to Standard output is redirected to
.Ar file . .Ar file .
If If
@ -2352,13 +2350,13 @@ for reading and then truncate it when it opens it for writing, before
.Ar cmd .Ar cmd
gets a chance to actually read gets a chance to actually read
.Ar foo . .Ar foo .
.It \*(Gt\*(Ba Ar file .It \*(Gt\*(Ba Ns Ar file
Same as Same as
.Ic \*(Gt , .Ic \*(Gt ,
except the file is truncated, even if the except the file is truncated, even if the
.Ic noclobber .Ic noclobber
option is set. option is set.
.It \*(Gt\*(Gt Ar file .It \*(Gt\*(Gt Ns Ar file
Same as Same as
.Ic \*(Gt , .Ic \*(Gt ,
except if except if
@ -2367,15 +2365,15 @@ exists it is appended to instead of being truncated.
Also, the file is opened Also, the file is opened
in append mode, so writes always go to the end of the file (see in append mode, so writes always go to the end of the file (see
.Xr open 2 ) . .Xr open 2 ) .
.It \*(Lt Ar file .It \*(Lt Ns Ar file
Standard input is redirected from Standard input is redirected from
.Ar file , .Ar file ,
which is opened for reading. which is opened for reading.
.It \*(Lt\*(Gt Ar file .It \*(Lt\*(Gt Ns Ar file
Same as Same as
.Ic \*(Lt , .Ic \*(Lt ,
except the file is opened for reading and writing. except the file is opened for reading and writing.
.It \*(Lt\*(Lt Ar marker .It \*(Lt\*(Lt Ns Ar marker
After reading the command line containing this kind of redirection (called a After reading the command line containing this kind of redirection (called a
.Dq here document ) , .Dq here document ) ,
the shell copies lines from the command source into a temporary file until a the shell copies lines from the command source into a temporary file until a
@ -2415,11 +2413,11 @@ or double
.Sq \&"" .Sq \&""
quotes with nothing in between, the here document ends at the next empty line quotes with nothing in between, the here document ends at the next empty line
and substitution will not be performed. and substitution will not be performed.
.It \*(Lt\*(Lt\- Ar marker .It \*(Lt\*(Lt\- Ns Ar marker
Same as Same as
.Ic \*(Lt\*(Lt , .Ic \*(Lt\*(Lt ,
except leading tabs are stripped from lines in the here document. except leading tabs are stripped from lines in the here document.
.It \*(Lt\*(Lt\*(Lt Ar word .It \*(Lt\*(Lt\*(Lt Ns Ar word
Same as Same as
.Ic \*(Lt\*(Lt , .Ic \*(Lt\*(Lt ,
except that except that
@ -2427,7 +2425,7 @@ except that
.Em is .Em is
the here document. the here document.
This is called a here string. This is called a here string.
.It \*(Lt& Ar fd .It \*(Lt& Ns Ar fd
Standard input is duplicated from file descriptor Standard input is duplicated from file descriptor
.Ar fd . .Ar fd .
.Ar fd .Ar fd
@ -2441,42 +2439,35 @@ indicating standard input is to be closed.
Note that Note that
.Ar fd .Ar fd
is limited to a single digit in most shell implementations. is limited to a single digit in most shell implementations.
.It \*(Gt& Ar fd .It \*(Gt& Ns Ar fd
Same as Same as
.Ic \*(Lt& , .Ic \*(Lt& ,
except the operation is done on standard output. except the operation is done on standard output.
.It &\*(Gt Ar file .It &\*(Gt Ns Ar file
Same as Same as
.Ic \*(Gt Ar file 2\*(Gt&1 . .Ic \*(Gt Ns Ar file 2\*(Gt&1 .
This is a GNU This is a deprecated (legacy) GNU
.Nm bash .Nm bash
extension supported by extension supported by
.Nm .Nm
which also supports the preceding explicit fd number, for example, which also supports the preceding explicit fd number, for example,
.Ic 3&\*(Gt Ar file .Ic 3&\*(Gt Ns Ar file
is the same as is the same as
.Ic 3\*(Gt Ar file 2\*(Gt&3 .Ic 3\*(Gt Ns Ar file 2\*(Gt&3
in in
.Nm .Nm
but a syntax error in GNU but a syntax error in GNU
.Nm bash . .Nm bash .
Setting the
.Fl o Ar posix
or
.Fl o Ar sh
shell options disable parsing of this redirection;
it's a compatibility feature to legacy scripts, to
not be used when writing new shell code.
.It Xo .It Xo
.No &\*(Gt\*(Ba Ar file , .No &\*(Gt\*(Ba Ns Ar file ,
.No &\*(Gt\*(Gt Ar file , .No &\*(Gt\*(Gt Ns Ar file ,
.No &\*(Gt& Ar fd .No &\*(Gt& Ns Ar fd
.Xc .Xc
Same as Same as
.Ic \*(Gt\*(Ba Ar file , .Ic \*(Gt\*(Ba Ns Ar file ,
.Ic \*(Gt\*(Gt Ar file , .Ic \*(Gt\*(Gt Ns Ar file ,
or or
.Ic \*(Gt& Ar fd , .Ic \*(Gt& Ns Ar fd ,
followed by followed by
.Ic 2\*(Gt&1 , .Ic 2\*(Gt&1 ,
as above. as above.
@ -2516,12 +2507,7 @@ will print an error with a line number prepended to it:
.Pp .Pp
.D1 $ cat /foo/bar 2\*(Gt&1 \*(Gt/dev/null \*(Ba pr \-n \-t .D1 $ cat /foo/bar 2\*(Gt&1 \*(Gt/dev/null \*(Ba pr \-n \-t
.Pp .Pp
File descriptors created by input/output redirections are private to the File descriptors created by I/O redirections are private to the shell.
Korn shell, but passed to sub-processes if
.Fl o Ic posix
or
.Fl o Ic sh
is set.
.Ss Arithmetic expressions .Ss Arithmetic expressions
Integer arithmetic expressions can be used with the Integer arithmetic expressions can be used with the
.Ic let .Ic let
@ -2597,12 +2583,8 @@ in all forms of arithmetic expressions, except as numeric arguments to the
built-in command. built-in command.
Prefixing numbers with a sole digit zero Prefixing numbers with a sole digit zero
.Pq Sq 0 .Pq Sq 0
leads to the shell interpreting it as base-8 (octal) integer in does not cause interpretation as octal, as that's unsafe to do.
.Ic posix .Pp
mode
.Em only ;
historically, (pd)ksh has never done so either anyway,
and it's unsafe to do that, but POSIX demands it nowadays.
As a special As a special
.Nm mksh .Nm mksh
extension, numbers to the base of one are treated as either (8-bit extension, numbers to the base of one are treated as either (8-bit
@ -2626,7 +2608,9 @@ octet not forming a valid and minimal CESU-8 sequence is passed, the
behaviour is undefined (usually, the shell aborts with a parse error, behaviour is undefined (usually, the shell aborts with a parse error,
but rarely, it succeeds, e.g. on the sequence C2 20). but rarely, it succeeds, e.g. on the sequence C2 20).
That's why you should always use ASCII mode unless you know that the That's why you should always use ASCII mode unless you know that the
input is well-formed UTF-8 in the range of 0000..FFFD. input is well-formed UTF-8 in the range of 0000..FFFD if you use this
feature, as opposed to
.Ic read Fl a .
.Pp .Pp
The operators are evaluated as follows: The operators are evaluated as follows:
.Bl -tag -width Ds -offset indent .Bl -tag -width Ds -offset indent
@ -2956,18 +2940,18 @@ Additional
.Nm .Nm
commands keeping assignments: commands keeping assignments:
.Pp .Pp
.Ic builtin , global , typeset , wait .Ic builtin , global , source , typeset ,
.Ic wait
.Pp .Pp
Builtins that are not special: Builtins that are not special:
.Pp .Pp
.Ic [ , alias , bg , bind , .Ic [ , alias , bg , bind ,
.Ic cat , cd , command , echo , .Ic cat , cd , command , echo ,
.Ic false , fc , fg , getopts , .Ic false , fc , fg , getopts ,
.Ic jobs , kill , let , mknod , .Ic jobs , kill , let , print ,
.Ic print , pwd , read , realpath , .Ic pwd , read , realpath , rename ,
.Ic rename , sleep , suspend , test , .Ic sleep , suspend , test , true ,
.Ic true , ulimit , umask , unalias , .Ic ulimit , umask , unalias , whence
.Ic whence
.Pp .Pp
Once the type of command has been determined, any command-line parameter Once the type of command has been determined, any command-line parameter
assignments are performed and exported for the duration of the command. assignments are performed and exported for the duration of the command.
@ -3687,10 +3671,6 @@ option),
and and
.Ar minor .Ar minor
(minor device number). (minor device number).
.Pp
See
.Xr mknod 8
for further information.
This is not normally part of This is not normally part of
.Nm mksh ; .Nm mksh ;
however, distributors may have added this as builtin as a speed hack. however, distributors may have added this as builtin as a speed hack.
@ -4241,19 +4221,25 @@ commands above for more details.
Make the exit status of a pipeline (before logically complementing) the Make the exit status of a pipeline (before logically complementing) the
rightmost non-zero errorlevel, or zero if all commands exited with zero. rightmost non-zero errorlevel, or zero if all commands exited with zero.
.It Fl o Ic posix .It Fl o Ic posix
Enable a somewhat more Behave closer to the standards
.Px (see
ish mode. .Sx POSIX mode
for details).
Automatically enabled if the basename of the shell invocation begins with
.Dq sh
and this autodetection feature is compiled in
.Pq not in MirBSD .
As a side effect, setting this flag turns off As a side effect, setting this flag turns off
.Ic braceexpand .Ic braceexpand
mode, which can be turned back on manually, and mode, which can be turned back on manually, and
.Ic sh .Ic sh
mode. mode (unless both are enabled at the same time).
.It Fl o Ic sh .It Fl o Ic sh
Enable Enable
.Pa /bin/sh .Pa /bin/sh
.Pq kludge .Pq kludge
mode. mode (see
.Sx SH mode ) .
Automatically enabled if the basename of the shell invocation begins with Automatically enabled if the basename of the shell invocation begins with
.Dq sh .Dq sh
and this autodetection feature is compiled in and this autodetection feature is compiled in
@ -4262,7 +4248,7 @@ As a side effect, setting this flag turns off
.Ic braceexpand .Ic braceexpand
mode, which can be turned back on manually, and mode, which can be turned back on manually, and
.Ic posix .Ic posix
mode. mode (unless both are enabled at the same time).
.It Fl o Ic vi .It Fl o Ic vi
Enable Enable
.Xr vi 1 Ns -like .Xr vi 1 Ns -like
@ -4332,16 +4318,9 @@ Signal delivery may continue execution earlier.
Like Like
.Ic \&. Po Do dot Dc Pc , .Ic \&. Po Do dot Dc Pc ,
except that the current working directory is appended to the except that the current working directory is appended to the
.Ev PATH search path (GNU
in GNU
.Nm bash .Nm bash
and extension).
.Nm mksh .
In
.Nm ksh93
and
.Nm mksh ,
this is implemented as a shell alias instead of a builtin.
.Pp .Pp
.It Ic suspend .It Ic suspend
Stops the shell as if it had received the suspend character from Stops the shell as if it had received the suspend character from
@ -5301,6 +5280,69 @@ If another attempt
is immediately made to exit the shell, the running jobs are sent a is immediately made to exit the shell, the running jobs are sent a
.Dv SIGHUP .Dv SIGHUP
signal and the shell exits. signal and the shell exits.
.Ss POSIX mode
Entering
.Ic set Fl o Ic posix
mode will cause
.Nm
to behave even more
.Tn POSIX
compliant in places where the defaults or opinions differ.
Note that
.Nm mksh
will still operate with unsigned 32-bit arithmetics; use
.Nm lksh
if arithmetics on the host
.Vt long
data type, complete with ISO C Undefined Behaviour, are required;
refer to the
.Xr lksh 1
manual page for details.
Most other historic,
.At
.Nm ksh Ns -compatible ,
or opinionated differences can be disabled by using this mode; these are:
.Bl -bullet
.It
The GNU
.Nm bash
I/O redirection
.Ic &\*(Gt Ns Ar file
is no longer supported.
.It
File descriptors created by I/O redirections are inherited by
child processes.
.It
Numbers with a leading digit zero are interpreted as octal.
.It
The
.Nm echo
builtin does not interpret backslashes and only supports the exact option
.Dq Fl n .
.It
\&... (list is incomplete)
.El
.Ss SH mode
Compatibility mode; intended for use with legacy scripts that
cannot easily be fixed; the changes are as follows:
.Bl -bullet
.It
The GNU
.Nm bash
I/O redirection
.Ic &\*(Gt Ns Ar file
is no longer supported.
.It
File descriptors created by I/O redirections are inherited by
child processes.
.It
The
.Nm echo
builtin does not interpret backslashes and only supports the exact option
.Dq Fl n .
.It
\&... (list is incomplete)
.El
.Ss Interactive input line editing .Ss Interactive input line editing
The shell supports three modes of reading command lines from a The shell supports three modes of reading command lines from a
.Xr tty 4 .Xr tty 4
@ -6394,8 +6436,8 @@ contains the system and suid profile.
.An -nosplit .An -nosplit
.Nm "The MirBSD Korn Shell" .Nm "The MirBSD Korn Shell"
is developed by is developed by
.An mirabilos Aq tg@mirbsd.org .An mirabilos Aq Mt m@mirbsd.org
and currently maintained as part of The MirOS Project. as part of The MirOS Project.
This shell is based on the public domain 7th edition Bourne shell clone by This shell is based on the public domain 7th edition Bourne shell clone by
.An Charles Forsyth , .An Charles Forsyth ,
who kindly agreed to, in countries where the Public Domain status of the work who kindly agreed to, in countries where the Public Domain status of the work
@ -6414,10 +6456,10 @@ The first release of
was created by was created by
.An Eric Gisin , .An Eric Gisin ,
and it was subsequently maintained by and it was subsequently maintained by
.An John R. MacMillan Aq Mt change!john@sq.sq.com , .An John R. MacMillan ,
.An Simon J. Gerraty Aq Mt sjg@zen.void.oz.au , .An Simon J. Gerraty ,
and and
.An Michael Rendell Aq Mt michael@cs.mun.ca . .An Michael Rendell .
The effort of several projects, such as Debian and OpenBSD, and other The effort of several projects, such as Debian and OpenBSD, and other
contributors including our users, to improve the shell is appreciated. contributors including our users, to improve the shell is appreciated.
See the documentation, CVS, and web site for details. See the documentation, CVS, and web site for details.
@ -6460,23 +6502,16 @@ foo \*(Ba bar \*(Ba& read \-p baz # will, however, do so
.Nm mksh .Nm mksh
provides a consistent set of 32-bit integer arithmetics, both signed provides a consistent set of 32-bit integer arithmetics, both signed
and unsigned, with defined wraparound and sign of the result of a and unsigned, with defined wraparound and sign of the result of a
remainder operation, even (defying POSIX) on 64-bit systems. remainder operation, even (defying POSIX) on 36-bit and 64-bit systems.
If you require 64-bit integer arithmetics, use
.Nm lksh Pq legacy mksh
instead, but be aware that, in POSIX, it's legal for the OS to make
.Li print $((2147483647 + 1))
delete all files on your system, as it's Undefined Behaviour.
.Pp .Pp
.Nm mksh .Nm mksh
provides a consistent, clear interface normally. provides a consistent, clear interface normally.
This may deviate from POSIX in optional or opinionated places, such This may deviate from POSIX in historic or opinionated places.
as whether leading-digit-zero numbers should be interpreted as octal.
.Ic set Fl o Ic posix .Ic set Fl o Ic posix
will cause the shell (either (see
.Nm mksh .Sx POSIX mode
or for details)
.Nm lksh ) will cause the shell to behave more conformant.
to behave more like the standard expects.
.Pp .Pp
For the purpose of For the purpose of
.Tn POSIX , .Tn POSIX ,
@ -6530,7 +6565,7 @@ for the in-memory portion of the history is slow, should use
.Xr memmove 3 . .Xr memmove 3 .
.Pp .Pp
This document attempts to describe This document attempts to describe
.Nm mksh\ R51 .Nm mksh\ R51 Ns -CVS
and up, and up,
.\" with vendor patches from insert-your-name-here, .\" with vendor patches from insert-your-name-here,
compiled without any options impacting functionality, such as compiled without any options impacting functionality, such as
@ -6549,7 +6584,7 @@ Please report bugs in
to the to the
.Mx .Mx
mailing list at mailing list at
.Aq miros\-mksh@mirbsd.org .Aq Mt miros\-mksh@mirbsd.org
or in the or in the
.Li \&#\&!/bin/mksh .Li \&#\&!/bin/mksh
.Pq or Li \&#ksh .Pq or Li \&#ksh

28
sh.h
View File

@ -1,4 +1,4 @@
/* $OpenBSD: sh.h,v 1.33 2013/12/18 13:53:12 millert Exp $ */ /* $OpenBSD: sh.h,v 1.35 2015/09/10 22:48:58 nicm Exp $ */
/* $OpenBSD: shf.h,v 1.6 2005/12/11 18:53:51 deraadt Exp $ */ /* $OpenBSD: shf.h,v 1.6 2005/12/11 18:53:51 deraadt Exp $ */
/* $OpenBSD: table.h,v 1.8 2012/02/19 07:52:30 otto Exp $ */ /* $OpenBSD: table.h,v 1.8 2012/02/19 07:52:30 otto Exp $ */
/* $OpenBSD: tree.h,v 1.10 2005/03/28 21:28:22 deraadt Exp $ */ /* $OpenBSD: tree.h,v 1.10 2005/03/28 21:28:22 deraadt Exp $ */
@ -11,7 +11,7 @@
/*- /*-
* Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, * Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
* 2011, 2012, 2013, 2014, 2015 * 2011, 2012, 2013, 2014, 2015
* mirabilos <tg@mirbsd.org> * mirabilos <m@mirbsd.org>
* *
* Provided that these terms and disclaimer and all copyright notices * Provided that these terms and disclaimer and all copyright notices
* are retained or reproduced in an accompanying document, permission * are retained or reproduced in an accompanying document, permission
@ -172,9 +172,9 @@
#endif #endif
#ifdef EXTERN #ifdef EXTERN
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.744 2015/09/06 19:47:00 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/sh.h,v 1.749 2015/10/09 21:36:59 tg Exp $");
#endif #endif
#define MKSH_VERSION "R51 2015/09/06" #define MKSH_VERSION "R51 2015/10/09"
/* arithmetic types: C implementation */ /* arithmetic types: C implementation */
#if !HAVE_CAN_INTTYPES #if !HAVE_CAN_INTTYPES
@ -387,12 +387,10 @@ struct rusage {
#endif #endif
#ifdef __OS2__ #ifdef __OS2__
#define MKSH_PATHSEPE "\\;"
#define MKSH_PATHSEPS ";" #define MKSH_PATHSEPS ";"
#define MKSH_PATHSEPC ';' #define MKSH_PATHSEPC ';'
#define MKSH_UNIXROOT "/@unixroot" #define MKSH_UNIXROOT "/@unixroot"
#else #else
#define MKSH_PATHSEPE ":"
#define MKSH_PATHSEPS ":" #define MKSH_PATHSEPS ":"
#define MKSH_PATHSEPC ':' #define MKSH_PATHSEPC ':'
#define MKSH_UNIXROOT "" #define MKSH_UNIXROOT ""
@ -1028,7 +1026,7 @@ EXTERN Getopt user_opt; /* parsing state for getopts builtin command */
/* This for co-processes */ /* This for co-processes */
/* something that won't (realisticly) wrap */ /* something that won't (realisticly) wrap */
typedef int32_t Coproc_id; typedef int Coproc_id;
struct coproc { struct coproc {
void *job; /* 0 or job of co-process using input pipe */ void *job; /* 0 or job of co-process using input pipe */
@ -1047,7 +1045,7 @@ EXTERN sigset_t sm_default, sm_sigchld;
/* name of called builtin function (used by error functions) */ /* name of called builtin function (used by error functions) */
EXTERN const char *builtin_argv0; EXTERN const char *builtin_argv0;
/* is called builtin SPEC_BI? */ /* is called builtin SPEC_BI? (also KEEPASN, odd use though) */
EXTERN bool builtin_spec; EXTERN bool builtin_spec;
/* current working directory */ /* current working directory */
@ -1072,12 +1070,8 @@ EXTERN mksh_ari_t x_lins E_INIT(24); /* tty lines */
/* Determine the location of the system (common) profile */ /* Determine the location of the system (common) profile */
#ifndef MKSH_DEFAULT_PROFILEDIR #ifndef MKSH_DEFAULT_PROFILEDIR
#if defined(ANDROID)
#define MKSH_DEFAULT_PROFILEDIR "/system/etc"
#else
#define MKSH_DEFAULT_PROFILEDIR MKSH_UNIXROOT "/etc" #define MKSH_DEFAULT_PROFILEDIR MKSH_UNIXROOT "/etc"
#endif #endif
#endif
#define MKSH_SYSTEM_PROFILE MKSH_DEFAULT_PROFILEDIR "/profile" #define MKSH_SYSTEM_PROFILE MKSH_DEFAULT_PROFILEDIR "/profile"
#define MKSH_SUID_PROFILE MKSH_DEFAULT_PROFILEDIR "/suid_profile" #define MKSH_SUID_PROFILE MKSH_DEFAULT_PROFILEDIR "/suid_profile"
@ -1398,7 +1392,7 @@ struct op {
* IO redirection * IO redirection
*/ */
struct ioword { struct ioword {
char *name; /* filename (unused if heredoc) */ char *ioname; /* filename (unused if heredoc) */
char *delim; /* delimiter for <<, <<- */ char *delim; /* delimiter for <<, <<- */
char *heredoc; /* content of heredoc */ char *heredoc; /* content of heredoc */
unsigned short ioflag; /* action (below) */ unsigned short ioflag; /* action (below) */
@ -1634,9 +1628,10 @@ typedef union {
#define VARASN BIT(5) /* check for var=word */ #define VARASN BIT(5) /* check for var=word */
#define ARRAYVAR BIT(6) /* parse x[1 & 2] as one word */ #define ARRAYVAR BIT(6) /* parse x[1 & 2] as one word */
#define ESACONLY BIT(7) /* only accept esac keyword */ #define ESACONLY BIT(7) /* only accept esac keyword */
#define HEREDELIM BIT(8) /* parsing <<,<<- delimiter */ #define CMDWORD BIT(8) /* parsing simple command (alias related) */
#define LQCHAR BIT(9) /* source string contains QCHAR */ #define HEREDELIM BIT(9) /* parsing <<,<<- delimiter */
#define HEREDOC BIT(10) /* parsing a here document body */ #define LQCHAR BIT(10) /* source string contains QCHAR */
#define HEREDOC BIT(11) /* parsing a here document body */
#define HERES 10 /* max number of << in line */ #define HERES 10 /* max number of << in line */
@ -1718,6 +1713,7 @@ int define(const char *, struct op *);
const char *builtin(const char *, int (*)(const char **)); const char *builtin(const char *, int (*)(const char **));
struct tbl *findcom(const char *, int); struct tbl *findcom(const char *, int);
void flushcom(bool); void flushcom(bool);
int search_access(const char *, int);
const char *search_path(const char *, const char *, int, int *); const char *search_path(const char *, const char *, int, int *);
void pr_menu(const char * const *); void pr_menu(const char * const *);
void pr_list(char * const *); void pr_list(char * const *);

16
shf.c
View File

@ -3,7 +3,7 @@
/*- /*-
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011, * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011,
* 2012, 2013, 2015 * 2012, 2013, 2015
* mirabilos <tg@mirbsd.org> * mirabilos <m@mirbsd.org>
* *
* Provided that these terms and disclaimer and all copyright notices * Provided that these terms and disclaimer and all copyright notices
* are retained or reproduced in an accompanying document, permission * are retained or reproduced in an accompanying document, permission
@ -25,7 +25,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/shf.c,v 1.67 2015/09/05 19:19:11 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/shf.c,v 1.68 2015/10/09 15:38:36 tg Exp $");
/* flags to shf_emptybuf() */ /* flags to shf_emptybuf() */
#define EB_READSW 0x01 /* about to switch to reading */ #define EB_READSW 0x01 /* about to switch to reading */
@ -1099,14 +1099,10 @@ cstrerror(int errnum)
switch (errnum) { switch (errnum) {
case 0: case 0:
return ("Undefined error: 0"); return ("Undefined error: 0");
#ifdef EPERM
case EPERM: case EPERM:
return ("Operation not permitted"); return ("Operation not permitted");
#endif
#ifdef ENOENT
case ENOENT: case ENOENT:
return ("No such file or directory"); return ("No such file or directory");
#endif
#ifdef ESRCH #ifdef ESRCH
case ESRCH: case ESRCH:
return ("No such process"); return ("No such process");
@ -1115,22 +1111,18 @@ cstrerror(int errnum)
case E2BIG: case E2BIG:
return ("Argument list too long"); return ("Argument list too long");
#endif #endif
#ifdef ENOEXEC
case ENOEXEC: case ENOEXEC:
return ("Exec format error"); return ("Exec format error");
#endif case EBADF:
return ("Bad file descriptor");
#ifdef ENOMEM #ifdef ENOMEM
case ENOMEM: case ENOMEM:
return ("Cannot allocate memory"); return ("Cannot allocate memory");
#endif #endif
#ifdef EACCES
case EACCES: case EACCES:
return ("Permission denied"); return ("Permission denied");
#endif
#ifdef ENOTDIR
case ENOTDIR: case ENOTDIR:
return ("Not a directory"); return ("Not a directory");
#endif
#ifdef EINVAL #ifdef EINVAL
case EINVAL: case EINVAL:
return ("Invalid argument"); return ("Invalid argument");

14
syn.c
View File

@ -3,7 +3,7 @@
/*- /*-
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009,
* 2011, 2012, 2013, 2014, 2015 * 2011, 2012, 2013, 2014, 2015
* mirabilos <tg@mirbsd.org> * mirabilos <m@mirbsd.org>
* *
* Provided that these terms and disclaimer and all copyright notices * Provided that these terms and disclaimer and all copyright notices
* are retained or reproduced in an accompanying document, permission * are retained or reproduced in an accompanying document, permission
@ -23,7 +23,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.104 2015/09/06 19:47:01 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/syn.c,v 1.106 2015/10/09 19:29:50 tg Exp $");
struct nesting_state { struct nesting_state {
int start_token; /* token than began nesting (eg, FOR) */ int start_token; /* token than began nesting (eg, FOR) */
@ -210,18 +210,22 @@ synio(int cf)
yyerror("too many %ss\n", "<<"); yyerror("too many %ss\n", "<<");
*herep++ = iop; *herep++ = iop;
} else } else
iop->name = yylval.cp; iop->ioname = yylval.cp;
if (iop->ioflag & IOBASH) { if (iop->ioflag & IOBASH) {
char *cp; char *cp;
nextiop = alloc(sizeof(*iop), ATEMP); nextiop = alloc(sizeof(*iop), ATEMP);
nextiop->name = cp = alloc(5, ATEMP); #ifdef MKSH_CONSERVATIVE_FDS
nextiop->ioname = cp = alloc(3, ATEMP);
#else
nextiop->ioname = cp = alloc(5, ATEMP);
if (iop->unit > 9) { if (iop->unit > 9) {
*cp++ = CHAR; *cp++ = CHAR;
*cp++ = digits_lc[iop->unit / 10]; *cp++ = digits_lc[iop->unit / 10];
} }
#endif
*cp++ = CHAR; *cp++ = CHAR;
*cp++ = digits_lc[iop->unit % 10]; *cp++ = digits_lc[iop->unit % 10];
*cp = EOS; *cp = EOS;
@ -294,7 +298,7 @@ get_command(int cf)
t->lineno = source->line; t->lineno = source->line;
while (/* CONSTCOND */ 1) { while (/* CONSTCOND */ 1) {
cf = (t->u.evalflags ? ARRAYVAR : 0) | cf = (t->u.evalflags ? ARRAYVAR : 0) |
(XPsize(args) == 0 ? sALIAS|VARASN : 0); (XPsize(args) == 0 ? sALIAS|VARASN : CMDWORD);
switch (tpeek(cf)) { switch (tpeek(cf)) {
case REDIR: case REDIR:
while ((iop = synio(cf)) != NULL) { while ((iop = synio(cf)) != NULL) {

22
tree.c
View File

@ -3,7 +3,7 @@
/*- /*-
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
* 2011, 2012, 2013, 2015 * 2011, 2012, 2013, 2015
* mirabilos <tg@mirbsd.org> * mirabilos <m@mirbsd.org>
* *
* Provided that these terms and disclaimer and all copyright notices * Provided that these terms and disclaimer and all copyright notices
* are retained or reproduced in an accompanying document, permission * are retained or reproduced in an accompanying document, permission
@ -23,7 +23,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/tree.c,v 1.77 2015/09/06 19:47:01 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/tree.c,v 1.78 2015/10/09 19:29:50 tg Exp $");
#define INDENT 8 #define INDENT 8
@ -286,11 +286,11 @@ pioact(struct shf *shf, struct ioword *iop)
if (type == IOHERE) { if (type == IOHERE) {
if (iop->delim && !(iop->ioflag & IONDELIM)) if (iop->delim && !(iop->ioflag & IONDELIM))
wdvarput(shf, iop->delim, 0, WDS_TPUTS); wdvarput(shf, iop->delim, 0, WDS_TPUTS);
} else if (iop->name) { } else if (iop->ioname) {
if (flag & IONAMEXP) if (flag & IONAMEXP)
print_value_quoted(shf, iop->name); print_value_quoted(shf, iop->ioname);
else else
wdvarput(shf, iop->name, 0, WDS_TPUTS); wdvarput(shf, iop->ioname, 0, WDS_TPUTS);
} }
shf_putc(' ', shf); shf_putc(' ', shf);
prevent_semicolon = false; prevent_semicolon = false;
@ -672,8 +672,8 @@ iocopy(struct ioword **iow, Area *ap)
q = alloc(sizeof(struct ioword), ap); q = alloc(sizeof(struct ioword), ap);
ior[i] = q; ior[i] = q;
*q = *p; *q = *p;
if (p->name != NULL) if (p->ioname != NULL)
q->name = wdcopy(p->name, ap); q->ioname = wdcopy(p->ioname, ap);
if (p->delim != NULL) if (p->delim != NULL)
q->delim = wdcopy(p->delim, ap); q->delim = wdcopy(p->delim, ap);
if (p->heredoc != NULL) if (p->heredoc != NULL)
@ -730,7 +730,7 @@ iofree(struct ioword **iow, Area *ap)
iop = iow; iop = iow;
while ((p = *iop++) != NULL) { while ((p = *iop++) != NULL) {
afree(p->name, ap); afree(p->ioname, ap);
afree(p->delim, ap); afree(p->delim, ap);
afree(p->heredoc, ap); afree(p->heredoc, ap);
afree(p, ap); afree(p, ap);
@ -936,13 +936,13 @@ dumpioact(struct shf *shf, struct op *t)
dumpwdvar(shf, iop->delim); dumpwdvar(shf, iop->delim);
shf_putc('>', shf); shf_putc('>', shf);
} }
if (iop->name) { if (iop->ioname) {
if (iop->ioflag & IONAMEXP) { if (iop->ioflag & IONAMEXP) {
shf_puts(",name=", shf); shf_puts(",name=", shf);
print_value_quoted(shf, iop->name); print_value_quoted(shf, iop->ioname);
} else { } else {
shf_puts(",name<", shf); shf_puts(",name<", shf);
dumpwdvar(shf, iop->name); dumpwdvar(shf, iop->ioname);
shf_putc('>', shf); shf_putc('>', shf);
} }
} }

6
var.c
View File

@ -1,9 +1,9 @@
/* $OpenBSD: var.c,v 1.43 2015/09/01 13:12:31 tedu Exp $ */ /* $OpenBSD: var.c,v 1.44 2015/09/10 11:37:42 jca Exp $ */
/*- /*-
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
* 2011, 2012, 2013, 2014, 2015 * 2011, 2012, 2013, 2014, 2015
* mirabilos <tg@mirbsd.org> * mirabilos <m@mirbsd.org>
* *
* Provided that these terms and disclaimer and all copyright notices * Provided that these terms and disclaimer and all copyright notices
* are retained or reproduced in an accompanying document, permission * are retained or reproduced in an accompanying document, permission
@ -28,7 +28,7 @@
#include <sys/sysctl.h> #include <sys/sysctl.h>
#endif #endif
__RCSID("$MirOS: src/bin/mksh/var.c,v 1.194 2015/09/05 19:19:12 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/var.c,v 1.195 2015/10/09 16:11:19 tg Exp $");
/*- /*-
* Variables * Variables