Merge tag 'mksh-R52c'
This commit is contained in:
commit
68f6e899ef
4
Build.sh
4
Build.sh
@ -1,5 +1,5 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.696 2016/01/21 18:24:33 tg Exp $'
|
srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.697 2016/03/04 18:28:39 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, 2016
|
# 2011, 2012, 2013, 2014, 2015, 2016
|
||||||
@ -2347,7 +2347,7 @@ addsrcs '!' HAVE_STRLCPY strlcpy.c
|
|||||||
addsrcs USE_PRINTF_BUILTIN printf.c
|
addsrcs USE_PRINTF_BUILTIN printf.c
|
||||||
test 1 = "$USE_PRINTF_BUILTIN" && add_cppflags -DMKSH_PRINTF_BUILTIN
|
test 1 = "$USE_PRINTF_BUILTIN" && add_cppflags -DMKSH_PRINTF_BUILTIN
|
||||||
test 1 = "$HAVE_CAN_VERB" && CFLAGS="$CFLAGS -verbose"
|
test 1 = "$HAVE_CAN_VERB" && CFLAGS="$CFLAGS -verbose"
|
||||||
add_cppflags -DMKSH_BUILD_R=522
|
add_cppflags -DMKSH_BUILD_R=523
|
||||||
|
|
||||||
$e $bi$me: Finished configuration testing, now producing output.$ao
|
$e $bi$me: Finished configuration testing, now producing output.$ao
|
||||||
|
|
||||||
|
188
Makefile
188
Makefile
@ -1,188 +0,0 @@
|
|||||||
# $MirOS: src/bin/mksh/Makefile,v 1.146 2016/01/21 18:24:34 tg Exp $
|
|
||||||
#-
|
|
||||||
# Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
|
||||||
# 2011, 2012, 2013, 2014, 2015, 2016
|
|
||||||
# mirabilos <m@mirbsd.org>
|
|
||||||
#
|
|
||||||
# Provided that these terms and disclaimer and all copyright notices
|
|
||||||
# are retained or reproduced in an accompanying document, permission
|
|
||||||
# is granted to deal in this work without restriction, including un-
|
|
||||||
# limited rights to use, publicly perform, distribute, sell, modify,
|
|
||||||
# merge, give away, or sublicence.
|
|
||||||
#
|
|
||||||
# This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to
|
|
||||||
# the utmost extent permitted by applicable law, neither express nor
|
|
||||||
# implied; without malicious intent or gross negligence. In no event
|
|
||||||
# may a licensor, author or contributor be held liable for indirect,
|
|
||||||
# direct, other damage, loss, or other issues arising in any way out
|
|
||||||
# of dealing in the work, even if advised of the possibility of such
|
|
||||||
# damage or existence of a defect, except proven that it results out
|
|
||||||
# of said person's immediate fault when using the work as intended.
|
|
||||||
|
|
||||||
.ifmake d
|
|
||||||
__CRAZY= Yes
|
|
||||||
MKC_DEBG= cpp
|
|
||||||
DEBUGFILE= Yes
|
|
||||||
NOMAN= Yes
|
|
||||||
.endif
|
|
||||||
|
|
||||||
.include <bsd.own.mk>
|
|
||||||
|
|
||||||
SRCDIR= ${.CURDIR}
|
|
||||||
|
|
||||||
PROG= mksh
|
|
||||||
SRCS= edit.c eval.c exec.c expr.c funcs.c histrap.c jobs.c \
|
|
||||||
lalloc.c lex.c main.c misc.c shf.c syn.c tree.c var.c
|
|
||||||
.if !make(test-build)
|
|
||||||
CPPFLAGS+= -DMKSH_ASSUME_UTF8 -DMKSH_DISABLE_DEPRECATED \
|
|
||||||
-DHAVE_ATTRIBUTE_BOUNDED=1 -DHAVE_ATTRIBUTE_FORMAT=1 \
|
|
||||||
-DHAVE_ATTRIBUTE_NORETURN=1 -DHAVE_ATTRIBUTE_PURE=1 \
|
|
||||||
-DHAVE_ATTRIBUTE_UNUSED=1 -DHAVE_ATTRIBUTE_USED=1 \
|
|
||||||
-DHAVE_SYS_TIME_H=1 -DHAVE_TIME_H=1 -DHAVE_BOTH_TIME_H=1 \
|
|
||||||
-DHAVE_SYS_BSDTYPES_H=0 -DHAVE_SYS_FILE_H=1 \
|
|
||||||
-DHAVE_SYS_MKDEV_H=0 -DHAVE_SYS_MMAN_H=1 -DHAVE_SYS_PARAM_H=1 \
|
|
||||||
-DHAVE_SYS_RESOURCE_H=1 -DHAVE_SYS_SELECT_H=1 \
|
|
||||||
-DHAVE_SYS_SYSMACROS_H=0 -DHAVE_BSTRING_H=0 -DHAVE_GRP_H=1 \
|
|
||||||
-DHAVE_IO_H=0 -DHAVE_LIBGEN_H=1 -DHAVE_LIBUTIL_H=0 \
|
|
||||||
-DHAVE_PATHS_H=1 -DHAVE_STDINT_H=1 -DHAVE_STRINGS_H=1 \
|
|
||||||
-DHAVE_TERMIOS_H=1 -DHAVE_ULIMIT_H=0 -DHAVE_VALUES_H=0 \
|
|
||||||
-DHAVE_CAN_INTTYPES=1 -DHAVE_CAN_UCBINTS=1 \
|
|
||||||
-DHAVE_CAN_INT8TYPE=1 -DHAVE_CAN_UCBINT8=1 -DHAVE_RLIM_T=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_GETRUSAGE=1 -DHAVE_GETSID=1 -DHAVE_GETTIMEOFDAY=1 \
|
|
||||||
-DHAVE_KILLPG=1 -DHAVE_MEMMOVE=1 -DHAVE_MKNOD=0 -DHAVE_MMAP=1 \
|
|
||||||
-DHAVE_NICE=1 -DHAVE_REVOKE=1 -DHAVE_SETLOCALE_CTYPE=0 \
|
|
||||||
-DHAVE_LANGINFO_CODESET=0 -DHAVE_SELECT=1 -DHAVE_SETRESUGID=1 \
|
|
||||||
-DHAVE_SETGROUPS=1 -DHAVE_STRERROR=0 -DHAVE_STRSIGNAL=0 \
|
|
||||||
-DHAVE_STRLCPY=1 -DHAVE_FLOCK_DECL=1 -DHAVE_REVOKE_DECL=1 \
|
|
||||||
-DHAVE_SYS_ERRLIST_DECL=1 -DHAVE_SYS_SIGLIST_DECL=1 \
|
|
||||||
-DHAVE_PERSISTENT_HISTORY=1 -DMKSH_BUILD_R=522
|
|
||||||
CPPFLAGS+= -D${${PROG:L}_tf:C/(Mir${MAN:E}{0,1}){2}/4/:S/x/mksh_BUILD/:U}
|
|
||||||
CPPFLAGS+= -I.
|
|
||||||
COPTS+= -std=c89 -Wall
|
|
||||||
.endif
|
|
||||||
|
|
||||||
USE_PRINTF_BUILTIN?= 0
|
|
||||||
.if ${USE_PRINTF_BUILTIN} == 1
|
|
||||||
.PATH: ${BSDSRCDIR}/usr.bin/printf
|
|
||||||
SRCS+= printf.c
|
|
||||||
CPPFLAGS+= -DMKSH_PRINTF_BUILTIN
|
|
||||||
.endif
|
|
||||||
|
|
||||||
DEBUGFILE?= No
|
|
||||||
.if ${DEBUGFILE:L} == "yes"
|
|
||||||
CPPFLAGS+= -DDF=mksh_debugtofile
|
|
||||||
.endif
|
|
||||||
|
|
||||||
MANLINKS= [ false pwd sh sleep test true
|
|
||||||
BINLINKS= ${MANLINKS} echo domainname kill
|
|
||||||
.for _i in ${BINLINKS}
|
|
||||||
LINKS+= ${BINDIR}/${PROG} ${BINDIR}/${_i}
|
|
||||||
.endfor
|
|
||||||
.for _i in ${MANLINKS}
|
|
||||||
MLINKS+= ${PROG}.1 ${_i}.1
|
|
||||||
.endfor
|
|
||||||
|
|
||||||
OPTGENS!= cd ${SRCDIR:Q} && echo *.opt
|
|
||||||
.for _i in ${OPTGENS}
|
|
||||||
GENERATED+= ${_i:R}.gen
|
|
||||||
${_i:R}.gen: ${_i} ${SRCDIR}/Build.sh
|
|
||||||
/bin/sh ${SRCDIR:Q}/Build.sh -G ${SRCDIR:Q}/${_i:Q}
|
|
||||||
.endfor
|
|
||||||
CLEANFILES+= ${GENERATED}
|
|
||||||
|
|
||||||
${PROG} beforedepend: ${GENERATED}
|
|
||||||
|
|
||||||
regress: ${PROG} check.pl check.t
|
|
||||||
-rm -rf regress-dir
|
|
||||||
mkdir -p regress-dir
|
|
||||||
echo export FNORD=666 >regress-dir/.mkshrc
|
|
||||||
HOME=$$(realpath regress-dir) perl ${SRCDIR}/check.pl \
|
|
||||||
-s ${SRCDIR}/check.t -v -p ./${PROG} \
|
|
||||||
-C shell:legacy-no,int:32,fastbox
|
|
||||||
|
|
||||||
test-build: .PHONY
|
|
||||||
-rm -rf build-dir
|
|
||||||
mkdir -p build-dir
|
|
||||||
.if ${USE_PRINTF_BUILTIN} == 1
|
|
||||||
cp ${BSDSRCDIR}/usr.bin/printf/printf.c build-dir/
|
|
||||||
.endif
|
|
||||||
cd build-dir; env CC=${CC:Q} CFLAGS=${CFLAGS:M*:Q} \
|
|
||||||
CPPFLAGS=${CPPFLAGS:M*:Q} LDFLAGS=${LDFLAGS:M*:Q} \
|
|
||||||
LIBS= NOWARN=-Wno-error TARGET_OS= CPP= /bin/sh \
|
|
||||||
${SRCDIR}/Build.sh -Q -r ${_TBF} && ./test.sh -v -f
|
|
||||||
|
|
||||||
CLEANFILES+= lksh.cat1
|
|
||||||
test-build-lksh: .PHONY
|
|
||||||
cd ${SRCDIR} && exec ${MAKE} lksh.cat1 test-build _TBF=-L
|
|
||||||
|
|
||||||
bothmans: .PHONY
|
|
||||||
cd ${SRCDIR} && exec ${MAKE} MAN='lksh.1 mksh.1' __MANALL
|
|
||||||
|
|
||||||
cleandir: clean-extra
|
|
||||||
|
|
||||||
clean-extra: .PHONY
|
|
||||||
-rm -rf build-dir regress-dir printf.o printf.ln
|
|
||||||
|
|
||||||
mksh_tf=xMakefile${OStype:S/${MACHINE_OS}/1/1g}${OSNAME}
|
|
||||||
distribution:
|
|
||||||
sed 's!\$$I''d\([:$$]\)!$$M''irSecuCron\1!g' \
|
|
||||||
${SRCDIR}/dot.mkshrc >${DESTDIR}/etc/skel/.mkshrc
|
|
||||||
chown ${BINOWN}:${CONFGRP} ${DESTDIR}/etc/skel/.mkshrc
|
|
||||||
chmod 0644 ${DESTDIR}/etc/skel/.mkshrc
|
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
|
||||||
|
|
||||||
.ifmake cats
|
|
||||||
V_GROFF!= pkg_info -e 'groff-*'
|
|
||||||
V_GHOSTSCRIPT!= pkg_info -e 'ghostscript-*'
|
|
||||||
. if empty(V_GROFF) || empty(V_GHOSTSCRIPT)
|
|
||||||
. error empty V_GROFF=${V_GROFF} or V_GHOSTSCRIPT=${V_GHOSTSCRIPT}
|
|
||||||
. endif
|
|
||||||
.endif
|
|
||||||
|
|
||||||
CLEANFILES+= ${MANALL:S/.cat/.ps/} ${MAN:S/$/.pdf/} ${MANALL:S/$/.gz/}
|
|
||||||
CLEANFILES+= ${MAN:S/$/.htm/} ${MAN:S/$/.htm.gz/}
|
|
||||||
CLEANFILES+= ${MAN:S/$/.txt/} ${MAN:S/$/.txt.gz/}
|
|
||||||
CATS_KW= mksh, ksh, sh
|
|
||||||
CATS_TITLE_mksh_1=mksh - The MirBSD Korn Shell
|
|
||||||
cats: ${MANALL} ${MANALL:S/.cat/.ps/}
|
|
||||||
.if "${MANALL:Nlksh.cat1:Nmksh.cat1}" != ""
|
|
||||||
. error Adjust here.
|
|
||||||
.endif
|
|
||||||
.for _m _n in mksh 1
|
|
||||||
x=$$(ident ${SRCDIR:Q}/${_m}.${_n} | \
|
|
||||||
awk '/Mir''OS:/ { print $$4$$5; }' | \
|
|
||||||
tr -dc 0-9); (( $${#x} == 14 )) || exit 1; exec \
|
|
||||||
${MKSH} ${BSDSRCDIR:Q}/contrib/hosted/tg/ps2pdfmir -c \
|
|
||||||
-o ${_m}.${_n}.pdf '[' /Author '(The MirOS Project)' \
|
|
||||||
/Title '('${CATS_TITLE_${_m}_${_n}:Q}')' \
|
|
||||||
/Subject '(BSD Reference Manual)' /ModDate "(D:$$x)" \
|
|
||||||
/Creator '(GNU groff version ${V_GROFF:S/groff-//} \(MirPorts\))' \
|
|
||||||
/Producer '(Artifex Ghostscript ${V_GHOSTSCRIPT:S/ghostscript-//:S/-artifex//} \(MirPorts\))' \
|
|
||||||
/Keywords '('${CATS_KW:Q}')' /DOCINFO pdfmark \
|
|
||||||
-f ${_m}.ps${_n}
|
|
||||||
.endfor
|
|
||||||
set -e; . ${BSDSRCDIR:Q}/scripts/roff2htm; set_target_absolute; \
|
|
||||||
for m in ${MANALL}; do \
|
|
||||||
bn=$${m%.*}; ext=$${m##*.cat}; \
|
|
||||||
[[ $$bn != $$m ]]; [[ $$ext != $$m ]]; \
|
|
||||||
gzip -n9 <"$$m" >"$$m.gz"; \
|
|
||||||
col -bx <"$$m" >"$$bn.$$ext.txt"; \
|
|
||||||
rm -f "$$bn.$$ext.txt.gz"; gzip -n9 "$$bn.$$ext.txt"; \
|
|
||||||
do_conversion_verbose "$$bn" "$$ext" "$$m" "$$bn.$$ext.htm"; \
|
|
||||||
rm -f "$$bn.$$ext.htm.gz"; gzip -n9 "$$bn.$$ext.htm"; \
|
|
||||||
done
|
|
||||||
|
|
||||||
.ifmake d
|
|
||||||
. ifmake obj || depend || all || install || regress || test-build
|
|
||||||
d:
|
|
||||||
. else
|
|
||||||
d: all
|
|
||||||
. endif
|
|
||||||
.endif
|
|
||||||
|
|
||||||
dr:
|
|
||||||
p=$$(realpath ${PROG:Q}) && cd ${SRCDIR:Q} && exec ${MKSH} \
|
|
||||||
${BSDSRCDIR:Q}/contrib/hosted/tg/sdmksh "$$p"
|
|
103
check.t
103
check.t
@ -1,4 +1,4 @@
|
|||||||
# $MirOS: src/bin/mksh/check.t,v 1.724 2016/02/24 01:47:30 tg Exp $
|
# $MirOS: src/bin/mksh/check.t,v 1.727 2016/03/04 14:26:09 tg Exp $
|
||||||
# -*- mode: sh -*-
|
# -*- mode: sh -*-
|
||||||
#-
|
#-
|
||||||
# Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
# 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
|
# (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 R52 2016/02/23
|
@(#)MIRBSD KSH R52 2016/03/04
|
||||||
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 R52 2016/02/23
|
@(#)LEGACY KSH R52 2016/03/04
|
||||||
description:
|
description:
|
||||||
Check version of legacy shell.
|
Check version of legacy shell.
|
||||||
stdin:
|
stdin:
|
||||||
@ -2249,7 +2249,7 @@ expected-stdout:
|
|||||||
hi
|
hi
|
||||||
there
|
there
|
||||||
---
|
---
|
||||||
name: heredoc-4
|
name: heredoc-4a
|
||||||
description:
|
description:
|
||||||
Check that an error occurs if the heredoc-delimiter is missing.
|
Check that an error occurs if the heredoc-delimiter is missing.
|
||||||
stdin: !
|
stdin: !
|
||||||
@ -2259,6 +2259,34 @@ stdin: !
|
|||||||
expected-exit: e > 0
|
expected-exit: e > 0
|
||||||
expected-stderr-pattern: /.*/
|
expected-stderr-pattern: /.*/
|
||||||
---
|
---
|
||||||
|
name: heredoc-4an
|
||||||
|
description:
|
||||||
|
Check that an error occurs if the heredoc-delimiter is missing.
|
||||||
|
arguments: !-n!
|
||||||
|
stdin: !
|
||||||
|
cat << EOF
|
||||||
|
hi
|
||||||
|
there
|
||||||
|
expected-exit: e > 0
|
||||||
|
expected-stderr-pattern: /.*/
|
||||||
|
---
|
||||||
|
name: heredoc-4b
|
||||||
|
description:
|
||||||
|
Check that an error occurs if the heredoc is missing.
|
||||||
|
stdin: !
|
||||||
|
cat << EOF
|
||||||
|
expected-exit: e > 0
|
||||||
|
expected-stderr-pattern: /.*/
|
||||||
|
---
|
||||||
|
name: heredoc-4bn
|
||||||
|
description:
|
||||||
|
Check that an error occurs if the heredoc is missing.
|
||||||
|
arguments: !-n!
|
||||||
|
stdin: !
|
||||||
|
cat << EOF
|
||||||
|
expected-exit: e > 0
|
||||||
|
expected-stderr-pattern: /.*/
|
||||||
|
---
|
||||||
name: heredoc-5
|
name: heredoc-5
|
||||||
description:
|
description:
|
||||||
Check that backslash quotes a $, ` and \ and kills a \newline
|
Check that backslash quotes a $, ` and \ and kills a \newline
|
||||||
@ -2657,6 +2685,32 @@ stdin:
|
|||||||
expected-stdout:
|
expected-stdout:
|
||||||
= these parens \( ) are a problem =
|
= these parens \( ) are a problem =
|
||||||
---
|
---
|
||||||
|
name: heredoc-comsub-5
|
||||||
|
description:
|
||||||
|
Check heredoc and COMSUB mixture in input
|
||||||
|
stdin:
|
||||||
|
prefix() { sed -e "s/^/$1:/"; }
|
||||||
|
XXX() { echo x-en; }
|
||||||
|
YYY() { echo y-es; }
|
||||||
|
|
||||||
|
prefix A <<XXX && echo "$(prefix B <<XXX
|
||||||
|
echo line 1
|
||||||
|
XXX
|
||||||
|
echo line 2)" && prefix C <<YYY
|
||||||
|
echo line 3
|
||||||
|
XXX
|
||||||
|
echo line 4)"
|
||||||
|
echo line 5
|
||||||
|
YYY
|
||||||
|
XXX
|
||||||
|
expected-stdout:
|
||||||
|
A:echo line 3
|
||||||
|
B:echo line 1
|
||||||
|
line 2
|
||||||
|
C:echo line 4)"
|
||||||
|
C:echo line 5
|
||||||
|
x-en
|
||||||
|
---
|
||||||
name: heredoc-subshell-1
|
name: heredoc-subshell-1
|
||||||
description:
|
description:
|
||||||
Tests for here documents in subshells, taken from Austin ML
|
Tests for here documents in subshells, taken from Austin ML
|
||||||
@ -6578,6 +6632,37 @@ stdin:
|
|||||||
expected-exit: 1
|
expected-exit: 1
|
||||||
expected-stderr-pattern: !/not set/
|
expected-stderr-pattern: !/not set/
|
||||||
---
|
---
|
||||||
|
name: xxx-param-subst-qmark-namespec
|
||||||
|
description:
|
||||||
|
Check special names are output correctly
|
||||||
|
stdin:
|
||||||
|
doit() {
|
||||||
|
"$__progname" -c "$@" >o1 2>o2
|
||||||
|
rv=$?
|
||||||
|
echo RETVAL: $rv
|
||||||
|
sed -e "s^${__progname%.exe}\.*e*x*e*: PROG: " -e 's/^/STDOUT: /g' <o1
|
||||||
|
sed -e "s^${__progname%.exe}\.*e*x*e*: PROG: " -e 's/^/STDERR: /g' <o2
|
||||||
|
}
|
||||||
|
doit 'echo ${1x}'
|
||||||
|
doit 'echo "${1x}"'
|
||||||
|
doit 'echo ${1?}'
|
||||||
|
doit 'echo ${19?}'
|
||||||
|
doit 'echo ${!:?}'
|
||||||
|
doit -u 'echo ${*:?}' foo ""
|
||||||
|
expected-stdout:
|
||||||
|
RETVAL: 1
|
||||||
|
STDERR: PROG: ${1x}: bad substitution
|
||||||
|
RETVAL: 1
|
||||||
|
STDERR: PROG: ${1x}: bad substitution
|
||||||
|
RETVAL: 1
|
||||||
|
STDERR: PROG: 1: parameter null or not set
|
||||||
|
RETVAL: 1
|
||||||
|
STDERR: PROG: 19: parameter null or not set
|
||||||
|
RETVAL: 1
|
||||||
|
STDERR: PROG: !: parameter null or not set
|
||||||
|
RETVAL: 1
|
||||||
|
STDERR: foo: ${*:?}: bad substitution
|
||||||
|
---
|
||||||
name: xxx-param-_-1
|
name: xxx-param-_-1
|
||||||
# fails due to weirdness of execv stuff
|
# fails due to weirdness of execv stuff
|
||||||
category: !os:uwin-nt
|
category: !os:uwin-nt
|
||||||
@ -12111,6 +12196,14 @@ expected-stdout:
|
|||||||
after 0='swc' 1='二' 2=''
|
after 0='swc' 1='二' 2=''
|
||||||
= done
|
= done
|
||||||
---
|
---
|
||||||
|
name: command-path
|
||||||
|
description:
|
||||||
|
Check 'command -p' is not 'whence -p'
|
||||||
|
stdin:
|
||||||
|
command -pv if
|
||||||
|
expected-stdout:
|
||||||
|
if
|
||||||
|
---
|
||||||
name: duffs-device
|
name: duffs-device
|
||||||
description:
|
description:
|
||||||
Check that the compiler did not optimise-break them
|
Check that the compiler did not optimise-break them
|
||||||
@ -12183,7 +12276,7 @@ stdin:
|
|||||||
Copyright (C) 2002 Free Software Foundation, Inc.'
|
Copyright (C) 2002 Free Software Foundation, Inc.'
|
||||||
EOF
|
EOF
|
||||||
chmod +x bash
|
chmod +x bash
|
||||||
"$__progname" -xc 'foo=$(./bash --version 2>&1 | sed 1q); echo "=$foo="'
|
"$__progname" -xc 'foo=$(./bash --version 2>&1 | sed q); echo "=$foo="'
|
||||||
expected-stdout:
|
expected-stdout:
|
||||||
=GNU bash, version 2.05b.0(1)-release (i386-ecce-mirbsd10)=
|
=GNU bash, version 2.05b.0(1)-release (i386-ecce-mirbsd10)=
|
||||||
expected-stderr-pattern:
|
expected-stderr-pattern:
|
||||||
|
6
edit.c
6
edit.c
@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
#ifndef MKSH_NO_CMDLINE_EDITING
|
#ifndef MKSH_NO_CMDLINE_EDITING
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.293 2016/01/21 18:24:37 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.294 2016/03/04 14:26:12 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
|
||||||
@ -4601,8 +4601,8 @@ vi_cmd(int argcnt, const char *cmd)
|
|||||||
static int
|
static int
|
||||||
domove(int argcnt, const char *cmd, int sub)
|
domove(int argcnt, const char *cmd, int sub)
|
||||||
{
|
{
|
||||||
int bcount, i = 0, t;
|
int ncursor = 0, i = 0, t;
|
||||||
int ncursor = 0;
|
unsigned int bcount;
|
||||||
|
|
||||||
switch (*cmd) {
|
switch (*cmd) {
|
||||||
case 'b':
|
case 'b':
|
||||||
|
12
eval.c
12
eval.c
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
#include "sh.h"
|
#include "sh.h"
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.182 2016/02/24 01:47:32 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.185 2016/02/26 19:05:21 tg Exp $");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* string expansion
|
* string expansion
|
||||||
@ -375,8 +375,9 @@ expand(
|
|||||||
unwind_substsyn:
|
unwind_substsyn:
|
||||||
/* restore sp */
|
/* restore sp */
|
||||||
sp = varname - 2;
|
sp = varname - 2;
|
||||||
end = (beg = wdcopy(sp, ATEMP)) +
|
beg = wdcopy(sp, ATEMP);
|
||||||
(wdscan(sp, CSUBST) - sp);
|
end = (wdscan(cstrchr(sp, '\0') + 1,
|
||||||
|
CSUBST) - sp) + beg;
|
||||||
/* ({) the } or x is already skipped */
|
/* ({) the } or x is already skipped */
|
||||||
if (end < wdscan(beg, EOS))
|
if (end < wdscan(beg, EOS))
|
||||||
*end = EOS;
|
*end = EOS;
|
||||||
@ -403,8 +404,8 @@ expand(
|
|||||||
st->stype = stype;
|
st->stype = stype;
|
||||||
st->base = Xsavepos(ds, dp);
|
st->base = Xsavepos(ds, dp);
|
||||||
st->f = f;
|
st->f = f;
|
||||||
if (x.var == &vtemp) {
|
if (x.var == vtemp) {
|
||||||
st->var = tempvar();
|
st->var = tempvar(vtemp->name);
|
||||||
st->var->flag &= ~INTEGER;
|
st->var->flag &= ~INTEGER;
|
||||||
/* can't fail here */
|
/* can't fail here */
|
||||||
setstr(st->var,
|
setstr(st->var,
|
||||||
@ -1192,6 +1193,7 @@ varsub(Expand *xp, const char *sp, const char *word,
|
|||||||
/* can't trim a vector (yet) */
|
/* can't trim a vector (yet) */
|
||||||
case '%':
|
case '%':
|
||||||
case '#':
|
case '#':
|
||||||
|
case '?':
|
||||||
case '0':
|
case '0':
|
||||||
case '/':
|
case '/':
|
||||||
case 0x100 | '#':
|
case 0x100 | '#':
|
||||||
|
9
exec.c
9
exec.c
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
#include "sh.h"
|
#include "sh.h"
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.171 2016/01/21 18:24:39 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.172 2016/03/01 18:30:04 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"
|
||||||
@ -1623,13 +1623,6 @@ herein(struct ioword *iop, char **resbuf)
|
|||||||
struct temp *h;
|
struct temp *h;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* ksh -c 'cat <<EOF' can cause this... */
|
|
||||||
if (iop->heredoc == NULL && !(iop->ioflag & IOHERESTR)) {
|
|
||||||
warningf(true, Tmissinghere);
|
|
||||||
/* special to iosetup(): don't print error */
|
|
||||||
return (-2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* lexer substitution flags */
|
/* lexer substitution flags */
|
||||||
i = (iop->ioflag & IOEVAL) ? (ONEWORD | HEREDOC) : 0;
|
i = (iop->ioflag & IOEVAL) ? (ONEWORD | HEREDOC) : 0;
|
||||||
|
|
||||||
|
23
expr.c
23
expr.c
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
#include "sh.h"
|
#include "sh.h"
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/expr.c,v 1.81 2016/01/14 21:17:50 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/expr.c,v 1.83 2016/03/01 18:29:38 tg Exp $");
|
||||||
|
|
||||||
/* the order of these enums is constrained by the order of opinfo[] */
|
/* the order of these enums is constrained by the order of opinfo[] */
|
||||||
enum token {
|
enum token {
|
||||||
@ -227,7 +227,7 @@ v_evaluate(struct tbl *vp, const char *expr, volatile int error_ok,
|
|||||||
exprtoken(es);
|
exprtoken(es);
|
||||||
if (es->tok == END) {
|
if (es->tok == END) {
|
||||||
es->tok = LIT;
|
es->tok = LIT;
|
||||||
es->val = tempvar();
|
es->val = tempvar("");
|
||||||
}
|
}
|
||||||
v = intvar(es, evalexpr(es, MAX_PREC));
|
v = intvar(es, evalexpr(es, MAX_PREC));
|
||||||
|
|
||||||
@ -649,7 +649,7 @@ exprtoken(Expr_state *es)
|
|||||||
cp += len;
|
cp += len;
|
||||||
}
|
}
|
||||||
if (es->noassign) {
|
if (es->noassign) {
|
||||||
es->val = tempvar();
|
es->val = tempvar("");
|
||||||
es->val->flag |= EXPRLVALUE;
|
es->val->flag |= EXPRLVALUE;
|
||||||
} else {
|
} else {
|
||||||
strndupx(tvar, es->tokp, cp - es->tokp, ATEMP);
|
strndupx(tvar, es->tokp, cp - es->tokp, ATEMP);
|
||||||
@ -665,7 +665,10 @@ exprtoken(Expr_state *es)
|
|||||||
goto process_tvar;
|
goto process_tvar;
|
||||||
#ifndef MKSH_SMALL
|
#ifndef MKSH_SMALL
|
||||||
} else if (c == '\'') {
|
} else if (c == '\'') {
|
||||||
++cp;
|
if (*++cp == '\0') {
|
||||||
|
es->tok = END;
|
||||||
|
evalerr(es, ET_UNEXPECTED, NULL);
|
||||||
|
}
|
||||||
cp += utf_ptradj(cp);
|
cp += utf_ptradj(cp);
|
||||||
if (*cp++ != '\'')
|
if (*cp++ != '\'')
|
||||||
evalerr(es, ET_STR,
|
evalerr(es, ET_STR,
|
||||||
@ -684,7 +687,7 @@ exprtoken(Expr_state *es)
|
|||||||
c = *cp++;
|
c = *cp++;
|
||||||
strndupx(tvar, es->tokp, --cp - es->tokp, ATEMP);
|
strndupx(tvar, es->tokp, --cp - es->tokp, ATEMP);
|
||||||
process_tvar:
|
process_tvar:
|
||||||
es->val = tempvar();
|
es->val = tempvar("");
|
||||||
es->val->flag &= ~INTEGER;
|
es->val->flag &= ~INTEGER;
|
||||||
es->val->type = 0;
|
es->val->type = 0;
|
||||||
es->val->val.s = tvar;
|
es->val->val.s = tvar;
|
||||||
@ -719,17 +722,19 @@ assign_check(Expr_state *es, enum token op, struct tbl *vasn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct tbl *
|
struct tbl *
|
||||||
tempvar(void)
|
tempvar(const char *vname)
|
||||||
{
|
{
|
||||||
struct tbl *vp;
|
struct tbl *vp;
|
||||||
|
size_t vsize;
|
||||||
|
|
||||||
vp = alloc(sizeof(struct tbl), ATEMP);
|
vsize = strlen(vname) + 1;
|
||||||
|
vp = alloc(offsetof(struct tbl, name[0]) + vsize, ATEMP);
|
||||||
|
memcpy(vp->name, vname, vsize);
|
||||||
vp->flag = ISSET|INTEGER;
|
vp->flag = ISSET|INTEGER;
|
||||||
vp->type = 0;
|
vp->type = 0;
|
||||||
vp->areap = ATEMP;
|
vp->areap = ATEMP;
|
||||||
vp->ua.hval = 0;
|
vp->ua.hval = 0;
|
||||||
vp->val.i = 0;
|
vp->val.i = 0;
|
||||||
vp->name[0] = '\0';
|
|
||||||
return (vp);
|
return (vp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -744,7 +749,7 @@ intvar(Expr_state *es, struct tbl *vp)
|
|||||||
(vp->flag & (ISSET|INTEGER|EXPRLVALUE)) == (ISSET|INTEGER))
|
(vp->flag & (ISSET|INTEGER|EXPRLVALUE)) == (ISSET|INTEGER))
|
||||||
return (vp);
|
return (vp);
|
||||||
|
|
||||||
vq = tempvar();
|
vq = tempvar("");
|
||||||
if (setint_v(vq, vp, es->arith) == NULL) {
|
if (setint_v(vq, vp, es->arith) == NULL) {
|
||||||
if (vp->flag & EXPRINEVAL)
|
if (vp->flag & EXPRINEVAL)
|
||||||
evalerr(es, ET_RECURSIVE, vp->name);
|
evalerr(es, ET_RECURSIVE, vp->name);
|
||||||
|
156
funcs.c
156
funcs.c
@ -38,7 +38,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.294 2016/01/21 18:24:39 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.295 2016/02/26 20:56:43 tg Exp $");
|
||||||
|
|
||||||
#if HAVE_KILLPG
|
#if HAVE_KILLPG
|
||||||
/*
|
/*
|
||||||
@ -64,6 +64,8 @@ __RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.294 2016/01/21 18:24:39 tg Exp $");
|
|||||||
static int c_suspend(const char **);
|
static int c_suspend(const char **);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static int do_whence(const char **, int, bool, bool);
|
||||||
|
|
||||||
/* getn() that prints error */
|
/* getn() that prints error */
|
||||||
static int
|
static int
|
||||||
bi_getn(const char *as, int *ai)
|
bi_getn(const char *as, int *ai)
|
||||||
@ -514,14 +516,10 @@ s_put(int c MKSH_A_UNUSED)
|
|||||||
int
|
int
|
||||||
c_whence(const char **wp)
|
c_whence(const char **wp)
|
||||||
{
|
{
|
||||||
struct tbl *tp;
|
int optc;
|
||||||
const char *id;
|
bool pflag = false, vflag = false;
|
||||||
bool pflag = false, vflag = false, Vflag = false;
|
|
||||||
int rv = 0, optc, fcflags;
|
|
||||||
bool iam_whence = wp[0][0] == 'w';
|
|
||||||
const char *opts = iam_whence ? "pv" : "pvV";
|
|
||||||
|
|
||||||
while ((optc = ksh_getopt(wp, &builtin_opt, opts)) != -1)
|
while ((optc = ksh_getopt(wp, &builtin_opt, "pv")) != -1)
|
||||||
switch (optc) {
|
switch (optc) {
|
||||||
case 'p':
|
case 'p':
|
||||||
pflag = true;
|
pflag = true;
|
||||||
@ -529,79 +527,82 @@ c_whence(const char **wp)
|
|||||||
case 'v':
|
case 'v':
|
||||||
vflag = true;
|
vflag = true;
|
||||||
break;
|
break;
|
||||||
|
case '?':
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
wp += builtin_opt.optind;
|
||||||
|
|
||||||
|
return (do_whence(wp, pflag ? FC_PATH :
|
||||||
|
FC_BI | FC_FUNC | FC_PATH | FC_WHENCE, vflag, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* note: command without -vV is dealt with in comexec() */
|
||||||
|
int
|
||||||
|
c_command(const char **wp)
|
||||||
|
{
|
||||||
|
int optc, fcflags = FC_BI | FC_FUNC | FC_PATH | FC_WHENCE;
|
||||||
|
bool vflag = false;
|
||||||
|
|
||||||
|
/* options not sorted to facilitate string pooling */
|
||||||
|
while ((optc = ksh_getopt(wp, &builtin_opt, "Vpv")) != -1)
|
||||||
|
switch (optc) {
|
||||||
|
case 'p':
|
||||||
|
fcflags |= FC_DEFPATH;
|
||||||
|
break;
|
||||||
case 'V':
|
case 'V':
|
||||||
Vflag = true;
|
vflag = true;
|
||||||
|
break;
|
||||||
|
case 'v':
|
||||||
|
vflag = false;
|
||||||
break;
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
wp += builtin_opt.optind;
|
wp += builtin_opt.optind;
|
||||||
|
|
||||||
fcflags = FC_BI | FC_PATH | FC_FUNC;
|
return (do_whence(wp, fcflags, vflag, true));
|
||||||
if (!iam_whence) {
|
}
|
||||||
/* Note that -p on its own is deal with in comexec() */
|
|
||||||
if (pflag)
|
static int
|
||||||
fcflags |= FC_DEFPATH;
|
do_whence(const char **wp, int fcflags, bool vflag, bool iscommand)
|
||||||
/*
|
{
|
||||||
* Convert command options to whence options - note that
|
uint32_t h;
|
||||||
* command -pV uses a different path search than whence -v
|
int rv = 0;
|
||||||
* or whence -pv. This should be considered a feature.
|
struct tbl *tp;
|
||||||
*/
|
const char *id;
|
||||||
vflag = Vflag;
|
|
||||||
}
|
|
||||||
if (pflag)
|
|
||||||
fcflags &= ~(FC_BI | FC_FUNC);
|
|
||||||
|
|
||||||
while ((vflag || rv == 0) && (id = *wp++) != NULL) {
|
while ((vflag || rv == 0) && (id = *wp++) != NULL) {
|
||||||
uint32_t h = 0;
|
h = hash(id);
|
||||||
|
|
||||||
tp = NULL;
|
tp = NULL;
|
||||||
if (!pflag)
|
|
||||||
tp = ktsearch(&keywords, id, h = hash(id));
|
if (fcflags & FC_WHENCE)
|
||||||
if (!tp && !pflag) {
|
tp = ktsearch(&keywords, id, h);
|
||||||
tp = ktsearch(&aliases, id, h ? h : hash(id));
|
if (!tp && (fcflags & FC_WHENCE)) {
|
||||||
|
tp = ktsearch(&aliases, id, h);
|
||||||
if (tp && !(tp->flag & ISSET))
|
if (tp && !(tp->flag & ISSET))
|
||||||
tp = NULL;
|
tp = NULL;
|
||||||
}
|
}
|
||||||
if (!tp)
|
if (!tp)
|
||||||
tp = findcom(id, fcflags);
|
tp = findcom(id, fcflags);
|
||||||
if (vflag || (tp->type != CALIAS && tp->type != CEXEC &&
|
|
||||||
tp->type != CTALIAS))
|
|
||||||
shf_puts(id, shl_stdout);
|
|
||||||
if (vflag) {
|
|
||||||
switch (tp->type) {
|
switch (tp->type) {
|
||||||
case CKEYWD:
|
case CSHELL:
|
||||||
case CALIAS:
|
|
||||||
case CFUNC:
|
case CFUNC:
|
||||||
case CSHELL:
|
|
||||||
shf_puts(" is a", shl_stdout);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
switch (tp->type) {
|
|
||||||
case CKEYWD:
|
case CKEYWD:
|
||||||
case CSHELL:
|
shf_puts(id, shl_stdout);
|
||||||
case CTALIAS:
|
|
||||||
case CEXEC:
|
|
||||||
shf_putc(' ', shl_stdout);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
switch (tp->type) {
|
switch (tp->type) {
|
||||||
case CKEYWD:
|
case CSHELL:
|
||||||
if (vflag)
|
if (vflag)
|
||||||
shf_puts("reserved word", shl_stdout);
|
shprintf(" is a %sshell %s",
|
||||||
break;
|
(tp->flag & SPEC_BI) ? "special " : "",
|
||||||
case CALIAS:
|
Tbuiltin);
|
||||||
if (vflag)
|
|
||||||
shprintf("n %salias for ",
|
|
||||||
(tp->flag & EXPORT) ? "exported " : null);
|
|
||||||
if (!iam_whence && !vflag)
|
|
||||||
shprintf("%s %s=", Talias, id);
|
|
||||||
print_value_quoted(shl_stdout, tp->val.s);
|
|
||||||
break;
|
break;
|
||||||
case CFUNC:
|
case CFUNC:
|
||||||
if (vflag) {
|
if (vflag) {
|
||||||
|
shf_puts(" is a", shl_stdout);
|
||||||
if (tp->flag & EXPORT)
|
if (tp->flag & EXPORT)
|
||||||
shf_puts("n exported", shl_stdout);
|
shf_puts("n exported", shl_stdout);
|
||||||
if (tp->flag & TRACE)
|
if (tp->flag & TRACE)
|
||||||
@ -615,34 +616,42 @@ c_whence(const char **wp)
|
|||||||
shf_puts(T_function, shl_stdout);
|
shf_puts(T_function, shl_stdout);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CSHELL:
|
|
||||||
if (vflag) {
|
|
||||||
if (tp->flag & SPEC_BI)
|
|
||||||
shf_puts("special ", shl_stdout);
|
|
||||||
shprintf("%s %s", "shell", Tbuiltin);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CTALIAS:
|
|
||||||
case CEXEC:
|
case CEXEC:
|
||||||
|
case CTALIAS:
|
||||||
if (tp->flag & ISSET) {
|
if (tp->flag & ISSET) {
|
||||||
if (vflag) {
|
if (vflag) {
|
||||||
shf_puts("is ", shl_stdout);
|
shprintf("%s is ", id);
|
||||||
if (tp->type == CTALIAS)
|
if (tp->type == CTALIAS)
|
||||||
shprintf("a tracked %s%s for ",
|
shprintf("a tracked %s%s for ",
|
||||||
(tp->flag & EXPORT) ?
|
(tp->flag & EXPORT) ?
|
||||||
"exported " : null,
|
"exported " : "",
|
||||||
Talias);
|
Talias);
|
||||||
}
|
}
|
||||||
shf_puts(tp->val.s, shl_stdout);
|
shf_puts(tp->val.s, shl_stdout);
|
||||||
} else {
|
} else {
|
||||||
if (vflag)
|
if (vflag)
|
||||||
shf_puts("not found", shl_stdout);
|
shprintf("%s not found", id);
|
||||||
rv = 1;
|
rv = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
case CALIAS:
|
||||||
shf_puts(" is *GOK*", shl_stdout);
|
if (vflag) {
|
||||||
|
shprintf("%s is an %s%s for ", id,
|
||||||
|
(tp->flag & EXPORT) ? "exported " : "",
|
||||||
|
Talias);
|
||||||
|
} else if (iscommand)
|
||||||
|
shprintf("%s %s=", Talias, id);
|
||||||
|
print_value_quoted(shl_stdout, tp->val.s);
|
||||||
break;
|
break;
|
||||||
|
case CKEYWD:
|
||||||
|
if (vflag)
|
||||||
|
shf_puts(" is a reserved word", shl_stdout);
|
||||||
|
break;
|
||||||
|
#ifndef MKSH_SMALL
|
||||||
|
default:
|
||||||
|
bi_errorf("%s is of unknown type %d", id, tp->type);
|
||||||
|
return (1);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
if (vflag || !rv)
|
if (vflag || !rv)
|
||||||
shf_putc('\n', shl_stdout);
|
shf_putc('\n', shl_stdout);
|
||||||
@ -650,17 +659,6 @@ c_whence(const char **wp)
|
|||||||
return (rv);
|
return (rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Deal with command -vV - command -p dealt with in comexec() */
|
|
||||||
int
|
|
||||||
c_command(const char **wp)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Let c_whence do the work. Note that c_command() must be
|
|
||||||
* a distinct function from c_whence() (tested in comexec()).
|
|
||||||
*/
|
|
||||||
return (c_whence(wp));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* typeset, global, export, and readonly */
|
/* typeset, global, export, and readonly */
|
||||||
static void c_typeset_vardump(struct tbl *, uint32_t, int, bool, bool);
|
static void c_typeset_vardump(struct tbl *, uint32_t, int, bool, bool);
|
||||||
static void c_typeset_vardump_recursive(struct block *, uint32_t, int, bool,
|
static void c_typeset_vardump_recursive(struct block *, uint32_t, int, bool,
|
||||||
|
22
histrap.c
22
histrap.c
@ -27,7 +27,7 @@
|
|||||||
#include <sys/file.h>
|
#include <sys/file.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.154 2016/02/24 01:45:59 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.156 2016/03/04 14:26:13 tg Exp $");
|
||||||
|
|
||||||
Trap sigtraps[ksh_NSIG + 1];
|
Trap sigtraps[ksh_NSIG + 1];
|
||||||
static struct sigaction Sigact_ign;
|
static struct sigaction Sigact_ign;
|
||||||
@ -1017,23 +1017,26 @@ inittraps(void)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
const char *cs;
|
const char *cs;
|
||||||
|
#if !HAVE_SYS_SIGNAME
|
||||||
|
const struct mksh_sigpair *pair;
|
||||||
|
#endif
|
||||||
|
|
||||||
trap_exstat = -1;
|
trap_exstat = -1;
|
||||||
|
|
||||||
/* Populate sigtraps based on sys_signame and sys_siglist. */
|
/* populate sigtraps based on sys_signame and sys_siglist */
|
||||||
for (i = 1; i < ksh_NSIG; i++) {
|
for (i = 1; i < ksh_NSIG; i++) {
|
||||||
sigtraps[i].signal = i;
|
sigtraps[i].signal = i;
|
||||||
#if HAVE_SYS_SIGNAME
|
#if HAVE_SYS_SIGNAME
|
||||||
cs = sys_signame[i];
|
cs = sys_signame[i];
|
||||||
#else
|
#else
|
||||||
const struct mksh_sigpair *pair = mksh_sigpairs;
|
pair = mksh_sigpairs;
|
||||||
while ((pair->nr != i) && (pair->name != NULL))
|
while ((pair->nr != i) && (pair->name != NULL))
|
||||||
++pair;
|
++pair;
|
||||||
cs = pair->name;
|
cs = pair->name;
|
||||||
#endif
|
#endif
|
||||||
if ((cs == NULL) ||
|
if ((cs == NULL) ||
|
||||||
(cs[0] == '\0'))
|
(cs[0] == '\0'))
|
||||||
sigtraps[i].name = shf_smprintf("%d", i);
|
sigtraps[i].name = null;
|
||||||
else {
|
else {
|
||||||
char *s;
|
char *s;
|
||||||
|
|
||||||
@ -1049,7 +1052,18 @@ inittraps(void)
|
|||||||
sigtraps[i].name = s;
|
sigtraps[i].name = s;
|
||||||
while ((*s = ksh_toupper(*s)))
|
while ((*s = ksh_toupper(*s)))
|
||||||
++s;
|
++s;
|
||||||
|
/* check for reserved names */
|
||||||
|
if (!strcmp(sigtraps[i].name, "EXIT") ||
|
||||||
|
!strcmp(sigtraps[i].name, "ERR")) {
|
||||||
|
#ifndef MKSH_SMALL
|
||||||
|
internal_warningf("ignoring invalid signal name %s",
|
||||||
|
sigtraps[i].name);
|
||||||
|
#endif
|
||||||
|
sigtraps[i].name = null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (sigtraps[i].name == null)
|
||||||
|
sigtraps[i].name = shf_smprintf("%d", i);
|
||||||
#if HAVE_SYS_SIGLIST
|
#if HAVE_SYS_SIGLIST
|
||||||
sigtraps[i].mess = sys_siglist[i];
|
sigtraps[i].mess = sys_siglist[i];
|
||||||
#elif HAVE_STRSIGNAL
|
#elif HAVE_STRSIGNAL
|
||||||
|
6
jobs.c
6
jobs.c
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
#include "sh.h"
|
#include "sh.h"
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/jobs.c,v 1.119 2016/02/24 01:44:45 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/jobs.c,v 1.120 2016/03/04 14:26:13 tg Exp $");
|
||||||
|
|
||||||
#if HAVE_KILLPG
|
#if HAVE_KILLPG
|
||||||
#define mksh_killpg killpg
|
#define mksh_killpg killpg
|
||||||
@ -1425,8 +1425,8 @@ check_job(Job *j)
|
|||||||
|
|
||||||
/* XXX debugging (nasty - interrupt routine using shl_out) */
|
/* XXX debugging (nasty - interrupt routine using shl_out) */
|
||||||
if (!(j->flags & JF_STARTED)) {
|
if (!(j->flags & JF_STARTED)) {
|
||||||
internal_warningf("check_job: job started (flags 0x%x)",
|
internal_warningf("check_job: job started (flags 0x%X)",
|
||||||
j->flags);
|
(unsigned int)j->flags);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
18
lalloc.c
18
lalloc.c
@ -23,7 +23,7 @@
|
|||||||
#include <err.h>
|
#include <err.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/lalloc.c,v 1.25 2016/02/24 02:08:39 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/lalloc.c,v 1.26 2016/02/26 21:53:36 tg Exp $");
|
||||||
|
|
||||||
/* build with CPPFLAGS+= -DUSE_REALLOC_MALLOC=0 on ancient systems */
|
/* build with CPPFLAGS+= -DUSE_REALLOC_MALLOC=0 on ancient systems */
|
||||||
#if defined(USE_REALLOC_MALLOC) && (USE_REALLOC_MALLOC == 0)
|
#if defined(USE_REALLOC_MALLOC) && (USE_REALLOC_MALLOC == 0)
|
||||||
@ -36,7 +36,7 @@ __RCSID("$MirOS: src/bin/mksh/lalloc.c,v 1.25 2016/02/24 02:08:39 tg Exp $");
|
|||||||
static struct lalloc_common *findptr(struct lalloc_common **, char *, Area *);
|
static struct lalloc_common *findptr(struct lalloc_common **, char *, Area *);
|
||||||
|
|
||||||
#ifndef MKSH_ALLOC_CATCH_UNDERRUNS
|
#ifndef MKSH_ALLOC_CATCH_UNDERRUNS
|
||||||
#define ALLOC_ISUNALIGNED(p) (((size_t)(p)) % ALLOC_SIZE)
|
#define ALLOC_ISUNALIGNED(p) (((size_t)(p)) % sizeof(struct lalloc_common))
|
||||||
#else
|
#else
|
||||||
#define ALLOC_ISUNALIGNED(p) (((size_t)(p)) & 4095)
|
#define ALLOC_ISUNALIGNED(p) (((size_t)(p)) & 4095)
|
||||||
#undef remalloc
|
#undef remalloc
|
||||||
@ -107,10 +107,10 @@ findptr(struct lalloc_common **lpp, char *ptr, Area *ap)
|
|||||||
#endif
|
#endif
|
||||||
/* get address of ALLOC_ITEM from user item */
|
/* get address of ALLOC_ITEM from user item */
|
||||||
/*
|
/*
|
||||||
* note: the alignment of "ptr" to ALLOC_SIZE is checked
|
* note: the alignment of "ptr" to ALLOC_ITEM is checked
|
||||||
* above; the "void *" gets us rid of a gcc 2.95 warning
|
* above; the "void *" gets us rid of a gcc 2.95 warning
|
||||||
*/
|
*/
|
||||||
*lpp = (lp = ptr - ALLOC_SIZE);
|
*lpp = (lp = ptr - sizeof(ALLOC_ITEM));
|
||||||
/* search for allocation item in group list */
|
/* search for allocation item in group list */
|
||||||
while (ap->next != lp)
|
while (ap->next != lp)
|
||||||
if ((ap = ap->next) == NULL) {
|
if ((ap = ap->next) == NULL) {
|
||||||
@ -126,7 +126,7 @@ findptr(struct lalloc_common **lpp, char *ptr, Area *ap)
|
|||||||
internal_errorf("rogue pointer %zX", (size_t)ptr);
|
internal_errorf("rogue pointer %zX", (size_t)ptr);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
return ((void *)ap);
|
return (ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
@ -150,18 +150,18 @@ aresize(void *ptr, size_t numb, Area *ap)
|
|||||||
pp->next = lp->next;
|
pp->next = lp->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (notoktoadd(numb, ALLOC_SIZE) ||
|
if (notoktoadd(numb, sizeof(ALLOC_ITEM)) ||
|
||||||
(lp = remalloc(lp, numb + ALLOC_SIZE)) == NULL
|
(lp = remalloc(lp, numb + sizeof(ALLOC_ITEM))) == NULL
|
||||||
#ifndef MKSH_SMALL
|
#ifndef MKSH_SMALL
|
||||||
|| ALLOC_ISUNALIGNED(lp)
|
|| ALLOC_ISUNALIGNED(lp)
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
internal_errorf(Toomem, numb);
|
internal_errorf(Toomem, numb);
|
||||||
/* this only works because Area and ALLOC_ITEM share lalloc_common */
|
/* area pointer and items share struct lalloc_common */
|
||||||
lp->next = ap->next;
|
lp->next = ap->next;
|
||||||
ap->next = lp;
|
ap->next = lp;
|
||||||
/* return user item address */
|
/* return user item address */
|
||||||
return ((char *)lp + ALLOC_SIZE);
|
return ((char *)lp + sizeof(ALLOC_ITEM));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
48
lex.c
48
lex.c
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
#include "sh.h"
|
#include "sh.h"
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.219 2016/01/21 18:24:41 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.222 2016/03/01 19:22:31 tg Exp $");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* states while lexing word
|
* states while lexing word
|
||||||
@ -526,33 +526,13 @@ yylex(int cf)
|
|||||||
*wp++ = COMSUB;
|
*wp++ = COMSUB;
|
||||||
/*
|
/*
|
||||||
* We need to know whether we are within double
|
* We need to know whether we are within double
|
||||||
* quotes, since most shells translate \" to "
|
* quotes in order to translate \" to " within
|
||||||
* within "…`…\"…`…". This is not done in POSIX
|
* "…`…\"…`…" because, unlike for COMSUBs, the
|
||||||
* mode (§2.2.3 Double-Quotes: “The backquote
|
* outer double quoteing changes the backslash
|
||||||
* shall retain its special meaning introducing
|
* meaning for the inside. For more details:
|
||||||
* the other form of command substitution (see
|
* http://austingroupbugs.net/view.php?id=1015
|
||||||
* Command Substitution). The portion of the
|
|
||||||
* quoted string from the initial backquote and
|
|
||||||
* the characters up to the next backquote that
|
|
||||||
* is not preceded by a <backslash>, having
|
|
||||||
* escape characters removed, defines that
|
|
||||||
* command whose output replaces "`...`" when
|
|
||||||
* the word is expanded.”; §2.6.3 Command
|
|
||||||
* Substitution: “Within the backquoted style
|
|
||||||
* of command substitution, <backslash> shall
|
|
||||||
* retain its literal meaning, except when
|
|
||||||
* followed by: '$', '`', or <backslash>. The
|
|
||||||
* 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;
|
||||||
#ifdef austingroupbugs1015_is_still_not_resolved
|
|
||||||
if (Flag(FPOSIX))
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
s2 = statep;
|
s2 = statep;
|
||||||
base = state_info.base;
|
base = state_info.base;
|
||||||
while (/* CONSTCOND */ 1) {
|
while (/* CONSTCOND */ 1) {
|
||||||
@ -1000,6 +980,16 @@ yylex(int cf)
|
|||||||
if (cf & CONTIN)
|
if (cf & CONTIN)
|
||||||
goto Again;
|
goto Again;
|
||||||
}
|
}
|
||||||
|
} else if (c == '\0' && !(cf & HEREDELIM)) {
|
||||||
|
struct ioword **p = heres;
|
||||||
|
|
||||||
|
while (p < herep)
|
||||||
|
if ((*p)->ioflag & IOHERESTR)
|
||||||
|
++p;
|
||||||
|
else
|
||||||
|
/* ksh -c 'cat <<EOF' can cause this */
|
||||||
|
yyerror("here document '%s' unclosed\n",
|
||||||
|
evalstr((*p)->delim, 0));
|
||||||
}
|
}
|
||||||
return (c);
|
return (c);
|
||||||
}
|
}
|
||||||
@ -1173,7 +1163,7 @@ readhere(struct ioword *iop)
|
|||||||
while (c != '\n') {
|
while (c != '\n') {
|
||||||
if (!c)
|
if (!c)
|
||||||
/* oops, reached EOF */
|
/* oops, reached EOF */
|
||||||
yyerror("%s '%s' unclosed\n", Theredoc, eof);
|
yyerror("here document '%s' unclosed\n", eof);
|
||||||
/* store character */
|
/* store character */
|
||||||
Xcheck(xs, xp);
|
Xcheck(xs, xp);
|
||||||
Xput(xs, xp, c);
|
Xput(xs, xp, c);
|
||||||
@ -1359,8 +1349,10 @@ getsc_line(Source *s)
|
|||||||
ksh_tmout_state = TMOUT_READING;
|
ksh_tmout_state = TMOUT_READING;
|
||||||
alarm(ksh_tmout);
|
alarm(ksh_tmout);
|
||||||
}
|
}
|
||||||
if (interactive)
|
if (interactive) {
|
||||||
|
histsave(&s->line, NULL, HIST_FLUSH, true);
|
||||||
change_winsz();
|
change_winsz();
|
||||||
|
}
|
||||||
#ifndef MKSH_NO_CMDLINE_EDITING
|
#ifndef MKSH_NO_CMDLINE_EDITING
|
||||||
if (have_tty && (
|
if (have_tty && (
|
||||||
#if !MKSH_S_NOVI
|
#if !MKSH_S_NOVI
|
||||||
|
16
main.c
16
main.c
@ -34,7 +34,7 @@
|
|||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.308 2016/02/24 01:44:46 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.310 2016/02/26 21:53:36 tg Exp $");
|
||||||
|
|
||||||
extern char **environ;
|
extern char **environ;
|
||||||
|
|
||||||
@ -110,13 +110,13 @@ rndsetup(void)
|
|||||||
} *bufptr;
|
} *bufptr;
|
||||||
char *cp;
|
char *cp;
|
||||||
|
|
||||||
cp = alloc(sizeof(*bufptr) - ALLOC_SIZE, APERM);
|
cp = alloc(sizeof(*bufptr) - sizeof(ALLOC_ITEM), APERM);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
/* clear the allocated space, for valgrind */
|
/* clear the allocated space, for valgrind */
|
||||||
memset(cp, 0, sizeof(*bufptr) - ALLOC_SIZE);
|
memset(cp, 0, sizeof(*bufptr) - sizeof(ALLOC_ITEM));
|
||||||
#endif
|
#endif
|
||||||
/* undo what alloc() did to the malloc result address */
|
/* undo what alloc() did to the malloc result address */
|
||||||
bufptr = (void *)(cp - ALLOC_SIZE);
|
bufptr = (void *)(cp - sizeof(ALLOC_ITEM));
|
||||||
/* PIE or something similar provides us with deltas here */
|
/* PIE or something similar provides us with deltas here */
|
||||||
bufptr->dataptr = &rndsetupstate;
|
bufptr->dataptr = &rndsetupstate;
|
||||||
/* ASLR in at least Windows, Linux, some BSDs */
|
/* ASLR in at least Windows, Linux, some BSDs */
|
||||||
@ -208,6 +208,8 @@ main_init(int argc, const char *argv[], Source **sp, struct block **lp)
|
|||||||
|
|
||||||
/* initialise permanent Area */
|
/* initialise permanent Area */
|
||||||
ainit(&aperm);
|
ainit(&aperm);
|
||||||
|
/* max. name length: -2147483648 = 11 (+ NUL) */
|
||||||
|
vtemp = alloc(offsetof(struct tbl, name[0]) + 12, APERM);
|
||||||
|
|
||||||
/* set up base environment */
|
/* set up base environment */
|
||||||
env.type = E_NONE;
|
env.type = E_NONE;
|
||||||
@ -933,9 +935,9 @@ newenv(int type)
|
|||||||
* struct env includes ALLOC_ITEM for alignment constraints
|
* struct env includes ALLOC_ITEM for alignment constraints
|
||||||
* so first get the actually used memory, then assign it
|
* so first get the actually used memory, then assign it
|
||||||
*/
|
*/
|
||||||
cp = alloc(sizeof(struct env) - ALLOC_SIZE, ATEMP);
|
cp = alloc(sizeof(struct env) - sizeof(ALLOC_ITEM), ATEMP);
|
||||||
/* undo what alloc() did to the malloc result address */
|
/* undo what alloc() did to the malloc result address */
|
||||||
ep = (void *)(cp - ALLOC_SIZE);
|
ep = (void *)(cp - sizeof(ALLOC_ITEM));
|
||||||
/* initialise public members of struct env (not the ALLOC_ITEM) */
|
/* initialise public members of struct env (not the ALLOC_ITEM) */
|
||||||
ainit(&ep->area);
|
ainit(&ep->area);
|
||||||
ep->oenv = e;
|
ep->oenv = e;
|
||||||
@ -1031,7 +1033,7 @@ quitenv(struct shf *shf)
|
|||||||
|
|
||||||
/* free the struct env - tricky due to the ALLOC_ITEM inside */
|
/* free the struct env - tricky due to the ALLOC_ITEM inside */
|
||||||
cp = (void *)ep;
|
cp = (void *)ep;
|
||||||
afree(cp + ALLOC_SIZE, ATEMP);
|
afree(cp + sizeof(ALLOC_ITEM), ATEMP);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called after a fork to cleanup stuff left over from parents environment */
|
/* Called after a fork to cleanup stuff left over from parents environment */
|
||||||
|
4
misc.c
4
misc.c
@ -30,7 +30,7 @@
|
|||||||
#include <grp.h>
|
#include <grp.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.241 2016/01/21 18:24:43 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.242 2016/03/04 14:26:13 tg Exp $");
|
||||||
|
|
||||||
#define KSH_CHVT_FLAG
|
#define KSH_CHVT_FLAG
|
||||||
#ifdef MKSH_SMALL
|
#ifdef MKSH_SMALL
|
||||||
@ -1291,7 +1291,7 @@ print_columns(struct shf *shf, unsigned int n,
|
|||||||
shf_puts(str, shf);
|
shf_puts(str, shf);
|
||||||
else
|
else
|
||||||
shf_fprintf(shf, "%*s%*s",
|
shf_fprintf(shf, "%*s%*s",
|
||||||
max_col, str, nspace, null);
|
(int)max_col, str, (int)nspace, null);
|
||||||
}
|
}
|
||||||
shf_putchar('\n', shf);
|
shf_putchar('\n', shf);
|
||||||
}
|
}
|
||||||
|
70
mksh.1
70
mksh.1
@ -1,4 +1,4 @@
|
|||||||
.\" $MirOS: src/bin/mksh/mksh.1,v 1.389 2016/02/11 19:00:50 tg Exp $
|
.\" $MirOS: src/bin/mksh/mksh.1,v 1.392 2016/03/04 18:28:41 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,
|
||||||
@ -76,7 +76,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: February 11 2016 $
|
.Dd $Mdocdate: March 4 2016 $
|
||||||
.\"
|
.\"
|
||||||
.\" Check which macro package we use, and do other -mdoc setup.
|
.\" Check which macro package we use, and do other -mdoc setup.
|
||||||
.\"
|
.\"
|
||||||
@ -1004,13 +1004,14 @@ quotes all characters, except
|
|||||||
.Ql \`
|
.Ql \`
|
||||||
and
|
and
|
||||||
.Ql \e ,
|
.Ql \e ,
|
||||||
up to the next unquoted double quote.
|
up to the next unescaped double quote.
|
||||||
.Ql $
|
.Ql $
|
||||||
and
|
and
|
||||||
.Ql \`
|
.Ql \`
|
||||||
inside double quotes have their usual meaning (i.e. parameter, arithmetic,
|
inside double quotes have their usual meaning (i.e. parameter, arithmetic,
|
||||||
or command substitution) except no field splitting is carried out on the
|
or command substitution) except no field splitting is carried out on the
|
||||||
results of double-quoted substitutions.
|
results of double-quoted substitutions, and the old-style form of command
|
||||||
|
substitution has backslash-quoting for double quotes enabled.
|
||||||
If a
|
If a
|
||||||
.Ql \e
|
.Ql \e
|
||||||
inside a double-quoted string is followed by
|
inside a double-quoted string is followed by
|
||||||
@ -1307,13 +1308,13 @@ form, a
|
|||||||
followed by any of
|
followed by any of
|
||||||
.Ql $ ,
|
.Ql $ ,
|
||||||
.Ql \` ,
|
.Ql \` ,
|
||||||
.Ql \&"
|
|
||||||
.Pq currently, and violating Tn POSIX ,
|
|
||||||
or
|
or
|
||||||
.Ql \e
|
.Ql \e
|
||||||
is stripped (a
|
is stripped (as is
|
||||||
|
.Ql \&"
|
||||||
|
when the substitution is part of a double-quoted string); a backslash
|
||||||
.Ql \e
|
.Ql \e
|
||||||
followed by any other character is unchanged).
|
followed by any other character is unchanged.
|
||||||
As a special case in command substitutions, a command of the form
|
As a special case in command substitutions, a command of the form
|
||||||
.Pf \*(Lt Ar file
|
.Pf \*(Lt Ar file
|
||||||
is interpreted to mean substitute the contents of
|
is interpreted to mean substitute the contents of
|
||||||
@ -4312,6 +4313,11 @@ options (with single letter names) can be found in the parameter
|
|||||||
with no option name will list all the options and whether each is on or off;
|
with no option name will list all the options and whether each is on or off;
|
||||||
.Ic set +o
|
.Ic set +o
|
||||||
will print the long names of all options that are currently on.
|
will print the long names of all options that are currently on.
|
||||||
|
In a future version,
|
||||||
|
.Ic set +o
|
||||||
|
will behave
|
||||||
|
.Tn POSIX
|
||||||
|
compliant and print commands to restore the current options instead.
|
||||||
.Pp
|
.Pp
|
||||||
Remaining arguments, if any, are positional parameters and are assigned, in
|
Remaining arguments, if any, are positional parameters and are assigned, in
|
||||||
order, to the positional parameters (i.e. $1, $2, etc.).
|
order, to the positional parameters (i.e. $1, $2, etc.).
|
||||||
@ -5141,38 +5147,20 @@ If job monitoring is enabled, the completion status of jobs is printed
|
|||||||
.Op Fl pv
|
.Op Fl pv
|
||||||
.Op Ar name ...
|
.Op Ar name ...
|
||||||
.Xc
|
.Xc
|
||||||
For each
|
|
||||||
.Ar name ,
|
|
||||||
the type of command is listed (reserved word, built-in, alias,
|
|
||||||
function, tracked alias, or executable).
|
|
||||||
If the
|
|
||||||
.Fl p
|
|
||||||
option is used, a path search is performed even if
|
|
||||||
.Ar name
|
|
||||||
is a reserved word, alias, etc.
|
|
||||||
Without the
|
Without the
|
||||||
.Fl v
|
.Fl v
|
||||||
option,
|
option, it is the same as
|
||||||
.Ic whence
|
.Ic command Fl v ,
|
||||||
is similar to
|
except aliases are not printed as alias command.
|
||||||
.Ic command Fl v
|
|
||||||
except that
|
|
||||||
.Ic whence
|
|
||||||
will find reserved words and won't print aliases as alias commands.
|
|
||||||
With the
|
With the
|
||||||
.Fl v
|
.Fl v
|
||||||
option,
|
option, it is exactly the same as
|
||||||
.Ic whence
|
|
||||||
is the same as
|
|
||||||
.Ic command Fl V .
|
.Ic command Fl V .
|
||||||
Note that for
|
In either case, the
|
||||||
.Ic whence ,
|
|
||||||
the
|
|
||||||
.Fl p
|
.Fl p
|
||||||
option does not affect the search path used, as it does for
|
option differs: the search path is not affected in
|
||||||
.Ic command .
|
.Ic whence ,
|
||||||
If the type of one or more of the names could not be determined, the exit
|
but the search is restricted to the path.
|
||||||
status is non-zero.
|
|
||||||
.El
|
.El
|
||||||
.Ss Job control
|
.Ss Job control
|
||||||
Job control refers to the shell's ability to monitor and control jobs which
|
Job control refers to the shell's ability to monitor and control jobs which
|
||||||
@ -6596,20 +6584,8 @@ when multiple shells are accessing the file; the rollover process
|
|||||||
for the in-memory portion of the history is slow, should use
|
for the in-memory portion of the history is slow, should use
|
||||||
.Xr memmove 3 .
|
.Xr memmove 3 .
|
||||||
.Pp
|
.Pp
|
||||||
Handling of backslash plus double-quote inside the (deprecated)
|
|
||||||
.Pf \` Ns Ar command Ns \`
|
|
||||||
form of command substitution when the substitution itself is
|
|
||||||
also inside double quotes currently deliberately violates
|
|
||||||
.Tn POSIX
|
|
||||||
even in
|
|
||||||
.Fl o Ic posix
|
|
||||||
mode until Austin group bug 1015 has been resolved either way,
|
|
||||||
as the current wording of the standard prohibits the current
|
|
||||||
and historic practice of several shells which several scripts
|
|
||||||
(admittedly wrongly) depend on.
|
|
||||||
.Pp
|
|
||||||
This document attempts to describe
|
This document attempts to describe
|
||||||
.Nm mksh\ R52b
|
.Nm mksh\ R52c
|
||||||
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
|
||||||
|
38
sh.h
38
sh.h
@ -175,9 +175,9 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef EXTERN
|
#ifdef EXTERN
|
||||||
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.762 2016/02/24 02:08:39 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.768 2016/03/04 18:28:42 tg Exp $");
|
||||||
#endif
|
#endif
|
||||||
#define MKSH_VERSION "R52 2016/02/23"
|
#define MKSH_VERSION "R52 2016/03/04"
|
||||||
|
|
||||||
/* arithmetic types: C implementation */
|
/* arithmetic types: C implementation */
|
||||||
#if !HAVE_CAN_INTTYPES
|
#if !HAVE_CAN_INTTYPES
|
||||||
@ -578,7 +578,7 @@ char *ucstrstr(char *, const char *);
|
|||||||
#define mkssert(e) do { } while (/* CONSTCOND */ 0)
|
#define mkssert(e) do { } while (/* CONSTCOND */ 0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (!defined(MKSH_BUILDMAKEFILE4BSD) && !defined(MKSH_BUILDSH)) || (MKSH_BUILD_R != 522)
|
#if (!defined(MKSH_BUILDMAKEFILE4BSD) && !defined(MKSH_BUILDSH)) || (MKSH_BUILD_R != 523)
|
||||||
#error Must run Build.sh to compile this.
|
#error Must run Build.sh to compile this.
|
||||||
extern void thiswillneverbedefinedIhope(void);
|
extern void thiswillneverbedefinedIhope(void);
|
||||||
int
|
int
|
||||||
@ -703,21 +703,21 @@ struct lalloc_common {
|
|||||||
struct lalloc_common *next;
|
struct lalloc_common *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef MKSH_ALLOC_CATCH_UNDERRUNS
|
||||||
struct lalloc_item {
|
struct lalloc_item {
|
||||||
struct lalloc_common *next;
|
struct lalloc_common *next;
|
||||||
#ifdef MKSH_ALLOC_CATCH_UNDERRUNS
|
|
||||||
size_t len;
|
size_t len;
|
||||||
char dummy[8192 - sizeof(struct lalloc_common *) - sizeof(size_t)];
|
char dummy[8192 - sizeof(struct lalloc_common *) - sizeof(size_t)];
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
/* 2. sizes */
|
/* 2. sizes */
|
||||||
|
#ifdef MKSH_ALLOC_CATCH_UNDERRUNS
|
||||||
#define ALLOC_ITEM struct lalloc_item
|
#define ALLOC_ITEM struct lalloc_item
|
||||||
#define ALLOC_SIZE (sizeof(ALLOC_ITEM))
|
|
||||||
#ifndef MKSH_ALLOC_CATCH_UNDERRUNS
|
|
||||||
#define ALLOC_OVERHEAD ALLOC_SIZE
|
|
||||||
#else
|
|
||||||
#define ALLOC_OVERHEAD 0
|
#define ALLOC_OVERHEAD 0
|
||||||
|
#else
|
||||||
|
#define ALLOC_ITEM struct lalloc_common
|
||||||
|
#define ALLOC_OVERHEAD (sizeof(ALLOC_ITEM))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* 3. group structure */
|
/* 3. group structure */
|
||||||
@ -850,11 +850,13 @@ EXTERN struct {
|
|||||||
/* null value for variable; comparison pointer for unset */
|
/* null value for variable; comparison pointer for unset */
|
||||||
EXTERN char null[] E_INIT("");
|
EXTERN char null[] E_INIT("");
|
||||||
/* helpers for string pooling */
|
/* helpers for string pooling */
|
||||||
EXTERN const char Tintovfl[] E_INIT("integer overflow %zu %c %zu prevented");
|
|
||||||
EXTERN const char Toomem[] E_INIT("can't allocate %zu data bytes");
|
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
#define Tsynerr "syntax error"
|
#define Tsynerr "syntax error"
|
||||||
|
#define Tintovfl "integer overflow %zu %c %zu prevented"
|
||||||
|
#define Toomem "can't allocate %zu data bytes"
|
||||||
#else
|
#else
|
||||||
|
EXTERN const char Tintovfl[] E_INIT("integer overflow %zu %c %zu prevented");
|
||||||
|
EXTERN const char Toomem[] E_INIT("can't allocate %zu data bytes");
|
||||||
EXTERN const char Tsynerr[] E_INIT("syntax error");
|
EXTERN const char Tsynerr[] E_INIT("syntax error");
|
||||||
#endif
|
#endif
|
||||||
EXTERN const char Tselect[] E_INIT("select");
|
EXTERN const char Tselect[] E_INIT("select");
|
||||||
@ -887,12 +889,6 @@ EXTERN const char T_funny_command[] E_INIT("funny $() command");
|
|||||||
EXTERN const char Tfg_badsubst[] E_INIT("fileglob: bad substitution");
|
EXTERN const char Tfg_badsubst[] E_INIT("fileglob: bad substitution");
|
||||||
#endif
|
#endif
|
||||||
#define Tbadsubst (Tfg_badsubst + 10) /* "bad substitution" */
|
#define Tbadsubst (Tfg_badsubst + 10) /* "bad substitution" */
|
||||||
#if defined(__GNUC__)
|
|
||||||
#define Tmissinghere "missing here document"
|
|
||||||
#else
|
|
||||||
EXTERN const char Tmissinghere[] E_INIT("missing here document");
|
|
||||||
#endif
|
|
||||||
#define Theredoc (Tmissinghere + 8) /* "here document" */
|
|
||||||
EXTERN const char TC_LEX1[] E_INIT("|&;<>() \t\n");
|
EXTERN const char TC_LEX1[] E_INIT("|&;<>() \t\n");
|
||||||
#define TC_IFSWS (TC_LEX1 + 7) /* space tab newline */
|
#define TC_IFSWS (TC_LEX1 + 7) /* space tab newline */
|
||||||
|
|
||||||
@ -1216,7 +1212,7 @@ struct tbl {
|
|||||||
char name[4];
|
char name[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
EXTERN struct tbl vtemp;
|
EXTERN struct tbl *vtemp;
|
||||||
/* set by global() and local() */
|
/* set by global() and local() */
|
||||||
EXTERN bool last_lookup_was_array;
|
EXTERN bool last_lookup_was_array;
|
||||||
|
|
||||||
@ -1285,7 +1281,7 @@ enum namerefflag {
|
|||||||
#define FC_BI (FC_SPECBI | FC_NORMBI)
|
#define FC_BI (FC_SPECBI | FC_NORMBI)
|
||||||
#define FC_PATH BIT(3) /* do path search */
|
#define FC_PATH BIT(3) /* do path search */
|
||||||
#define FC_DEFPATH BIT(4) /* use default path in path search */
|
#define FC_DEFPATH BIT(4) /* use default path in path search */
|
||||||
|
#define FC_WHENCE BIT(5) /* for use by command and whence */
|
||||||
|
|
||||||
#define AF_ARGV_ALLOC 0x1 /* argv[] array allocated */
|
#define AF_ARGV_ALLOC 0x1 /* argv[] array allocated */
|
||||||
#define AF_ARGS_ALLOCED 0x2 /* argument strings allocated */
|
#define AF_ARGS_ALLOCED 0x2 /* argument strings allocated */
|
||||||
@ -1768,7 +1764,7 @@ size_t utf_ptradj(const char *) MKSH_A_PURE;
|
|||||||
int utf_wcwidth(unsigned int) MKSH_A_PURE;
|
int utf_wcwidth(unsigned int) MKSH_A_PURE;
|
||||||
#endif
|
#endif
|
||||||
int ksh_access(const char *, int);
|
int ksh_access(const char *, int);
|
||||||
struct tbl *tempvar(void);
|
struct tbl *tempvar(const char *);
|
||||||
/* funcs.c */
|
/* funcs.c */
|
||||||
int c_hash(const char **);
|
int c_hash(const char **);
|
||||||
int c_pwd(const char **);
|
int c_pwd(const char **);
|
||||||
@ -2025,7 +2021,7 @@ char *shf_smprintf(const char *, ...)
|
|||||||
ssize_t shf_vfprintf(struct shf *, const char *, va_list)
|
ssize_t shf_vfprintf(struct shf *, const char *, va_list)
|
||||||
MKSH_A_FORMAT(__printf__, 2, 0);
|
MKSH_A_FORMAT(__printf__, 2, 0);
|
||||||
/* syn.c */
|
/* syn.c */
|
||||||
int assign_command(const char *, bool);
|
int assign_command(const char *, bool) MKSH_A_PURE;
|
||||||
void initkeywords(void);
|
void initkeywords(void);
|
||||||
struct op *compile(Source *, bool);
|
struct op *compile(Source *, bool);
|
||||||
bool parse_usec(const char *, struct timeval *);
|
bool parse_usec(const char *, struct timeval *);
|
||||||
|
69
shf.c
69
shf.c
@ -2,7 +2,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, 2016
|
||||||
* mirabilos <m@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
|
||||||
@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
#include "sh.h"
|
#include "sh.h"
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/shf.c,v 1.69 2015/12/31 20:38:59 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/shf.c,v 1.70 2016/03/04 14:26:16 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 */
|
||||||
@ -197,7 +197,8 @@ shf_sopen(char *buf, ssize_t bsize, int sflags, struct shf *shf)
|
|||||||
{
|
{
|
||||||
/* can't have a read+write string */
|
/* can't have a read+write string */
|
||||||
if (!(!(sflags & SHF_RD) ^ !(sflags & SHF_WR)))
|
if (!(!(sflags & SHF_RD) ^ !(sflags & SHF_WR)))
|
||||||
internal_errorf("%s: flags 0x%X", "shf_sopen", sflags);
|
internal_errorf("%s: flags 0x%X", "shf_sopen",
|
||||||
|
(unsigned int)sflags);
|
||||||
|
|
||||||
if (!shf) {
|
if (!shf) {
|
||||||
shf = alloc(sizeof(struct shf), ATEMP);
|
shf = alloc(sizeof(struct shf), ATEMP);
|
||||||
@ -452,7 +453,8 @@ shf_read(char *buf, ssize_t bsize, struct shf *shf)
|
|||||||
ssize_t ncopy, orig_bsize = bsize;
|
ssize_t ncopy, orig_bsize = bsize;
|
||||||
|
|
||||||
if (!(shf->flags & SHF_RD))
|
if (!(shf->flags & SHF_RD))
|
||||||
internal_errorf("%s: flags 0x%X", "shf_read", shf->flags);
|
internal_errorf("%s: flags 0x%X", "shf_read",
|
||||||
|
(unsigned int)shf->flags);
|
||||||
|
|
||||||
if (bsize <= 0)
|
if (bsize <= 0)
|
||||||
internal_errorf("%s: %s %zd", "shf_write", "bsize", bsize);
|
internal_errorf("%s: %s %zd", "shf_write", "bsize", bsize);
|
||||||
@ -489,7 +491,8 @@ shf_getse(char *buf, ssize_t bsize, struct shf *shf)
|
|||||||
char *orig_buf = buf;
|
char *orig_buf = buf;
|
||||||
|
|
||||||
if (!(shf->flags & SHF_RD))
|
if (!(shf->flags & SHF_RD))
|
||||||
internal_errorf("%s: flags 0x%X", "shf_getse", shf->flags);
|
internal_errorf("%s: flags 0x%X", "shf_getse",
|
||||||
|
(unsigned int)shf->flags);
|
||||||
|
|
||||||
if (bsize <= 0)
|
if (bsize <= 0)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
@ -525,7 +528,8 @@ int
|
|||||||
shf_getchar(struct shf *shf)
|
shf_getchar(struct shf *shf)
|
||||||
{
|
{
|
||||||
if (!(shf->flags & SHF_RD))
|
if (!(shf->flags & SHF_RD))
|
||||||
internal_errorf("%s: flags 0x%X", "shf_getchar", shf->flags);
|
internal_errorf("%s: flags 0x%X", "shf_getchar",
|
||||||
|
(unsigned int)shf->flags);
|
||||||
|
|
||||||
if (shf->rnleft == 0 && (shf_fillbuf(shf) == -1 || shf->rnleft == 0))
|
if (shf->rnleft == 0 && (shf_fillbuf(shf) == -1 || shf->rnleft == 0))
|
||||||
return (-1);
|
return (-1);
|
||||||
@ -541,7 +545,8 @@ int
|
|||||||
shf_ungetc(int c, struct shf *shf)
|
shf_ungetc(int c, struct shf *shf)
|
||||||
{
|
{
|
||||||
if (!(shf->flags & SHF_RD))
|
if (!(shf->flags & SHF_RD))
|
||||||
internal_errorf("%s: flags 0x%X", "shf_ungetc", shf->flags);
|
internal_errorf("%s: flags 0x%X", "shf_ungetc",
|
||||||
|
(unsigned int)shf->flags);
|
||||||
|
|
||||||
if ((shf->flags & SHF_ERROR) || c == -1 ||
|
if ((shf->flags & SHF_ERROR) || c == -1 ||
|
||||||
(shf->rp == shf->buf && shf->rnleft))
|
(shf->rp == shf->buf && shf->rnleft))
|
||||||
@ -578,7 +583,8 @@ int
|
|||||||
shf_putchar(int c, struct shf *shf)
|
shf_putchar(int c, struct shf *shf)
|
||||||
{
|
{
|
||||||
if (!(shf->flags & SHF_WR))
|
if (!(shf->flags & SHF_WR))
|
||||||
internal_errorf("%s: flags 0x%X", "shf_putchar", shf->flags);
|
internal_errorf("%s: flags 0x%X", "shf_putchar",
|
||||||
|
(unsigned int)shf->flags);
|
||||||
|
|
||||||
if (c == -1)
|
if (c == -1)
|
||||||
return (-1);
|
return (-1);
|
||||||
@ -633,7 +639,8 @@ shf_write(const char *buf, ssize_t nbytes, struct shf *shf)
|
|||||||
ssize_t n, ncopy, orig_nbytes = nbytes;
|
ssize_t n, ncopy, orig_nbytes = nbytes;
|
||||||
|
|
||||||
if (!(shf->flags & SHF_WR))
|
if (!(shf->flags & SHF_WR))
|
||||||
internal_errorf("%s: flags 0x%X", "shf_write", shf->flags);
|
internal_errorf("%s: flags 0x%X", "shf_write",
|
||||||
|
(unsigned int)shf->flags);
|
||||||
|
|
||||||
if (nbytes < 0)
|
if (nbytes < 0)
|
||||||
internal_errorf("%s: %s %zd", "shf_write", "nbytes", nbytes);
|
internal_errorf("%s: %s %zd", "shf_write", "nbytes", nbytes);
|
||||||
@ -764,7 +771,7 @@ shf_vfprintf(struct shf *shf, const char *fmt, va_list args)
|
|||||||
const char *s;
|
const char *s;
|
||||||
char c, *cp;
|
char c, *cp;
|
||||||
int tmp = 0, flags;
|
int tmp = 0, flags;
|
||||||
ssize_t field, precision, len;
|
size_t field, precision, len;
|
||||||
unsigned long lnum;
|
unsigned long lnum;
|
||||||
/* %#o produces the longest output */
|
/* %#o produces the longest output */
|
||||||
char numbuf[(8 * sizeof(long) + 2) / 3 + 1];
|
char numbuf[(8 * sizeof(long) + 2) / 3 + 1];
|
||||||
@ -791,7 +798,7 @@ shf_vfprintf(struct shf *shf, const char *fmt, va_list args)
|
|||||||
*/
|
*/
|
||||||
flags = 0;
|
flags = 0;
|
||||||
field = precision = 0;
|
field = precision = 0;
|
||||||
for ( ; (c = *fmt++) ; ) {
|
while ((c = *fmt++)) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case '#':
|
case '#':
|
||||||
flags |= FL_HASH;
|
flags |= FL_HASH;
|
||||||
@ -821,12 +828,17 @@ shf_vfprintf(struct shf *shf, const char *fmt, va_list args)
|
|||||||
|
|
||||||
case '*':
|
case '*':
|
||||||
tmp = VA(int);
|
tmp = VA(int);
|
||||||
|
if (tmp < 0) {
|
||||||
if (flags & FL_DOT)
|
if (flags & FL_DOT)
|
||||||
precision = tmp;
|
precision = 0;
|
||||||
else if ((field = tmp) < 0) {
|
else {
|
||||||
field = -field;
|
field = (unsigned int)-tmp;
|
||||||
flags |= FL_RIGHT;
|
flags |= FL_RIGHT;
|
||||||
}
|
}
|
||||||
|
} else if (flags & FL_DOT)
|
||||||
|
precision = (unsigned int)tmp;
|
||||||
|
else
|
||||||
|
field = (unsigned int)tmp;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case 'l':
|
case 'l':
|
||||||
@ -848,26 +860,23 @@ shf_vfprintf(struct shf *shf, const char *fmt, va_list args)
|
|||||||
bool overflowed = false;
|
bool overflowed = false;
|
||||||
|
|
||||||
tmp = ksh_numdig(c);
|
tmp = ksh_numdig(c);
|
||||||
while (c = *fmt++, ksh_isdigit(c)) {
|
while (c = *fmt++, ksh_isdigit(c))
|
||||||
if (notok2mul(2147483647, tmp, 10))
|
if (notok2mul(2147483647, tmp, 10))
|
||||||
overflowed = true;
|
overflowed = true;
|
||||||
|
else
|
||||||
tmp = tmp * 10 + ksh_numdig(c);
|
tmp = tmp * 10 + ksh_numdig(c);
|
||||||
}
|
|
||||||
--fmt;
|
--fmt;
|
||||||
if (overflowed)
|
if (overflowed)
|
||||||
tmp = 0;
|
tmp = 0;
|
||||||
if (flags & FL_DOT)
|
if (flags & FL_DOT)
|
||||||
precision = tmp;
|
precision = (unsigned int)tmp;
|
||||||
else
|
else
|
||||||
field = tmp;
|
field = (unsigned int)tmp;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (precision < 0)
|
|
||||||
precision = 0;
|
|
||||||
|
|
||||||
if (!c)
|
if (!c)
|
||||||
/* nasty format */
|
/* nasty format */
|
||||||
break;
|
break;
|
||||||
@ -999,7 +1008,6 @@ shf_vfprintf(struct shf *shf, const char *fmt, va_list args)
|
|||||||
if (field > precision) {
|
if (field > precision) {
|
||||||
field -= precision;
|
field -= precision;
|
||||||
if (!(flags & FL_RIGHT)) {
|
if (!(flags & FL_RIGHT)) {
|
||||||
field = -field;
|
|
||||||
/* skip past sign or 0x when padding with 0 */
|
/* skip past sign or 0x when padding with 0 */
|
||||||
if ((flags & FL_ZERO) && (flags & FL_NUMBER)) {
|
if ((flags & FL_ZERO) && (flags & FL_NUMBER)) {
|
||||||
if (*s == '+' || *s == '-' ||
|
if (*s == '+' || *s == '-' ||
|
||||||
@ -1012,7 +1020,7 @@ shf_vfprintf(struct shf *shf, const char *fmt, va_list args)
|
|||||||
shf_putc(*s, shf);
|
shf_putc(*s, shf);
|
||||||
s++;
|
s++;
|
||||||
nwritten++;
|
nwritten++;
|
||||||
if (--precision > 0 &&
|
if (--precision &&
|
||||||
ksh_eq(*s, 'X', 'x')) {
|
ksh_eq(*s, 'X', 'x')) {
|
||||||
shf_putc(*s, shf);
|
shf_putc(*s, shf);
|
||||||
s++;
|
s++;
|
||||||
@ -1023,19 +1031,16 @@ shf_vfprintf(struct shf *shf, const char *fmt, va_list args)
|
|||||||
c = '0';
|
c = '0';
|
||||||
} else
|
} else
|
||||||
c = flags & FL_ZERO ? '0' : ' ';
|
c = flags & FL_ZERO ? '0' : ' ';
|
||||||
if (field < 0) {
|
nwritten += field;
|
||||||
nwritten += -field;
|
while (field--)
|
||||||
while (field < 0) {
|
|
||||||
shf_putc(c, shf);
|
shf_putc(c, shf);
|
||||||
++field;
|
field = 0;
|
||||||
}
|
|
||||||
}
|
|
||||||
} else
|
} else
|
||||||
c = ' ';
|
c = ' ';
|
||||||
} else
|
} else
|
||||||
field = 0;
|
field = 0;
|
||||||
|
|
||||||
if (precision > 0) {
|
if (precision) {
|
||||||
const char *q;
|
const char *q;
|
||||||
|
|
||||||
nwritten += precision;
|
nwritten += precision;
|
||||||
@ -1044,12 +1049,10 @@ shf_vfprintf(struct shf *shf, const char *fmt, va_list args)
|
|||||||
shf_putc(*s, shf);
|
shf_putc(*s, shf);
|
||||||
} while (++s < q);
|
} while (++s < q);
|
||||||
}
|
}
|
||||||
if (field > 0) {
|
|
||||||
nwritten += field;
|
nwritten += field;
|
||||||
for ( ; field > 0 ; --field)
|
while (field--)
|
||||||
shf_putc(c, shf);
|
shf_putc(c, shf);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return (shf_error(shf) ? -1 : nwritten);
|
return (shf_error(shf) ? -1 : nwritten);
|
||||||
}
|
}
|
||||||
|
6
syn.c
6
syn.c
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
#include "sh.h"
|
#include "sh.h"
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.110 2016/01/21 18:24:44 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.111 2016/02/26 21:24:58 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) */
|
||||||
@ -31,6 +31,7 @@ struct nesting_state {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct yyrecursive_state {
|
struct yyrecursive_state {
|
||||||
|
struct ioword *old_heres[HERES];
|
||||||
struct yyrecursive_state *next;
|
struct yyrecursive_state *next;
|
||||||
struct ioword **old_herep;
|
struct ioword **old_herep;
|
||||||
int old_symbol;
|
int old_symbol;
|
||||||
@ -1175,7 +1176,9 @@ yyrecursive(int subtype MKSH_A_UNUSED)
|
|||||||
ys->old_reject = reject;
|
ys->old_reject = reject;
|
||||||
ys->old_symbol = symbol;
|
ys->old_symbol = symbol;
|
||||||
ACCEPT;
|
ACCEPT;
|
||||||
|
memcpy(ys->old_heres, heres, sizeof(heres));
|
||||||
ys->old_herep = herep;
|
ys->old_herep = herep;
|
||||||
|
herep = heres;
|
||||||
ys->old_salias = sALIAS;
|
ys->old_salias = sALIAS;
|
||||||
sALIAS = 0;
|
sALIAS = 0;
|
||||||
ys->next = e->yyrecursive_statep;
|
ys->next = e->yyrecursive_statep;
|
||||||
@ -1202,6 +1205,7 @@ yyrecursive_pop(bool popall)
|
|||||||
e->yyrecursive_statep = ys->next;
|
e->yyrecursive_statep = ys->next;
|
||||||
|
|
||||||
sALIAS = ys->old_salias;
|
sALIAS = ys->old_salias;
|
||||||
|
memcpy(heres, ys->old_heres, sizeof(heres));
|
||||||
herep = ys->old_herep;
|
herep = ys->old_herep;
|
||||||
reject = ys->old_reject;
|
reject = ys->old_reject;
|
||||||
symbol = ys->old_symbol;
|
symbol = ys->old_symbol;
|
||||||
|
12
tree.c
12
tree.c
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
#include "sh.h"
|
#include "sh.h"
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/tree.c,v 1.81 2016/01/21 18:24:45 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/tree.c,v 1.83 2016/03/04 14:26:16 tg Exp $");
|
||||||
|
|
||||||
#define INDENT 8
|
#define INDENT 8
|
||||||
|
|
||||||
@ -631,8 +631,8 @@ wdscan(const char *wp, int c)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
internal_warningf(
|
internal_warningf(
|
||||||
"wdscan: unknown char 0x%x (carrying on)",
|
"wdscan: unknown char 0x%X (carrying on)",
|
||||||
wp[-1]);
|
(unsigned char)wp[-1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -817,7 +817,7 @@ dumpwdvar_i(struct shf *shf, const char *wp, int quotelevel)
|
|||||||
return (--wp);
|
return (--wp);
|
||||||
case ADELIM:
|
case ADELIM:
|
||||||
if (*wp == /*{*/'}') {
|
if (*wp == /*{*/'}') {
|
||||||
shf_puts("]ADELIM(})", shf);
|
shf_puts(/*{*/ "]ADELIM(})", shf);
|
||||||
return (wp + 1);
|
return (wp + 1);
|
||||||
}
|
}
|
||||||
shf_puts("ADELIM=", shf);
|
shf_puts("ADELIM=", shf);
|
||||||
@ -852,10 +852,10 @@ dumpwdvar_i(struct shf *shf, const char *wp, int quotelevel)
|
|||||||
shf_puts("EXPRSUB<", shf);
|
shf_puts("EXPRSUB<", shf);
|
||||||
goto dumpsub;
|
goto dumpsub;
|
||||||
case OQUOTE:
|
case OQUOTE:
|
||||||
shf_fprintf(shf, "OQUOTE{%d", ++quotelevel);
|
shf_fprintf(shf, "OQUOTE{%d" /*}*/, ++quotelevel);
|
||||||
break;
|
break;
|
||||||
case CQUOTE:
|
case CQUOTE:
|
||||||
shf_fprintf(shf, "%d}CQUOTE", quotelevel);
|
shf_fprintf(shf, /*{*/ "%d}CQUOTE", quotelevel);
|
||||||
if (quotelevel)
|
if (quotelevel)
|
||||||
quotelevel--;
|
quotelevel--;
|
||||||
else
|
else
|
||||||
|
38
var.c
38
var.c
@ -28,7 +28,7 @@
|
|||||||
#include <sys/sysctl.h>
|
#include <sys/sysctl.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/var.c,v 1.198 2016/01/21 18:24:45 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/var.c,v 1.201 2016/03/01 20:28:33 tg Exp $");
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Variables
|
* Variables
|
||||||
@ -242,18 +242,26 @@ global(const char *n)
|
|||||||
if (!ksh_isalphx(c)) {
|
if (!ksh_isalphx(c)) {
|
||||||
if (array)
|
if (array)
|
||||||
errorf(Tbadsubst);
|
errorf(Tbadsubst);
|
||||||
vp = &vtemp;
|
vp = vtemp;
|
||||||
vp->flag = DEFINED;
|
vp->flag = DEFINED;
|
||||||
vp->type = 0;
|
vp->type = 0;
|
||||||
vp->areap = ATEMP;
|
vp->areap = ATEMP;
|
||||||
*vp->name = c;
|
|
||||||
if (ksh_isdigit(c)) {
|
if (ksh_isdigit(c)) {
|
||||||
if (getn(vn, &c) && (c <= l->argc))
|
if (getn(vn, &c)) {
|
||||||
|
/* main.c:main_init() says 12 */
|
||||||
|
shf_snprintf(vp->name, 12, "%d", c);
|
||||||
|
if (c <= l->argc) {
|
||||||
/* setstr can't fail here */
|
/* setstr can't fail here */
|
||||||
setstr(vp, l->argv[c], KSH_RETURN_ERROR);
|
setstr(vp, l->argv[c],
|
||||||
|
KSH_RETURN_ERROR);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
vp->name[0] = '\0';
|
||||||
vp->flag |= RDONLY;
|
vp->flag |= RDONLY;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
vp->name[0] = c;
|
||||||
|
vp->name[1] = '\0';
|
||||||
vp->flag |= RDONLY;
|
vp->flag |= RDONLY;
|
||||||
if (vn[1] != '\0')
|
if (vn[1] != '\0')
|
||||||
goto out;
|
goto out;
|
||||||
@ -320,7 +328,7 @@ local(const char *n, bool copy)
|
|||||||
vn = array_index_calc(n, &array, &val);
|
vn = array_index_calc(n, &array, &val);
|
||||||
h = hash(vn);
|
h = hash(vn);
|
||||||
if (!ksh_isalphx(*vn)) {
|
if (!ksh_isalphx(*vn)) {
|
||||||
vp = &vtemp;
|
vp = vtemp;
|
||||||
vp->flag = DEFINED|RDONLY;
|
vp->flag = DEFINED|RDONLY;
|
||||||
vp->type = 0;
|
vp->type = 0;
|
||||||
vp->areap = ATEMP;
|
vp->areap = ATEMP;
|
||||||
@ -479,13 +487,12 @@ void
|
|||||||
setint(struct tbl *vq, mksh_ari_t n)
|
setint(struct tbl *vq, mksh_ari_t n)
|
||||||
{
|
{
|
||||||
if (!(vq->flag&INTEGER)) {
|
if (!(vq->flag&INTEGER)) {
|
||||||
struct tbl *vp = &vtemp;
|
vtemp->flag = (ISSET|INTEGER);
|
||||||
vp->flag = (ISSET|INTEGER);
|
vtemp->type = 0;
|
||||||
vp->type = 0;
|
vtemp->areap = ATEMP;
|
||||||
vp->areap = ATEMP;
|
vtemp->val.i = n;
|
||||||
vp->val.i = n;
|
|
||||||
/* setstr can't fail here */
|
/* setstr can't fail here */
|
||||||
setstr(vq, str_val(vp), KSH_RETURN_ERROR);
|
setstr(vq, str_val(vtemp), KSH_RETURN_ERROR);
|
||||||
} else
|
} else
|
||||||
vq->val.i = n;
|
vq->val.i = n;
|
||||||
vq->flag |= ISSET;
|
vq->flag |= ISSET;
|
||||||
@ -827,12 +834,13 @@ typeset(const char *var, uint32_t set, uint32_t clr, int field, int base)
|
|||||||
/* check target value for being a valid variable name */
|
/* check target value for being a valid variable name */
|
||||||
ccp = skip_varname(qval, false);
|
ccp = skip_varname(qval, false);
|
||||||
if (ccp == qval) {
|
if (ccp == qval) {
|
||||||
if (ksh_isdigit(qval[0])) {
|
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
if (getn(qval, &c))
|
if (!(c = (unsigned char)qval[0]))
|
||||||
|
goto nameref_empty;
|
||||||
|
else if (ksh_isdigit(c) && getn(qval, &c))
|
||||||
goto nameref_rhs_checked;
|
goto nameref_rhs_checked;
|
||||||
} else if (qval[1] == '\0') switch (qval[0]) {
|
else if (qval[1] == '\0') switch (c) {
|
||||||
case '$':
|
case '$':
|
||||||
case '!':
|
case '!':
|
||||||
case '?':
|
case '?':
|
||||||
|
Loading…
x
Reference in New Issue
Block a user