Merge tag 'mksh-R52c'
This commit is contained in:
commit
68f6e899ef
4
Build.sh
4
Build.sh
@ -1,5 +1,5 @@
|
||||
#!/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,
|
||||
# 2011, 2012, 2013, 2014, 2015, 2016
|
||||
@ -2347,7 +2347,7 @@ addsrcs '!' HAVE_STRLCPY strlcpy.c
|
||||
addsrcs USE_PRINTF_BUILTIN printf.c
|
||||
test 1 = "$USE_PRINTF_BUILTIN" && add_cppflags -DMKSH_PRINTF_BUILTIN
|
||||
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
|
||||
|
||||
|
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 -*-
|
||||
#-
|
||||
# Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||
@ -30,7 +30,7 @@
|
||||
# (2013/12/02 20:39:44) http://openbsd.cs.toronto.edu/cgi-bin/cvsweb/src/regress/bin/ksh/?sortby=date
|
||||
|
||||
expected-stdout:
|
||||
@(#)MIRBSD KSH R52 2016/02/23
|
||||
@(#)MIRBSD KSH R52 2016/03/04
|
||||
description:
|
||||
Check version of shell.
|
||||
stdin:
|
||||
@ -39,7 +39,7 @@ name: KSH_VERSION
|
||||
category: shell:legacy-no
|
||||
---
|
||||
expected-stdout:
|
||||
@(#)LEGACY KSH R52 2016/02/23
|
||||
@(#)LEGACY KSH R52 2016/03/04
|
||||
description:
|
||||
Check version of legacy shell.
|
||||
stdin:
|
||||
@ -2249,7 +2249,7 @@ expected-stdout:
|
||||
hi
|
||||
there
|
||||
---
|
||||
name: heredoc-4
|
||||
name: heredoc-4a
|
||||
description:
|
||||
Check that an error occurs if the heredoc-delimiter is missing.
|
||||
stdin: !
|
||||
@ -2259,6 +2259,34 @@ stdin: !
|
||||
expected-exit: e > 0
|
||||
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
|
||||
description:
|
||||
Check that backslash quotes a $, ` and \ and kills a \newline
|
||||
@ -2657,6 +2685,32 @@ stdin:
|
||||
expected-stdout:
|
||||
= 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
|
||||
description:
|
||||
Tests for here documents in subshells, taken from Austin ML
|
||||
@ -6578,6 +6632,37 @@ stdin:
|
||||
expected-exit: 1
|
||||
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
|
||||
# fails due to weirdness of execv stuff
|
||||
category: !os:uwin-nt
|
||||
@ -12111,6 +12196,14 @@ expected-stdout:
|
||||
after 0='swc' 1='二' 2=''
|
||||
= done
|
||||
---
|
||||
name: command-path
|
||||
description:
|
||||
Check 'command -p' is not 'whence -p'
|
||||
stdin:
|
||||
command -pv if
|
||||
expected-stdout:
|
||||
if
|
||||
---
|
||||
name: duffs-device
|
||||
description:
|
||||
Check that the compiler did not optimise-break them
|
||||
@ -12183,7 +12276,7 @@ stdin:
|
||||
Copyright (C) 2002 Free Software Foundation, Inc.'
|
||||
EOF
|
||||
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:
|
||||
=GNU bash, version 2.05b.0(1)-release (i386-ecce-mirbsd10)=
|
||||
expected-stderr-pattern:
|
||||
|
6
edit.c
6
edit.c
@ -28,7 +28,7 @@
|
||||
|
||||
#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
|
||||
@ -4601,8 +4601,8 @@ vi_cmd(int argcnt, const char *cmd)
|
||||
static int
|
||||
domove(int argcnt, const char *cmd, int sub)
|
||||
{
|
||||
int bcount, i = 0, t;
|
||||
int ncursor = 0;
|
||||
int ncursor = 0, i = 0, t;
|
||||
unsigned int bcount;
|
||||
|
||||
switch (*cmd) {
|
||||
case 'b':
|
||||
|
12
eval.c
12
eval.c
@ -23,7 +23,7 @@
|
||||
|
||||
#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
|
||||
@ -375,8 +375,9 @@ expand(
|
||||
unwind_substsyn:
|
||||
/* restore sp */
|
||||
sp = varname - 2;
|
||||
end = (beg = wdcopy(sp, ATEMP)) +
|
||||
(wdscan(sp, CSUBST) - sp);
|
||||
beg = wdcopy(sp, ATEMP);
|
||||
end = (wdscan(cstrchr(sp, '\0') + 1,
|
||||
CSUBST) - sp) + beg;
|
||||
/* ({) the } or x is already skipped */
|
||||
if (end < wdscan(beg, EOS))
|
||||
*end = EOS;
|
||||
@ -403,8 +404,8 @@ expand(
|
||||
st->stype = stype;
|
||||
st->base = Xsavepos(ds, dp);
|
||||
st->f = f;
|
||||
if (x.var == &vtemp) {
|
||||
st->var = tempvar();
|
||||
if (x.var == vtemp) {
|
||||
st->var = tempvar(vtemp->name);
|
||||
st->var->flag &= ~INTEGER;
|
||||
/* can't fail here */
|
||||
setstr(st->var,
|
||||
@ -1192,6 +1193,7 @@ varsub(Expand *xp, const char *sp, const char *word,
|
||||
/* can't trim a vector (yet) */
|
||||
case '%':
|
||||
case '#':
|
||||
case '?':
|
||||
case '0':
|
||||
case '/':
|
||||
case 0x100 | '#':
|
||||
|
9
exec.c
9
exec.c
@ -23,7 +23,7 @@
|
||||
|
||||
#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
|
||||
#define MKSH_DEFAULT_EXECSHELL MKSH_UNIXROOT "/bin/sh"
|
||||
@ -1623,13 +1623,6 @@ herein(struct ioword *iop, char **resbuf)
|
||||
struct temp *h;
|
||||
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 */
|
||||
i = (iop->ioflag & IOEVAL) ? (ONEWORD | HEREDOC) : 0;
|
||||
|
||||
|
23
expr.c
23
expr.c
@ -23,7 +23,7 @@
|
||||
|
||||
#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[] */
|
||||
enum token {
|
||||
@ -227,7 +227,7 @@ v_evaluate(struct tbl *vp, const char *expr, volatile int error_ok,
|
||||
exprtoken(es);
|
||||
if (es->tok == END) {
|
||||
es->tok = LIT;
|
||||
es->val = tempvar();
|
||||
es->val = tempvar("");
|
||||
}
|
||||
v = intvar(es, evalexpr(es, MAX_PREC));
|
||||
|
||||
@ -649,7 +649,7 @@ exprtoken(Expr_state *es)
|
||||
cp += len;
|
||||
}
|
||||
if (es->noassign) {
|
||||
es->val = tempvar();
|
||||
es->val = tempvar("");
|
||||
es->val->flag |= EXPRLVALUE;
|
||||
} else {
|
||||
strndupx(tvar, es->tokp, cp - es->tokp, ATEMP);
|
||||
@ -665,7 +665,10 @@ exprtoken(Expr_state *es)
|
||||
goto process_tvar;
|
||||
#ifndef MKSH_SMALL
|
||||
} else if (c == '\'') {
|
||||
++cp;
|
||||
if (*++cp == '\0') {
|
||||
es->tok = END;
|
||||
evalerr(es, ET_UNEXPECTED, NULL);
|
||||
}
|
||||
cp += utf_ptradj(cp);
|
||||
if (*cp++ != '\'')
|
||||
evalerr(es, ET_STR,
|
||||
@ -684,7 +687,7 @@ exprtoken(Expr_state *es)
|
||||
c = *cp++;
|
||||
strndupx(tvar, es->tokp, --cp - es->tokp, ATEMP);
|
||||
process_tvar:
|
||||
es->val = tempvar();
|
||||
es->val = tempvar("");
|
||||
es->val->flag &= ~INTEGER;
|
||||
es->val->type = 0;
|
||||
es->val->val.s = tvar;
|
||||
@ -719,17 +722,19 @@ assign_check(Expr_state *es, enum token op, struct tbl *vasn)
|
||||
}
|
||||
|
||||
struct tbl *
|
||||
tempvar(void)
|
||||
tempvar(const char *vname)
|
||||
{
|
||||
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->type = 0;
|
||||
vp->areap = ATEMP;
|
||||
vp->ua.hval = 0;
|
||||
vp->val.i = 0;
|
||||
vp->name[0] = '\0';
|
||||
return (vp);
|
||||
}
|
||||
|
||||
@ -744,7 +749,7 @@ intvar(Expr_state *es, struct tbl *vp)
|
||||
(vp->flag & (ISSET|INTEGER|EXPRLVALUE)) == (ISSET|INTEGER))
|
||||
return (vp);
|
||||
|
||||
vq = tempvar();
|
||||
vq = tempvar("");
|
||||
if (setint_v(vq, vp, es->arith) == NULL) {
|
||||
if (vp->flag & EXPRINEVAL)
|
||||
evalerr(es, ET_RECURSIVE, vp->name);
|
||||
|
156
funcs.c
156
funcs.c
@ -38,7 +38,7 @@
|
||||
#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
|
||||
/*
|
||||
@ -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 **);
|
||||
#endif
|
||||
|
||||
static int do_whence(const char **, int, bool, bool);
|
||||
|
||||
/* getn() that prints error */
|
||||
static int
|
||||
bi_getn(const char *as, int *ai)
|
||||
@ -514,14 +516,10 @@ s_put(int c MKSH_A_UNUSED)
|
||||
int
|
||||
c_whence(const char **wp)
|
||||
{
|
||||
struct tbl *tp;
|
||||
const char *id;
|
||||
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";
|
||||
int optc;
|
||||
bool pflag = false, vflag = false;
|
||||
|
||||
while ((optc = ksh_getopt(wp, &builtin_opt, opts)) != -1)
|
||||
while ((optc = ksh_getopt(wp, &builtin_opt, "pv")) != -1)
|
||||
switch (optc) {
|
||||
case 'p':
|
||||
pflag = true;
|
||||
@ -529,79 +527,82 @@ c_whence(const char **wp)
|
||||
case 'v':
|
||||
vflag = true;
|
||||
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':
|
||||
Vflag = true;
|
||||
vflag = true;
|
||||
break;
|
||||
case 'v':
|
||||
vflag = false;
|
||||
break;
|
||||
case '?':
|
||||
return (1);
|
||||
}
|
||||
wp += builtin_opt.optind;
|
||||
|
||||
fcflags = FC_BI | FC_PATH | FC_FUNC;
|
||||
if (!iam_whence) {
|
||||
/* Note that -p on its own is deal with in comexec() */
|
||||
if (pflag)
|
||||
fcflags |= FC_DEFPATH;
|
||||
/*
|
||||
* Convert command options to whence options - note that
|
||||
* command -pV uses a different path search than whence -v
|
||||
* or whence -pv. This should be considered a feature.
|
||||
*/
|
||||
vflag = Vflag;
|
||||
}
|
||||
if (pflag)
|
||||
fcflags &= ~(FC_BI | FC_FUNC);
|
||||
return (do_whence(wp, fcflags, vflag, true));
|
||||
}
|
||||
|
||||
static int
|
||||
do_whence(const char **wp, int fcflags, bool vflag, bool iscommand)
|
||||
{
|
||||
uint32_t h;
|
||||
int rv = 0;
|
||||
struct tbl *tp;
|
||||
const char *id;
|
||||
|
||||
while ((vflag || rv == 0) && (id = *wp++) != NULL) {
|
||||
uint32_t h = 0;
|
||||
|
||||
h = hash(id);
|
||||
tp = NULL;
|
||||
if (!pflag)
|
||||
tp = ktsearch(&keywords, id, h = hash(id));
|
||||
if (!tp && !pflag) {
|
||||
tp = ktsearch(&aliases, id, h ? h : hash(id));
|
||||
|
||||
if (fcflags & FC_WHENCE)
|
||||
tp = ktsearch(&keywords, id, h);
|
||||
if (!tp && (fcflags & FC_WHENCE)) {
|
||||
tp = ktsearch(&aliases, id, h);
|
||||
if (tp && !(tp->flag & ISSET))
|
||||
tp = NULL;
|
||||
}
|
||||
if (!tp)
|
||||
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) {
|
||||
case CKEYWD:
|
||||
case CALIAS:
|
||||
case CSHELL:
|
||||
case CFUNC:
|
||||
case CSHELL:
|
||||
shf_puts(" is a", shl_stdout);
|
||||
break;
|
||||
}
|
||||
switch (tp->type) {
|
||||
case CKEYWD:
|
||||
case CSHELL:
|
||||
case CTALIAS:
|
||||
case CEXEC:
|
||||
shf_putc(' ', shl_stdout);
|
||||
shf_puts(id, shl_stdout);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (tp->type) {
|
||||
case CKEYWD:
|
||||
case CSHELL:
|
||||
if (vflag)
|
||||
shf_puts("reserved word", shl_stdout);
|
||||
break;
|
||||
case CALIAS:
|
||||
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);
|
||||
shprintf(" is a %sshell %s",
|
||||
(tp->flag & SPEC_BI) ? "special " : "",
|
||||
Tbuiltin);
|
||||
break;
|
||||
case CFUNC:
|
||||
if (vflag) {
|
||||
shf_puts(" is a", shl_stdout);
|
||||
if (tp->flag & EXPORT)
|
||||
shf_puts("n exported", shl_stdout);
|
||||
if (tp->flag & TRACE)
|
||||
@ -615,34 +616,42 @@ c_whence(const char **wp)
|
||||
shf_puts(T_function, shl_stdout);
|
||||
}
|
||||
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 CTALIAS:
|
||||
if (tp->flag & ISSET) {
|
||||
if (vflag) {
|
||||
shf_puts("is ", shl_stdout);
|
||||
shprintf("%s is ", id);
|
||||
if (tp->type == CTALIAS)
|
||||
shprintf("a tracked %s%s for ",
|
||||
(tp->flag & EXPORT) ?
|
||||
"exported " : null,
|
||||
"exported " : "",
|
||||
Talias);
|
||||
}
|
||||
shf_puts(tp->val.s, shl_stdout);
|
||||
} else {
|
||||
if (vflag)
|
||||
shf_puts("not found", shl_stdout);
|
||||
shprintf("%s not found", id);
|
||||
rv = 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
shf_puts(" is *GOK*", shl_stdout);
|
||||
case CALIAS:
|
||||
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;
|
||||
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)
|
||||
shf_putc('\n', shl_stdout);
|
||||
@ -650,17 +659,6 @@ c_whence(const char **wp)
|
||||
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 */
|
||||
static void c_typeset_vardump(struct tbl *, uint32_t, int, bool, 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>
|
||||
#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];
|
||||
static struct sigaction Sigact_ign;
|
||||
@ -1017,23 +1017,26 @@ inittraps(void)
|
||||
{
|
||||
int i;
|
||||
const char *cs;
|
||||
#if !HAVE_SYS_SIGNAME
|
||||
const struct mksh_sigpair *pair;
|
||||
#endif
|
||||
|
||||
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++) {
|
||||
sigtraps[i].signal = i;
|
||||
#if HAVE_SYS_SIGNAME
|
||||
cs = sys_signame[i];
|
||||
#else
|
||||
const struct mksh_sigpair *pair = mksh_sigpairs;
|
||||
pair = mksh_sigpairs;
|
||||
while ((pair->nr != i) && (pair->name != NULL))
|
||||
++pair;
|
||||
cs = pair->name;
|
||||
#endif
|
||||
if ((cs == NULL) ||
|
||||
(cs[0] == '\0'))
|
||||
sigtraps[i].name = shf_smprintf("%d", i);
|
||||
sigtraps[i].name = null;
|
||||
else {
|
||||
char *s;
|
||||
|
||||
@ -1049,7 +1052,18 @@ inittraps(void)
|
||||
sigtraps[i].name = s;
|
||||
while ((*s = ksh_toupper(*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
|
||||
sigtraps[i].mess = sys_siglist[i];
|
||||
#elif HAVE_STRSIGNAL
|
||||
|
6
jobs.c
6
jobs.c
@ -23,7 +23,7 @@
|
||||
|
||||
#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
|
||||
#define mksh_killpg killpg
|
||||
@ -1425,8 +1425,8 @@ check_job(Job *j)
|
||||
|
||||
/* XXX debugging (nasty - interrupt routine using shl_out) */
|
||||
if (!(j->flags & JF_STARTED)) {
|
||||
internal_warningf("check_job: job started (flags 0x%x)",
|
||||
j->flags);
|
||||
internal_warningf("check_job: job started (flags 0x%X)",
|
||||
(unsigned int)j->flags);
|
||||
return;
|
||||
}
|
||||
|
||||
|
18
lalloc.c
18
lalloc.c
@ -23,7 +23,7 @@
|
||||
#include <err.h>
|
||||
#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 */
|
||||
#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 *);
|
||||
|
||||
#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
|
||||
#define ALLOC_ISUNALIGNED(p) (((size_t)(p)) & 4095)
|
||||
#undef remalloc
|
||||
@ -107,10 +107,10 @@ findptr(struct lalloc_common **lpp, char *ptr, Area *ap)
|
||||
#endif
|
||||
/* 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
|
||||
*/
|
||||
*lpp = (lp = ptr - ALLOC_SIZE);
|
||||
*lpp = (lp = ptr - sizeof(ALLOC_ITEM));
|
||||
/* search for allocation item in group list */
|
||||
while (ap->next != lp)
|
||||
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);
|
||||
#endif
|
||||
}
|
||||
return ((void *)ap);
|
||||
return (ap);
|
||||
}
|
||||
|
||||
void *
|
||||
@ -150,18 +150,18 @@ aresize(void *ptr, size_t numb, Area *ap)
|
||||
pp->next = lp->next;
|
||||
}
|
||||
|
||||
if (notoktoadd(numb, ALLOC_SIZE) ||
|
||||
(lp = remalloc(lp, numb + ALLOC_SIZE)) == NULL
|
||||
if (notoktoadd(numb, sizeof(ALLOC_ITEM)) ||
|
||||
(lp = remalloc(lp, numb + sizeof(ALLOC_ITEM))) == NULL
|
||||
#ifndef MKSH_SMALL
|
||||
|| ALLOC_ISUNALIGNED(lp)
|
||||
#endif
|
||||
)
|
||||
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;
|
||||
ap->next = lp;
|
||||
/* return user item address */
|
||||
return ((char *)lp + ALLOC_SIZE);
|
||||
return ((char *)lp + sizeof(ALLOC_ITEM));
|
||||
}
|
||||
|
||||
void
|
||||
|
48
lex.c
48
lex.c
@ -23,7 +23,7 @@
|
||||
|
||||
#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
|
||||
@ -526,33 +526,13 @@ yylex(int cf)
|
||||
*wp++ = COMSUB;
|
||||
/*
|
||||
* We need to know whether we are within double
|
||||
* quotes, since most shells translate \" to "
|
||||
* within "…`…\"…`…". This is not done in POSIX
|
||||
* mode (§2.2.3 Double-Quotes: “The backquote
|
||||
* shall retain its special meaning introducing
|
||||
* the other form of command substitution (see
|
||||
* 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.”).
|
||||
* quotes in order to translate \" to " within
|
||||
* "…`…\"…`…" because, unlike for COMSUBs, the
|
||||
* outer double quoteing changes the backslash
|
||||
* meaning for the inside. For more details:
|
||||
* http://austingroupbugs.net/view.php?id=1015
|
||||
*/
|
||||
statep->ls_bool = false;
|
||||
#ifdef austingroupbugs1015_is_still_not_resolved
|
||||
if (Flag(FPOSIX))
|
||||
break;
|
||||
#endif
|
||||
s2 = statep;
|
||||
base = state_info.base;
|
||||
while (/* CONSTCOND */ 1) {
|
||||
@ -1000,6 +980,16 @@ yylex(int cf)
|
||||
if (cf & CONTIN)
|
||||
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);
|
||||
}
|
||||
@ -1173,7 +1163,7 @@ readhere(struct ioword *iop)
|
||||
while (c != '\n') {
|
||||
if (!c)
|
||||
/* oops, reached EOF */
|
||||
yyerror("%s '%s' unclosed\n", Theredoc, eof);
|
||||
yyerror("here document '%s' unclosed\n", eof);
|
||||
/* store character */
|
||||
Xcheck(xs, xp);
|
||||
Xput(xs, xp, c);
|
||||
@ -1359,8 +1349,10 @@ getsc_line(Source *s)
|
||||
ksh_tmout_state = TMOUT_READING;
|
||||
alarm(ksh_tmout);
|
||||
}
|
||||
if (interactive)
|
||||
if (interactive) {
|
||||
histsave(&s->line, NULL, HIST_FLUSH, true);
|
||||
change_winsz();
|
||||
}
|
||||
#ifndef MKSH_NO_CMDLINE_EDITING
|
||||
if (have_tty && (
|
||||
#if !MKSH_S_NOVI
|
||||
|
16
main.c
16
main.c
@ -34,7 +34,7 @@
|
||||
#include <locale.h>
|
||||
#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;
|
||||
|
||||
@ -110,13 +110,13 @@ rndsetup(void)
|
||||
} *bufptr;
|
||||
char *cp;
|
||||
|
||||
cp = alloc(sizeof(*bufptr) - ALLOC_SIZE, APERM);
|
||||
cp = alloc(sizeof(*bufptr) - sizeof(ALLOC_ITEM), APERM);
|
||||
#ifdef DEBUG
|
||||
/* clear the allocated space, for valgrind */
|
||||
memset(cp, 0, sizeof(*bufptr) - ALLOC_SIZE);
|
||||
memset(cp, 0, sizeof(*bufptr) - sizeof(ALLOC_ITEM));
|
||||
#endif
|
||||
/* 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 */
|
||||
bufptr->dataptr = &rndsetupstate;
|
||||
/* 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 */
|
||||
ainit(&aperm);
|
||||
/* max. name length: -2147483648 = 11 (+ NUL) */
|
||||
vtemp = alloc(offsetof(struct tbl, name[0]) + 12, APERM);
|
||||
|
||||
/* set up base environment */
|
||||
env.type = E_NONE;
|
||||
@ -933,9 +935,9 @@ newenv(int type)
|
||||
* struct env includes ALLOC_ITEM for alignment constraints
|
||||
* 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 */
|
||||
ep = (void *)(cp - ALLOC_SIZE);
|
||||
ep = (void *)(cp - sizeof(ALLOC_ITEM));
|
||||
/* initialise public members of struct env (not the ALLOC_ITEM) */
|
||||
ainit(&ep->area);
|
||||
ep->oenv = e;
|
||||
@ -1031,7 +1033,7 @@ quitenv(struct shf *shf)
|
||||
|
||||
/* free the struct env - tricky due to the ALLOC_ITEM inside */
|
||||
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 */
|
||||
|
4
misc.c
4
misc.c
@ -30,7 +30,7 @@
|
||||
#include <grp.h>
|
||||
#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
|
||||
#ifdef MKSH_SMALL
|
||||
@ -1291,7 +1291,7 @@ print_columns(struct shf *shf, unsigned int n,
|
||||
shf_puts(str, shf);
|
||||
else
|
||||
shf_fprintf(shf, "%*s%*s",
|
||||
max_col, str, nspace, null);
|
||||
(int)max_col, str, (int)nspace, null);
|
||||
}
|
||||
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 $
|
||||
.\"-
|
||||
.\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
|
||||
@ -76,7 +76,7 @@
|
||||
.\" with -mandoc, it might implement .Mx itself, but we want to
|
||||
.\" 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.
|
||||
.\"
|
||||
@ -1004,13 +1004,14 @@ quotes all characters, except
|
||||
.Ql \`
|
||||
and
|
||||
.Ql \e ,
|
||||
up to the next unquoted double quote.
|
||||
up to the next unescaped double quote.
|
||||
.Ql $
|
||||
and
|
||||
.Ql \`
|
||||
inside double quotes have their usual meaning (i.e. parameter, arithmetic,
|
||||
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
|
||||
.Ql \e
|
||||
inside a double-quoted string is followed by
|
||||
@ -1307,13 +1308,13 @@ form, a
|
||||
followed by any of
|
||||
.Ql $ ,
|
||||
.Ql \` ,
|
||||
.Ql \&"
|
||||
.Pq currently, and violating Tn POSIX ,
|
||||
or
|
||||
.Ql \e
|
||||
is stripped (a
|
||||
is stripped (as is
|
||||
.Ql \&"
|
||||
when the substitution is part of a double-quoted string); a backslash
|
||||
.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
|
||||
.Pf \*(Lt Ar file
|
||||
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;
|
||||
.Ic set +o
|
||||
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
|
||||
Remaining arguments, if any, are positional parameters and are assigned, in
|
||||
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 Ar name ...
|
||||
.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
|
||||
.Fl v
|
||||
option,
|
||||
.Ic whence
|
||||
is similar to
|
||||
.Ic command Fl v
|
||||
except that
|
||||
.Ic whence
|
||||
will find reserved words and won't print aliases as alias commands.
|
||||
option, it is the same as
|
||||
.Ic command Fl v ,
|
||||
except aliases are not printed as alias command.
|
||||
With the
|
||||
.Fl v
|
||||
option,
|
||||
.Ic whence
|
||||
is the same as
|
||||
option, it is exactly the same as
|
||||
.Ic command Fl V .
|
||||
Note that for
|
||||
.Ic whence ,
|
||||
the
|
||||
In either case, the
|
||||
.Fl p
|
||||
option does not affect the search path used, as it does for
|
||||
.Ic command .
|
||||
If the type of one or more of the names could not be determined, the exit
|
||||
status is non-zero.
|
||||
option differs: the search path is not affected in
|
||||
.Ic whence ,
|
||||
but the search is restricted to the path.
|
||||
.El
|
||||
.Ss Job control
|
||||
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
|
||||
.Xr memmove 3 .
|
||||
.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
|
||||
.Nm mksh\ R52b
|
||||
.Nm mksh\ R52c
|
||||
and up,
|
||||
.\" with vendor patches from insert-your-name-here,
|
||||
compiled without any options impacting functionality, such as
|
||||
|
38
sh.h
38
sh.h
@ -175,9 +175,9 @@
|
||||
#endif
|
||||
|
||||
#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
|
||||
#define MKSH_VERSION "R52 2016/02/23"
|
||||
#define MKSH_VERSION "R52 2016/03/04"
|
||||
|
||||
/* arithmetic types: C implementation */
|
||||
#if !HAVE_CAN_INTTYPES
|
||||
@ -578,7 +578,7 @@ char *ucstrstr(char *, const char *);
|
||||
#define mkssert(e) do { } while (/* CONSTCOND */ 0)
|
||||
#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.
|
||||
extern void thiswillneverbedefinedIhope(void);
|
||||
int
|
||||
@ -703,21 +703,21 @@ struct lalloc_common {
|
||||
struct lalloc_common *next;
|
||||
};
|
||||
|
||||
#ifdef MKSH_ALLOC_CATCH_UNDERRUNS
|
||||
struct lalloc_item {
|
||||
struct lalloc_common *next;
|
||||
#ifdef MKSH_ALLOC_CATCH_UNDERRUNS
|
||||
size_t len;
|
||||
char dummy[8192 - sizeof(struct lalloc_common *) - sizeof(size_t)];
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
/* 2. sizes */
|
||||
#ifdef MKSH_ALLOC_CATCH_UNDERRUNS
|
||||
#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
|
||||
#else
|
||||
#define ALLOC_ITEM struct lalloc_common
|
||||
#define ALLOC_OVERHEAD (sizeof(ALLOC_ITEM))
|
||||
#endif
|
||||
|
||||
/* 3. group structure */
|
||||
@ -850,11 +850,13 @@ EXTERN struct {
|
||||
/* null value for variable; comparison pointer for unset */
|
||||
EXTERN char null[] E_INIT("");
|
||||
/* 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__)
|
||||
#define Tsynerr "syntax error"
|
||||
#define Tintovfl "integer overflow %zu %c %zu prevented"
|
||||
#define Toomem "can't allocate %zu data bytes"
|
||||
#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");
|
||||
#endif
|
||||
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");
|
||||
#endif
|
||||
#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");
|
||||
#define TC_IFSWS (TC_LEX1 + 7) /* space tab newline */
|
||||
|
||||
@ -1216,7 +1212,7 @@ struct tbl {
|
||||
char name[4];
|
||||
};
|
||||
|
||||
EXTERN struct tbl vtemp;
|
||||
EXTERN struct tbl *vtemp;
|
||||
/* set by global() and local() */
|
||||
EXTERN bool last_lookup_was_array;
|
||||
|
||||
@ -1285,7 +1281,7 @@ enum namerefflag {
|
||||
#define FC_BI (FC_SPECBI | FC_NORMBI)
|
||||
#define FC_PATH BIT(3) /* do 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_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;
|
||||
#endif
|
||||
int ksh_access(const char *, int);
|
||||
struct tbl *tempvar(void);
|
||||
struct tbl *tempvar(const char *);
|
||||
/* funcs.c */
|
||||
int c_hash(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)
|
||||
MKSH_A_FORMAT(__printf__, 2, 0);
|
||||
/* syn.c */
|
||||
int assign_command(const char *, bool);
|
||||
int assign_command(const char *, bool) MKSH_A_PURE;
|
||||
void initkeywords(void);
|
||||
struct op *compile(Source *, bool);
|
||||
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,
|
||||
* 2012, 2013, 2015
|
||||
* 2012, 2013, 2015, 2016
|
||||
* mirabilos <m@mirbsd.org>
|
||||
*
|
||||
* Provided that these terms and disclaimer and all copyright notices
|
||||
@ -25,7 +25,7 @@
|
||||
|
||||
#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() */
|
||||
#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 */
|
||||
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) {
|
||||
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;
|
||||
|
||||
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)
|
||||
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;
|
||||
|
||||
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)
|
||||
return (NULL);
|
||||
@ -525,7 +528,8 @@ int
|
||||
shf_getchar(struct shf *shf)
|
||||
{
|
||||
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))
|
||||
return (-1);
|
||||
@ -541,7 +545,8 @@ int
|
||||
shf_ungetc(int c, struct shf *shf)
|
||||
{
|
||||
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 ||
|
||||
(shf->rp == shf->buf && shf->rnleft))
|
||||
@ -578,7 +583,8 @@ int
|
||||
shf_putchar(int c, struct shf *shf)
|
||||
{
|
||||
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)
|
||||
return (-1);
|
||||
@ -633,7 +639,8 @@ shf_write(const char *buf, ssize_t nbytes, struct shf *shf)
|
||||
ssize_t n, ncopy, orig_nbytes = nbytes;
|
||||
|
||||
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)
|
||||
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;
|
||||
char c, *cp;
|
||||
int tmp = 0, flags;
|
||||
ssize_t field, precision, len;
|
||||
size_t field, precision, len;
|
||||
unsigned long lnum;
|
||||
/* %#o produces the longest output */
|
||||
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;
|
||||
field = precision = 0;
|
||||
for ( ; (c = *fmt++) ; ) {
|
||||
while ((c = *fmt++)) {
|
||||
switch (c) {
|
||||
case '#':
|
||||
flags |= FL_HASH;
|
||||
@ -821,12 +828,17 @@ shf_vfprintf(struct shf *shf, const char *fmt, va_list args)
|
||||
|
||||
case '*':
|
||||
tmp = VA(int);
|
||||
if (tmp < 0) {
|
||||
if (flags & FL_DOT)
|
||||
precision = tmp;
|
||||
else if ((field = tmp) < 0) {
|
||||
field = -field;
|
||||
precision = 0;
|
||||
else {
|
||||
field = (unsigned int)-tmp;
|
||||
flags |= FL_RIGHT;
|
||||
}
|
||||
} else if (flags & FL_DOT)
|
||||
precision = (unsigned int)tmp;
|
||||
else
|
||||
field = (unsigned int)tmp;
|
||||
continue;
|
||||
|
||||
case 'l':
|
||||
@ -848,26 +860,23 @@ shf_vfprintf(struct shf *shf, const char *fmt, va_list args)
|
||||
bool overflowed = false;
|
||||
|
||||
tmp = ksh_numdig(c);
|
||||
while (c = *fmt++, ksh_isdigit(c)) {
|
||||
while (c = *fmt++, ksh_isdigit(c))
|
||||
if (notok2mul(2147483647, tmp, 10))
|
||||
overflowed = true;
|
||||
else
|
||||
tmp = tmp * 10 + ksh_numdig(c);
|
||||
}
|
||||
--fmt;
|
||||
if (overflowed)
|
||||
tmp = 0;
|
||||
if (flags & FL_DOT)
|
||||
precision = tmp;
|
||||
precision = (unsigned int)tmp;
|
||||
else
|
||||
field = tmp;
|
||||
field = (unsigned int)tmp;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (precision < 0)
|
||||
precision = 0;
|
||||
|
||||
if (!c)
|
||||
/* nasty format */
|
||||
break;
|
||||
@ -999,7 +1008,6 @@ shf_vfprintf(struct shf *shf, const char *fmt, va_list args)
|
||||
if (field > precision) {
|
||||
field -= precision;
|
||||
if (!(flags & FL_RIGHT)) {
|
||||
field = -field;
|
||||
/* skip past sign or 0x when padding with 0 */
|
||||
if ((flags & FL_ZERO) && (flags & FL_NUMBER)) {
|
||||
if (*s == '+' || *s == '-' ||
|
||||
@ -1012,7 +1020,7 @@ shf_vfprintf(struct shf *shf, const char *fmt, va_list args)
|
||||
shf_putc(*s, shf);
|
||||
s++;
|
||||
nwritten++;
|
||||
if (--precision > 0 &&
|
||||
if (--precision &&
|
||||
ksh_eq(*s, 'X', 'x')) {
|
||||
shf_putc(*s, shf);
|
||||
s++;
|
||||
@ -1023,19 +1031,16 @@ shf_vfprintf(struct shf *shf, const char *fmt, va_list args)
|
||||
c = '0';
|
||||
} else
|
||||
c = flags & FL_ZERO ? '0' : ' ';
|
||||
if (field < 0) {
|
||||
nwritten += -field;
|
||||
while (field < 0) {
|
||||
nwritten += field;
|
||||
while (field--)
|
||||
shf_putc(c, shf);
|
||||
++field;
|
||||
}
|
||||
}
|
||||
field = 0;
|
||||
} else
|
||||
c = ' ';
|
||||
} else
|
||||
field = 0;
|
||||
|
||||
if (precision > 0) {
|
||||
if (precision) {
|
||||
const char *q;
|
||||
|
||||
nwritten += precision;
|
||||
@ -1044,12 +1049,10 @@ shf_vfprintf(struct shf *shf, const char *fmt, va_list args)
|
||||
shf_putc(*s, shf);
|
||||
} while (++s < q);
|
||||
}
|
||||
if (field > 0) {
|
||||
nwritten += field;
|
||||
for ( ; field > 0 ; --field)
|
||||
while (field--)
|
||||
shf_putc(c, shf);
|
||||
}
|
||||
}
|
||||
|
||||
return (shf_error(shf) ? -1 : nwritten);
|
||||
}
|
||||
|
6
syn.c
6
syn.c
@ -23,7 +23,7 @@
|
||||
|
||||
#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 {
|
||||
int start_token; /* token than began nesting (eg, FOR) */
|
||||
@ -31,6 +31,7 @@ struct nesting_state {
|
||||
};
|
||||
|
||||
struct yyrecursive_state {
|
||||
struct ioword *old_heres[HERES];
|
||||
struct yyrecursive_state *next;
|
||||
struct ioword **old_herep;
|
||||
int old_symbol;
|
||||
@ -1175,7 +1176,9 @@ yyrecursive(int subtype MKSH_A_UNUSED)
|
||||
ys->old_reject = reject;
|
||||
ys->old_symbol = symbol;
|
||||
ACCEPT;
|
||||
memcpy(ys->old_heres, heres, sizeof(heres));
|
||||
ys->old_herep = herep;
|
||||
herep = heres;
|
||||
ys->old_salias = sALIAS;
|
||||
sALIAS = 0;
|
||||
ys->next = e->yyrecursive_statep;
|
||||
@ -1202,6 +1205,7 @@ yyrecursive_pop(bool popall)
|
||||
e->yyrecursive_statep = ys->next;
|
||||
|
||||
sALIAS = ys->old_salias;
|
||||
memcpy(heres, ys->old_heres, sizeof(heres));
|
||||
herep = ys->old_herep;
|
||||
reject = ys->old_reject;
|
||||
symbol = ys->old_symbol;
|
||||
|
12
tree.c
12
tree.c
@ -23,7 +23,7 @@
|
||||
|
||||
#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
|
||||
|
||||
@ -631,8 +631,8 @@ wdscan(const char *wp, int c)
|
||||
break;
|
||||
default:
|
||||
internal_warningf(
|
||||
"wdscan: unknown char 0x%x (carrying on)",
|
||||
wp[-1]);
|
||||
"wdscan: unknown char 0x%X (carrying on)",
|
||||
(unsigned char)wp[-1]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -817,7 +817,7 @@ dumpwdvar_i(struct shf *shf, const char *wp, int quotelevel)
|
||||
return (--wp);
|
||||
case ADELIM:
|
||||
if (*wp == /*{*/'}') {
|
||||
shf_puts("]ADELIM(})", shf);
|
||||
shf_puts(/*{*/ "]ADELIM(})", shf);
|
||||
return (wp + 1);
|
||||
}
|
||||
shf_puts("ADELIM=", shf);
|
||||
@ -852,10 +852,10 @@ dumpwdvar_i(struct shf *shf, const char *wp, int quotelevel)
|
||||
shf_puts("EXPRSUB<", shf);
|
||||
goto dumpsub;
|
||||
case OQUOTE:
|
||||
shf_fprintf(shf, "OQUOTE{%d", ++quotelevel);
|
||||
shf_fprintf(shf, "OQUOTE{%d" /*}*/, ++quotelevel);
|
||||
break;
|
||||
case CQUOTE:
|
||||
shf_fprintf(shf, "%d}CQUOTE", quotelevel);
|
||||
shf_fprintf(shf, /*{*/ "%d}CQUOTE", quotelevel);
|
||||
if (quotelevel)
|
||||
quotelevel--;
|
||||
else
|
||||
|
38
var.c
38
var.c
@ -28,7 +28,7 @@
|
||||
#include <sys/sysctl.h>
|
||||
#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
|
||||
@ -242,18 +242,26 @@ global(const char *n)
|
||||
if (!ksh_isalphx(c)) {
|
||||
if (array)
|
||||
errorf(Tbadsubst);
|
||||
vp = &vtemp;
|
||||
vp = vtemp;
|
||||
vp->flag = DEFINED;
|
||||
vp->type = 0;
|
||||
vp->areap = ATEMP;
|
||||
*vp->name = 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(vp, l->argv[c], KSH_RETURN_ERROR);
|
||||
setstr(vp, l->argv[c],
|
||||
KSH_RETURN_ERROR);
|
||||
}
|
||||
} else
|
||||
vp->name[0] = '\0';
|
||||
vp->flag |= RDONLY;
|
||||
goto out;
|
||||
}
|
||||
vp->name[0] = c;
|
||||
vp->name[1] = '\0';
|
||||
vp->flag |= RDONLY;
|
||||
if (vn[1] != '\0')
|
||||
goto out;
|
||||
@ -320,7 +328,7 @@ local(const char *n, bool copy)
|
||||
vn = array_index_calc(n, &array, &val);
|
||||
h = hash(vn);
|
||||
if (!ksh_isalphx(*vn)) {
|
||||
vp = &vtemp;
|
||||
vp = vtemp;
|
||||
vp->flag = DEFINED|RDONLY;
|
||||
vp->type = 0;
|
||||
vp->areap = ATEMP;
|
||||
@ -479,13 +487,12 @@ void
|
||||
setint(struct tbl *vq, mksh_ari_t n)
|
||||
{
|
||||
if (!(vq->flag&INTEGER)) {
|
||||
struct tbl *vp = &vtemp;
|
||||
vp->flag = (ISSET|INTEGER);
|
||||
vp->type = 0;
|
||||
vp->areap = ATEMP;
|
||||
vp->val.i = n;
|
||||
vtemp->flag = (ISSET|INTEGER);
|
||||
vtemp->type = 0;
|
||||
vtemp->areap = ATEMP;
|
||||
vtemp->val.i = n;
|
||||
/* setstr can't fail here */
|
||||
setstr(vq, str_val(vp), KSH_RETURN_ERROR);
|
||||
setstr(vq, str_val(vtemp), KSH_RETURN_ERROR);
|
||||
} else
|
||||
vq->val.i = n;
|
||||
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 */
|
||||
ccp = skip_varname(qval, false);
|
||||
if (ccp == qval) {
|
||||
if (ksh_isdigit(qval[0])) {
|
||||
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;
|
||||
} else if (qval[1] == '\0') switch (qval[0]) {
|
||||
else if (qval[1] == '\0') switch (c) {
|
||||
case '$':
|
||||
case '!':
|
||||
case '?':
|
||||
|
Loading…
x
Reference in New Issue
Block a user