Please review changes against upstream code using SCM,
see the Vcs-* tags in debian/control for its location.

--- mksh-57.orig/Build.sh
+++ mksh-57/Build.sh
@@ -1,8 +1,8 @@
 #!/bin/sh
-srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.734 2019/03/01 16:18:13 tg Exp $'
+srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.744 2019/09/05 14:32:04 tg Exp $'
 #-
 # Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
-#		2011, 2012, 2013, 2014, 2015, 2016, 2017
+#		2011, 2012, 2013, 2014, 2015, 2016, 2017, 2019
 #	mirabilos <m@mirbsd.org>
 #
 # Provided that these terms and disclaimer and all copyright notices
@@ -25,8 +25,8 @@ srcversion='$MirOS: src/bin/mksh/Build.s
 #
 # Used environment documentation is at the end of this file.
 
-LC_ALL=C
-export LC_ALL
+LC_ALL=C; LANGUAGE=C
+export LC_ALL; unset LANGUAGE
 
 case $ZSH_VERSION:$VERSION in
 :zsh*) ZSH_VERSION=2 ;;
@@ -234,7 +234,7 @@ vq() {
 rmf() {
 	for _f in "$@"; do
 		case $_f in
-		Build.sh|check.pl|check.t|dot.mkshrc|*.1|*.c|*.h|*.ico|*.opt) ;;
+		*.1|*.ico) ;;
 		*) rm -f "$_f" ;;
 		esac
 	done
@@ -512,7 +512,7 @@ ebcdic=false
 for i
 do
 	case $last:$i in
-	c:combine|c:dragonegg|c:llvm|c:lto)
+	c:dragonegg|c:llvm)
 		cm=$i
 		last=
 		;;
@@ -524,10 +524,6 @@ do
 		optflags=$i
 		last=
 		;;
-	t:*)
-		tfn=$i
-		last=
-		;;
 	:-c)
 		last=c
 		;;
@@ -573,9 +569,6 @@ do
 	:+T)
 		textmode=0
 		;;
-	:-t)
-		last=t
-		;;
 	:-v)
 		echo "Build.sh $srcversion"
 		echo "for mksh $dstversion"
@@ -652,7 +645,7 @@ oswarn=
 ccpc=-Wc,
 ccpl=-Wl,
 tsts=
-ccpr='|| for _f in ${tcfn}*; do case $_f in Build.sh|check.pl|check.t|dot.mkshrc|*.1|*.c|*.h|*.ico|*.opt) ;; *) rm -f "$_f" ;; esac; done'
+ccpr='|| for _f in ${tcfn}*; do case $_f in *.1|*.ico) ;; *) rm -f "$_f" ;; esac; done'
 
 # Evil hack
 if test x"$TARGET_OS" = x"Android"; then
@@ -847,6 +840,11 @@ Linux)
 LynxOS)
 	oswarn="; it has minor issues"
 	;;
+midipix)
+	add_cppflags -D_GNU_SOURCE
+	# their Perl (currently…) identifies as os:linux ☹
+	check_categories="$check_categories os:midipix"
+	;;
 MidnightBSD)
 	;;
 Minix-vmd)
@@ -1088,7 +1086,8 @@ test -z "$oswarn" || echo >&2 "
 Warning: mksh has not yet been ported to or tested on your
 operating system '$TARGET_OS'$oswarn. If you can provide
 a shell account to the developer, this may improve; please
-drop us a success or failure notice or even send in diffs.
+drop us a success or failure notice or even send in diffs,
+at the very least, complete logs (Build.sh + test.sh) will help.
 "
 $e "$bi$me: Building the MirBSD Korn Shell$ao $ui$dstversion$ao on $TARGET_OS ${TARGET_OSREV}..."
 
@@ -1230,9 +1229,8 @@ dmc)
 	;;
 gcc)
 	vv '|' "$CC $CFLAGS $CPPFLAGS $LDFLAGS $NOWARN -v conftest.c $LIBS"
-	vv '|' 'echo `$CC $CFLAGS $CPPFLAGS $LDFLAGS $NOWARN $LIBS \
-	    -dumpmachine` gcc`$CC $CFLAGS $CPPFLAGS $LDFLAGS $NOWARN \
-	    $LIBS -dumpversion`'
+	vv '|' 'eval echo "\`$CC $CFLAGS $CPPFLAGS $LDFLAGS $NOWARN $LIBS -dumpmachine\`" \
+		 "gcc\`$CC $CFLAGS $CPPFLAGS $LDFLAGS $NOWARN $LIBS -dumpversion\`"'
 	: "${HAVE_STRING_POOLING=i2}"
 	;;
 hpcc)
@@ -1376,14 +1374,14 @@ if ac_ifcpp 'if 0' compiler_fails '' \
 	case $ct in
 	dec)
 		CFLAGS="$CFLAGS ${ccpl}-non_shared"
-		ac_testn can_delexe compiler_fails 0 'for the -non_shared linker option' <<-EOF
+		ac_testn can_delexe compiler_fails 0 'for the -non_shared linker option' <<-'EOF'
 			#include <unistd.h>
 			int main(void) { return (isatty(0)); }
 		EOF
 		;;
 	dmc)
 		CFLAGS="$CFLAGS ${ccpl}/DELEXECUTABLE"
-		ac_testn can_delexe compiler_fails 0 'for the /DELEXECUTABLE linker option' <<-EOF
+		ac_testn can_delexe compiler_fails 0 'for the /DELEXECUTABLE linker option' <<-'EOF'
 			#include <unistd.h>
 			int main(void) { return (isatty(0)); }
 		EOF
@@ -1393,9 +1391,8 @@ if ac_ifcpp 'if 0' compiler_fails '' \
 		;;
 	esac
 	test 1 = $HAVE_CAN_DELEXE || CFLAGS=$save_CFLAGS
-	ac_testn compiler_still_fails '' 'if the compiler still does not fail correctly' <<-EOF
-	EOF
-	test 1 = $HAVE_COMPILER_STILL_FAILS && exit 1
+	ac_ifcpp 'if 0' compiler_still_fails \
+	    'if the compiler still does not fail correctly' && exit 1
 fi
 if ac_ifcpp 'ifdef __TINYC__' couldbe_tcc '!' compiler_known 0 \
     'if this could be tcc'; then
@@ -1526,6 +1523,7 @@ dmc)
 	ac_flags 1 schk "${ccpc}-s" 'for stack overflow checking'
 	;;
 gcc)
+	ac_flags 1 fnolto -fno-lto 'whether we can explicitly disable buggy GCC LTO' -fno-lto
 	# The following tests run with -Werror (gcc only) if possible
 	NOWARN=$DOWARN; phase=u
 	ac_flags 1 wnodeprecateddecls -Wno-deprecated-declarations
@@ -1708,7 +1706,7 @@ ac_test attribute_format '' 'for __attri
 	#undef fprintf
 	extern int fprintf(FILE *, const char *format, ...)
 	    __attribute__((__format__(__printf__, 2, 3)));
-	int main(int ac, char **av) { return (fprintf(stderr, "%s%d", *av, ac)); }
+	int main(int ac, char *av[]) { return (fprintf(stderr, "%s%d", *av, ac)); }
 	#endif
 EOF
 ac_test attribute_noreturn '' 'for __attribute__((__noreturn__))' <<-'EOF'
@@ -1733,7 +1731,7 @@ ac_test attribute_pure '' 'for __attribu
 	#include <unistd.h>
 	#undef __attribute__
 	int foo(const char *) __attribute__((__pure__));
-	int main(int ac, char **av) { return (foo(av[ac - 1]) + isatty(0)); }
+	int main(int ac, char *av[]) { return (foo(av[ac - 1]) + isatty(0)); }
 	int foo(const char *s) { return ((int)s[0]); }
 	#endif
 EOF
@@ -1745,7 +1743,7 @@ ac_test attribute_unused '' 'for __attri
 	#else
 	#include <unistd.h>
 	#undef __attribute__
-	int main(int ac __attribute__((__unused__)), char **av
+	int main(int ac __attribute__((__unused__)), char *av[]
 	    __attribute__((__unused__))) { return (isatty(0)); }
 	#endif
 EOF
@@ -1863,22 +1861,22 @@ rmf lft*	# end of large file support tes
 ac_test can_inttypes '!' stdint_h 1 "for standard 32-bit integer types" <<-'EOF'
 	#include <sys/types.h>
 	#include <stddef.h>
-	int main(int ac, char **av) { return ((uint32_t)(size_t)*av + (int32_t)ac); }
+	int main(int ac, char *av[]) { return ((uint32_t)(size_t)*av + (int32_t)ac); }
 EOF
 ac_test can_ucbints '!' can_inttypes 1 "for UCB 32-bit integer types" <<-'EOF'
 	#include <sys/types.h>
 	#include <stddef.h>
-	int main(int ac, char **av) { return ((u_int32_t)(size_t)*av + (int32_t)ac); }
+	int main(int ac, char *av[]) { return ((u_int32_t)(size_t)*av + (int32_t)ac); }
 EOF
 ac_test can_int8type '!' stdint_h 1 "for standard 8-bit integer type" <<-'EOF'
 	#include <sys/types.h>
 	#include <stddef.h>
-	int main(int ac, char **av) { return ((uint8_t)(size_t)av[ac]); }
+	int main(int ac, char *av[]) { return ((uint8_t)(size_t)av[ac]); }
 EOF
 ac_test can_ucbint8 '!' can_int8type 1 "for UCB 8-bit integer type" <<-'EOF'
 	#include <sys/types.h>
 	#include <stddef.h>
-	int main(int ac, char **av) { return ((u_int8_t)(size_t)av[ac]); }
+	int main(int ac, char *av[]) { return ((u_int8_t)(size_t)av[ac]); }
 EOF
 
 ac_test rlim_t <<-'EOF'
@@ -1948,7 +1946,11 @@ else
 		#define MKSH_INCLUDES_ONLY
 		#include "sh.h"
 		__RCSID("$srcversion");
-		int main(void) { printf("Hello, World!\\n"); return (isatty(0)); }
+		int main(void) {
+			struct timeval tv;
+			printf("Hello, World!\\n");
+			return (time(&tv.tv_sec));
+		}
 EOF
 	case $cm in
 	llvm)
@@ -2005,15 +2007,15 @@ ac_cppflags SYS_ERRLIST
 
 for what in name list; do
 	uwhat=`upper $what`
-	ac_testn sys_sig$what '' "the sys_sig${what}[] array" <<-EOF
-		extern const char * const sys_sig${what}[];
+	ac_testn sys_sig$what '' "the sys_sig$what[] array" <<-EOF
+		extern const char * const sys_sig$what[];
 		extern int isatty(int);
-		int main(void) { return (sys_sig${what}[0][0] + isatty(0)); }
+		int main(void) { return (sys_sig$what[0][0] + isatty(0)); }
 	EOF
-	ac_testn _sys_sig$what '!' sys_sig$what 0 "the _sys_sig${what}[] array" <<-EOF
-		extern const char * const _sys_sig${what}[];
+	ac_testn _sys_sig$what '!' sys_sig$what 0 "the _sys_sig$what[] array" <<-EOF
+		extern const char * const _sys_sig$what[];
 		extern int isatty(int);
-		int main(void) { return (_sys_sig${what}[0][0] + isatty(0)); }
+		int main(void) { return (_sys_sig$what[0][0] + isatty(0)); }
 	EOF
 	eval uwhat_v=\$HAVE__SYS_SIG$uwhat
 	if test 1 = "$uwhat_v"; then
@@ -2614,8 +2616,8 @@ INDSRCS=	$extras
 NONSRCS_INST=	dot.mkshrc \$(MAN)
 NONSRCS_NOINST=	Build.sh Makefile Rebuild.sh check.pl check.t test.sh
 CC=		$CC
-CFLAGS=		$CFLAGS
 CPPFLAGS=	$CPPFLAGS
+CFLAGS=		$CFLAGS
 LDFLAGS=	$LDFLAGS
 LIBS=		$LIBS
 
@@ -2740,6 +2742,7 @@ HAVE_CAN_FSTACKPROTECTORALL	ac_flags
 ==== cpp definitions ====
 DEBUG				dont use in production, wants gcc, implies:
 DEBUG_LEAKS			enable freeing resources before exiting
+KSH_VERSIONNAME_VENDOR_EXT	when patching; space+plus+word (e.g. " +SuSE")
 MKSHRC_PATH			"~/.mkshrc" (do not change)
 MKSH_A4PB			force use of arc4random_pushb
 MKSH_ASSUME_UTF8		(0=disabled, 1=enabled; default: unset)
@@ -2777,7 +2780,7 @@ them, set to a value other than 0 or 1.
 MKSH_SMALL but with Vi mode, add -DMKSH_S_NOVI=0 to CPPFLAGS as well.
 
 Normally, the following command is what you want to run, then:
-$ (sh Build.sh -r -c lto && ./test.sh -f) 2>&1 | tee log
+$ (sh Build.sh -r && ./test.sh -f) 2>&1 | tee log
 
 Copy dot.mkshrc to /etc/skel/.mkshrc; install mksh into $prefix/bin; or
 /bin; install the manpage, if omitting the -r flag a catmanpage is made
@@ -2786,6 +2789,6 @@ http://anonscm.debian.org/cgit/collab-ma
 and put dot.mkshrc as /etc/mkshrc so users need not keep up their HOME.
 
 You may also want to install the lksh binary (also as /bin/sh) built by:
-$ CPPFLAGS="$CPPFLAGS -DMKSH_BINSHPOSIX" sh Build.sh -L -r -c lto
+$ CPPFLAGS="$CPPFLAGS -DMKSH_BINSHPOSIX" sh Build.sh -L -r
 
 EOD
--- mksh-57.orig/check.pl
+++ mksh-57/check.pl
@@ -1,4 +1,4 @@
-# $MirOS: src/bin/mksh/check.pl,v 1.49 2017/05/05 21:17:31 tg Exp $
+# $MirOS: src/bin/mksh/check.pl,v 1.50 2019/08/01 20:05:55 tg Exp $
 # $OpenBSD: th,v 1.1 2013/12/02 20:39:44 millert Exp $
 #-
 # Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011,
@@ -292,7 +292,7 @@ $all_tests = @ARGV == 0;
 # Set up a very minimal environment
 %new_env = ();
 foreach $env (('HOME', 'LD_LIBRARY_PATH', 'LOCPATH', 'LOGNAME',
-  'PATH', 'SHELL', 'UNIXMODE', 'UNIXROOT', 'USER')) {
+  'PATH', 'PERLIO', 'SHELL', 'UNIXMODE', 'UNIXROOT', 'USER')) {
     $new_env{$env} = $ENV{$env} if defined $ENV{$env};
 }
 $new_env{'CYGWIN'} = 'nodosfilewarning';
--- mksh-57.orig/check.t
+++ mksh-57/check.t
@@ -1,4 +1,4 @@
-# $MirOS: src/bin/mksh/check.t,v 1.812 2019/03/01 16:17:29 tg Exp $
+# $MirOS: src/bin/mksh/check.t,v 1.824 2019/10/24 00:12:42 tg Exp $
 # -*- mode: sh -*-
 #-
 # Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
@@ -31,7 +31,7 @@
 # (2013/12/02 20:39:44) http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/regress/bin/ksh/?sortby=date
 
 expected-stdout:
-	@(#)MIRBSD KSH R57 2019/03/01
+	@(#)MIRBSD KSH R57 2019/08/02
 description:
 	Check base version of full shell
 stdin:
@@ -40,7 +40,7 @@ name: KSH_VERSION
 category: !shell:legacy-yes
 ---
 expected-stdout:
-	@(#)LEGACY KSH R57 2019/03/01
+	@(#)LEGACY KSH R57 2019/08/02
 description:
 	Check base version of legacy shell
 stdin:
@@ -178,7 +178,7 @@ stdin:
 expected-stdout:
 	ok
 expected-stderr-pattern:
-	/mksh: warning: won't have full job control\nXX/
+	/ksh: warning: won't have full job control\nXX/
 ---
 name: selftest-tty-present
 description:
@@ -1392,7 +1392,7 @@ need-pass: no
 # the mv command fails on Cygwin and z/OS
 # Hurd aborts the testsuite (permission denied)
 # QNX does not find subdir to cd into
-category: !os:cygwin,!os:gnu,!os:msys,!os:nto,!os:os390,!nosymlink
+category: !os:cygwin,!os:gnu,!os:midipix,!os:msys,!os:nto,!os:os390,!nosymlink
 file-setup: file 644 "x"
 	mkdir noread noread/target noread/target/subdir
 	ln -s noread link
@@ -1999,7 +1999,7 @@ expected-stdout:
 name: eglob-bad-1
 description:
 	Check that globbing isn't done when glob has syntax error
-category: !os:cygwin,!os:msys,!os:os2
+category: !os:cygwin,!os:midipix,!os:msys,!os:os2
 file-setup: file 644 "@(a[b|)c]foo"
 stdin:
 	echo @(a[b|)c]*
@@ -2491,7 +2491,7 @@ description:
 # breaks on Mac OSX (HFS+ non-standard UTF-8 canonical decomposition)
 # breaks on Cygwin 1.7 (files are now UTF-16 or something)
 # breaks on QNX 6.4.1 (says RT)
-category: !os:cygwin,!os:darwin,!os:msys,!os:nto,!os:os2,!os:os390
+category: !os:cygwin,!os:midipix,!os:darwin,!os:msys,!os:nto,!os:os2,!os:os390
 need-pass: no
 file-setup: file 644 "ac"
 stdin:
@@ -7389,6 +7389,8 @@ expected-stdout:
 name: xxx-stat-1
 description:
 	Check that tests on files are consistent
+	(fails when run as root, unfortunately)
+category: disabled
 stdin:
 	mkdir a
 	echo x >a/b
@@ -8672,7 +8674,7 @@ description:
 	note: Ultrix perl5 t4 returns 65280 (exit-code 255) and no text
 	XXX fails when LD_PRELOAD is set with -e and Perl chokes it (ASan)
 need-pass: no
-category: !os:cygwin,!os:msys,!os:ultrix,!os:uwin-nt,!smksh
+category: !os:cygwin,!os:midipix,!os:msys,!os:ultrix,!os:uwin-nt,!smksh
 env-setup: !FOO=BAR!
 stdin:
 	print '#!'"$__progname"'\nprint "1 a=$ENV{FOO}";' >t1
@@ -10841,6 +10843,43 @@ stdin:
 expected-stdout:
 	okay
 ---
+name: ulimit-3
+description:
+	Check that there are no duplicate limits (if this fails,
+	immediately contact with system information the developers)
+stdin:
+	[[ -z $(set | grep ^opt) ]]; mis=$?
+	set | grep ^opt | sed 's/^/unexpectedly set in environment: /'
+	opta='<used for showing all limits>'
+	optH='<used to set hard limits>'
+	optS='<used to set soft limits>'
+	ulimit -a >tmpf
+	set -o noglob
+	while IFS= read -r line; do
+		x=${line:1:1}
+		if [[ -z $x || ${#x}/${%x} != 1/1 ]]; then
+			print -r -- "weird line: $line"
+			(( mis |= 1 ))
+			continue
+		fi
+		set -- $line
+		nameref v=opt$x
+		if [[ -n $v ]]; then
+			print -r -- "duplicate -$x \"$2\" already seen as \"$v\""
+			(( mis |= 2 ))
+		fi
+		v=$2
+	done <tmpf
+	if (( mis & 2 )); then
+		echo failed
+	elif (( mis & 1 )); then
+		echo inconclusive
+	else
+		echo done
+	fi
+expected-stdout:
+	done
+---
 name: redir-1
 description:
 	Check some of the most basic invariants of I/O redirection
@@ -12659,7 +12698,7 @@ stdin:
 	echo =14
 	(mypid=$$; try mypid)
 	echo =15
-	) 2>&1 | sed -e 's/^[^]]*]//' -e 's/^[^:]*: *//'
+	) 2>&1 | sed -e 's/^[A-Za-z]://' -e 's/^[^]]*]//' -e 's/^[^:]*: *//'
 	exit ${PIPESTATUS[0]}
 expected-stdout:
 	y
@@ -13362,6 +13401,59 @@ expected-stdout:
 	after	0='swc' 1='二' 2=''
 	= done
 ---
+name: command-set
+description:
+	Same but with set
+stdin:
+	showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
+	showargs 1 "$@"
+	set -- foo bar baz
+	showargs 2 "$@"
+	command set -- miau 'meow nyao'
+	showargs 3 "$@"
+expected-stdout:
+	<1> .
+	<2> <foo> <bar> <baz> .
+	<3> <miau> <meow nyao> .
+---
+name: command-readonly
+description:
+	These should not exit on error when prefixed
+stdin:
+	exec 2>/dev/null
+	"$__progname" -c 'readonly v; export v=foo || echo ok'
+	echo ef=$?
+	"$__progname" -c 'readonly v; command export v=foo || echo ok'
+	echo en=$?
+	"$__progname" -c 'readonly v; readonly v=foo || echo ok'
+	echo rf=$?
+	"$__progname" -c 'readonly v; command readonly v=foo || echo ok'
+	echo rn=$?
+expected-stdout:
+	ef=2
+	ok
+	en=0
+	rf=2
+	ok
+	rn=0
+---
+name: command-dot-regression
+description:
+	Check a regression in fixing the above does not appear
+stdin:
+	cat >test.mksh <<\EOF
+	set -- one two
+	shift
+	for s_arg in "$#" "$@"; do echo -n "<$s_arg> "; done; echo .
+	EOF
+	"$__progname" -c '. ./test.mksh' dummy oh dear this is not good
+	echo =
+	"$__progname" -c 'command . ./test.mksh' dummy oh dear this is not good
+expected-stdout:
+	<1> <two> .
+	=
+	<1> <two> .
+---
 name: command-pvV-posix-priorities
 description:
 	For POSIX compatibility, command -v should find aliases and reserved
--- mksh-57.orig/dot.mkshrc
+++ mksh-57/dot.mkshrc
@@ -1,8 +1,8 @@
 # $Id$
-# $MirOS: src/bin/mksh/dot.mkshrc,v 1.121 2017/08/08 21:10:21 tg Exp $
+# $MirOS: src/bin/mksh/dot.mkshrc,v 1.124 2019/09/25 22:50:11 tg Exp $
 #-
 # Copyright (c) 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010,
-#		2011, 2012, 2013, 2014, 2015, 2016, 2017
+#		2011, 2012, 2013, 2014, 2015, 2016, 2017, 2019
 #	mirabilos <m@mirbsd.org>
 #
 # Provided that these terms and disclaimer and all copyright notices
@@ -64,11 +64,10 @@ for EDITOR in "${EDITOR:-}" jupp jstar m
 done
 
 \\builtin alias ls=ls l='ls -F' la='l -a' ll='l -l' lo='l -alo'
-\: "${HOSTNAME:=$(\\builtin ulimit -c 0; \\builtin print -r -- $(hostname \
-    2>/dev/null))}${EDITOR:=/bin/ed}${TERM:=vt100}${USER:=$(\\builtin ulimit \
-    -c 0; id -un 2>/dev/null)}${USER:=?}"
+\: "${EDITOR:=/bin/ed}${TERM:=vt100}${USER:=$(\\builtin ulimit -c 0; id -un \
+    2>/dev/null)}${HOSTNAME:=$(\\builtin ulimit -c 0; hostname 2>/dev/null)}"
 [[ $HOSTNAME = ?(?(ip6-)localhost?(6)) ]] && HOSTNAME=nil; \\builtin unalias ls
-\\builtin export EDITOR HOSTNAME TERM USER
+\\builtin export EDITOR HOSTNAME TERM USER="${USER:-?}"
 
 # minimal support for lksh users
 if [[ $KSH_VERSION = *LEGACY\ KSH* ]]; then
@@ -604,7 +603,7 @@ function enable {
 
 \: place customisations below this line
 
-# some defaults follow — you are supposed to adjust these to your
+# some defaults/samples — you are supposed to adjust these to your
 # liking; by default we add ~/.etc/bin and ~/bin (whichever exist)
 # to $PATH, set $SHELL to mksh, set some defaults for man and less
 # and show a few more possible things for users to begin moving in
@@ -618,11 +617,15 @@ done
 \\builtin export SHELL=$MKSH MANWIDTH=80 LESSHISTFILE=-
 \\builtin alias cls='\\builtin print -n \\ec'
 
-#\\builtin unset LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_IDENTIFICATION LC_MONETARY \
-#    LC_NAME LC_NUMERIC LC_TELEPHONE LC_TIME
+#\\builtin unset LC_ADDRESS LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+#    LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+#    LC_TELEPHONE LC_TIME LANGUAGE LANG LC_ALL
 #p=en_GB.UTF-8
 #\\builtin export LANG=C LC_CTYPE=$p LC_MEASUREMENT=$p LC_MESSAGES=$p LC_PAPER=$p
+#\\builtin export LANG=C.UTF-8 LC_CTYPE=C.UTF-8
+#\\builtin export LC_ALL=C.UTF-8
 #\\builtin set -U
+#[[ ${LC_ALL:-${LC_CTYPE:-${LANG:-}}} = *[Uu][Tt][Ff]?(-)8* ]] || \\builtin set +U
 
 \\builtin unset p
 
--- mksh-57.orig/exec.c
+++ mksh-57/exec.c
@@ -24,7 +24,7 @@
 
 #include "sh.h"
 
-__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.206 2019/03/01 16:17:53 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.210 2019/08/02 19:27:15 tg Exp $");
 
 #ifndef MKSH_DEFAULT_EXECSHELL
 #define MKSH_DEFAULT_EXECSHELL	MKSH_UNIXROOT "/bin/sh"
@@ -446,7 +446,7 @@ execute(struct op * volatile t,
 		if (rv == ENOEXEC)
 			scriptexec(t, (const char **)up);
 		else
-			errorf(Tf_sD_s, t->str, cstrerror(rv));
+			errorfx(126, Tf_sD_s, t->str, cstrerror(rv));
 	}
  Break:
 	exstat = rv & 0xFF;
@@ -694,11 +694,9 @@ comexec(struct op *t, struct tbl * volat
 	/* shell built-in */
 	case CSHELL:
  do_call_builtin:
+		if (l_expand != l_assign)
+			l_assign->flags |= (tp->flag & NEXTLOC_BI);
 		rv = call_builtin(tp, (const char **)ap, null, resetspec);
-		if (resetspec && tp->val.f == c_shift) {
-			l_expand->argc = l_assign->argc;
-			l_expand->argv = l_assign->argv;
-		}
 		break;
 
 	/* function call */
@@ -1147,6 +1145,10 @@ builtin(const char *name, int (*func) (c
 		/* is declaration utility (POSIX: export, readonly) */
 		flag |= DECL_UTIL;
 		break;
+	case '#':
+		/* is set or shift */
+		flag |= NEXTLOC_BI;
+		break;
 	default:
 		goto flags_seen;
 	}
--- mksh-57.orig/funcs.c
+++ mksh-57/funcs.c
@@ -5,7 +5,8 @@
 
 /*-
  * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
- *		 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017
+ *		 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017,
+ *		 2019
  *	mirabilos <m@mirbsd.org>
  *
  * Provided that these terms and disclaimer and all copyright notices
@@ -38,7 +39,7 @@
 #endif
 #endif
 
-__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.355 2018/10/20 21:04:28 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.357 2019/08/02 19:27:15 tg Exp $");
 
 #if HAVE_KILLPG
 /*
@@ -129,8 +130,8 @@ const struct builtin mkshbuiltins[] = {
 	{"!realpath", c_realpath},
 	{"~rename", c_rename},
 	{"*=return", c_exitreturn},
-	{Tsgset, c_set},
-	{"*=shift", c_shift},
+	{Tsghset, c_set},
+	{"*=#shift", c_shift},
 	{Tgsource, c_dot},
 #if !defined(MKSH_UNEMPLOYED) && HAVE_GETSID
 	{Tsuspend, c_suspend},
@@ -1347,10 +1348,17 @@ c_bind(const char **wp)
 int
 c_shift(const char **wp)
 {
-	struct block *l = e->loc;
 	int n;
 	mksh_ari_t val;
 	const char *arg;
+	struct block *l = e->loc;
+
+	if ((l->flags & BF_RESETSPEC)) {
+		/* prevent pollution */
+		l->flags &= ~BF_RESETSPEC;
+		/* operate on parent environment */
+		l = l->next;
+	}
 
 	if (ksh_getopt(wp, &builtin_opt, null) == '?')
 		return (1);
@@ -1369,6 +1377,7 @@ c_shift(const char **wp)
 		bi_errorf(Tf_sD_s, Tbadnum, arg);
 		return (1);
 	}
+
 	if (l->argc < n) {
 		bi_errorf("nothing to shift");
 		return (1);
@@ -2231,7 +2240,13 @@ c_set(const char **wp)
 	int argi;
 	bool setargs;
 	struct block *l = e->loc;
-	const char **owp;
+
+	if ((l->flags & BF_RESETSPEC)) {
+		/* prevent pollution */
+		l->flags &= ~BF_RESETSPEC;
+		/* operate on parent environment */
+		l = l->next;
+	}
 
 	if (wp[1] == NULL) {
 		static const char *args[] = { Tset, "-", NULL };
@@ -2242,6 +2257,8 @@ c_set(const char **wp)
 		return (2);
 	/* set $# and $* */
 	if (setargs) {
+		const char **owp;
+
 		wp += argi - 1;
 		owp = wp;
 		/* save $0 */
--- mksh-57.orig/histrap.c
+++ mksh-57/histrap.c
@@ -3,7 +3,7 @@
 
 /*-
  * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
- *		 2011, 2012, 2014, 2015, 2016, 2017, 2018
+ *		 2011, 2012, 2014, 2015, 2016, 2017, 2018, 2019
  *	mirabilos <m@mirbsd.org>
  *
  * Provided that these terms and disclaimer and all copyright notices
@@ -27,7 +27,7 @@
 #include <sys/file.h>
 #endif
 
-__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.167 2018/04/28 17:16:54 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.169 2019/09/16 21:10:33 tg Exp $");
 
 Trap sigtraps[ksh_NSIG + 1];
 static struct sigaction Sigact_ign;
@@ -504,6 +504,8 @@ findhist(int start, int fwd, const char
 void
 sethistsize(mksh_ari_t n)
 {
+	if (n > 65535)
+		n = 65535;
 	if (n > 0 && n != histsize) {
 		int cursize = histptr - history;
 
--- mksh-57.orig/main.c
+++ mksh-57/main.c
@@ -35,7 +35,7 @@
 #include <locale.h>
 #endif
 
-__RCSID("$MirOS: src/bin/mksh/main.c,v 1.351 2019/01/05 13:24:18 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/main.c,v 1.352 2019/08/02 00:21:53 tg Exp $");
 
 #ifndef MKSHRC_PATH
 #define MKSHRC_PATH	"~/.mkshrc"
@@ -1329,6 +1329,39 @@ bi_errorf(const char *fmt, ...)
 		unwind(LERROR);
 	}
 }
+
+/*
+ * Used by functions called by builtins and not:
+ * identical to errorfx if first argument is nil,
+ * like bi_errorf storing the errorlevel into it otherwise
+ */
+void
+maybe_errorf(int *ep, int rc, const char *fmt, ...)
+{
+	va_list va;
+
+	/* debugging: note that stdout not valid */
+	shl_stdout_ok = false;
+
+	exstat = rc;
+
+	va_start(va, fmt);
+	vwarningf(VWARNINGF_ERRORPREFIX | VWARNINGF_FILELINE |
+	    (ep ? VWARNINGF_BUILTIN : 0), fmt, va);
+	va_end(va);
+
+	if (!ep)
+		goto and_out;
+	*ep = rc;
+
+	/* POSIX special builtins cause non-interactive shells to exit */
+	if (builtin_spec) {
+		builtin_argv0 = NULL;
+		/* may not want to use LERROR here */
+ and_out:
+		unwind(LERROR);
+	}
+}
 
 /* Called when something that shouldn't happen does */
 void
--- mksh-57.orig/mksh.1
+++ mksh-57/mksh.1
@@ -1,4 +1,4 @@
-.\" $MirOS: src/bin/mksh/mksh.1,v 1.463 2019/03/01 16:17:31 tg Exp $
+.\" $MirOS: src/bin/mksh/mksh.1,v 1.466 2019/09/10 19:52:53 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,
@@ -77,7 +77,7 @@
 .\" with -mandoc, it might implement .Mx itself, but we want to
 .\" use our own definition. And .Dd must come *first*, always.
 .\"
-.Dd $Mdocdate: March 1 2019 $
+.Dd $Mdocdate: September 10 2019 $
 .\"
 .\" Check which macro package we use, and do other -mdoc setup.
 .\"
@@ -1924,9 +1924,7 @@ This is different from
 .It Ev HISTSIZE
 The number of commands normally stored for history.
 The default is 2047.
-Do not set this value to insanely high values such as 1000000000 because
-.Nm
-can then not allocate enough memory for the history and will not start.
+The maximum is 65535.
 .It Ev HOME
 The default directory for the
 .Ic cd
@@ -5005,7 +5003,7 @@ unless they are also given on the same c
 .Pp
 .It Xo
 .Ic ulimit
-.Op Fl aBCcdefHilMmnOPpqrSsTtVvw
+.Op Fl aBCcdefHilMmnOPpqrSsTtVvwx
 .Op Ar value
 .Xc
 Display or set process limits.
@@ -5078,6 +5076,17 @@ Set the number of AIO operations to
 .It Fl P Ar n
 Limit the number of threads per process to
 .Ar n .
+.Pp
+This option mostly matches
+.At
+.Nm ksh93 Ns 's
+.Fl T ;
+on
+.Tn AIX ,
+see
+.Fl r
+.Pq as used by its Nm ksh
+though.
 .It Fl p Ar n
 Impose a limit of
 .Ar n
@@ -5089,6 +5098,11 @@ message queues to
 .Ar n
 bytes.
 .It Fl r Ar n
+.Pq Cm AIX
+Limit the number of threads per process to
+.Ar n .
+.br
+.Pq Cm Linux
 Set the maximum real-time priority to
 .Ar n .
 .It Fl S
@@ -5116,6 +5130,9 @@ kibibytes on the amount of virtual memor
 Impose a limit of
 .Ar n
 kibibytes on the amount of swap space used.
+.It Fl x Ar n
+Set the maximum number of file locks to
+.Ar n .
 .El
 .Pp
 As far as
@@ -6719,7 +6736,7 @@ Using
 .Ic set Fl o Ic pipefail
 makes the following construct error out:
 .Bd -literal -offset indent
-set -e
+set \-e
 for x in 1 2; do
 	false && echo $x
 done \*(Ba cat
--- mksh-57.orig/os2.c
+++ mksh-57/os2.c
@@ -20,6 +20,7 @@
  * of said person's immediate fault when using the work as intended.
  */
 
+#define INCL_KBD
 #define INCL_DOS
 #include <os2.h>
 
@@ -31,7 +32,7 @@
 #include <unistd.h>
 #include <process.h>
 
-__RCSID("$MirOS: src/bin/mksh/os2.c,v 1.8 2017/12/22 16:41:42 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/os2.c,v 1.9 2019/08/01 20:05:01 tg Exp $");
 
 static char *remove_trailing_dots(char *);
 static int access_stat_ex(int (*)(), const char *, void *);
@@ -172,6 +173,8 @@ init_extlibpath(void)
 void
 os2_init(int *argcp, const char ***argvp)
 {
+	KBDINFO ki;
+
 	response(argcp, argvp);
 
 	init_extlibpath();
@@ -183,6 +186,12 @@ os2_init(int *argcp, const char ***argvp
 	if (!isatty(STDERR_FILENO))
 		setmode(STDERR_FILENO, O_BINARY);
 
+	/* ensure ECHO mode is ON so that read command echoes. */
+	memset(&ki, 0, sizeof(ki));
+	ki.cb = sizeof(ki);
+	ki.fsMask |= KEYBOARD_ECHO_ON;
+	KbdSetStatus(&ki, 0);
+
 	atexit(cleanup);
 }
 
--- mksh-57.orig/rlimits.opt
+++ mksh-57/rlimits.opt
@@ -19,7 +19,7 @@
  */
 
 @RLIMITS_DEFNS
-__RCSID("$MirOS: src/bin/mksh/rlimits.opt,v 1.3 2015/12/12 21:08:44 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/rlimits.opt,v 1.4 2019/04/24 20:56:31 tg Exp $");
 @RLIMITS_ITEMS
 #define FN(lname,lid,lfac,lopt) (const struct limits *)(&rlimits_ ## lid),
 @@
@@ -86,6 +86,9 @@ FN("sockbufsiz(KiB)", RLIMIT_SBSIZE, 102
 >P|RLIMIT_PTHREAD
 FN("threadsperprocess", RLIMIT_PTHREAD, 1
 
+>r|RLIMIT_THREADS
+FN("threadsperprocess", RLIMIT_THREADS, 1
+
 >e|RLIMIT_NICE
 FN("maxnice", RLIMIT_NICE, 1
 
@@ -102,4 +105,7 @@ FN("virtual-memory(KiB)", RLIMIT_VMEM, 1
 >v|ULIMIT_V_IS_AS
 FN("address-space(KiB)", RLIMIT_AS, 1024
 
+>x|RLIMIT_LOCKS
+FN("filelocks", RLIMIT_LOCKS, 1
+
 |RLIMITS_OPTCS
--- mksh-57.orig/sh.h
+++ mksh-57/sh.h
@@ -182,9 +182,9 @@
 #endif
 
 #ifdef EXTERN
-__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.870 2019/03/01 16:18:14 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.873 2019/08/02 19:27:17 tg Exp $");
 #endif
-#define MKSH_VERSION "R57 2019/03/01"
+#define MKSH_VERSION "R57 2019/08/02"
 
 /* arithmetic types: C implementation */
 #if !HAVE_CAN_INTTYPES
@@ -999,8 +999,8 @@ EXTERN const char Tredirection_dup[] E_I
 EXTERN const char Treal_sp2[] E_INIT(" real ");
 EXTERN const char Treq_arg[] E_INIT("requires an argument");
 EXTERN const char Tselect[] E_INIT("select");
-EXTERN const char Tsgset[] E_INIT("*=set");
 #define Tset (Tf_parm + 18)
+EXTERN const char Tsghset[] E_INIT("*=#set");
 #define Tsh (Tmksh + 2)
 #define TSHELL (TEXECSHELL + 4)
 #define Tshell (Ttoo_many_files + 23)
@@ -1160,8 +1160,8 @@ EXTERN const char T_devtty[] E_INIT("/de
 #define Treal_sp2 " real "
 #define Treq_arg "requires an argument"
 #define Tselect "select"
-#define Tsgset "*=set"
 #define Tset "set"
+#define Tsghset "*=#set"
 #define Tsh "sh"
 #define TSHELL "SHELL"
 #define Tshell "shell"
@@ -1756,6 +1756,7 @@ EXTERN bool last_lookup_was_array;
 #define LOW_BI		BIT(14)	/* external utility overrides built-in one */
 #define DECL_UTIL	BIT(15)	/* is declaration utility */
 #define DECL_FWDR	BIT(16) /* is declaration utility forwarder */
+#define NEXTLOC_BI	BIT(17)	/* needs BF_RESETSPEC on e->loc */
 
 /*
  * Attributes that can be set by the user (used to decide if an unset
@@ -1824,6 +1825,8 @@ struct block {
 /* Values for struct block.flags */
 #define BF_DOGETOPTS	BIT(0)	/* save/restore getopts state */
 #define BF_STOPENV	BIT(1)	/* do not export further */
+/* BF_RESETSPEC and NEXTLOC_BI must be numerically identical! */
+#define BF_RESETSPEC	BIT(17)	/* use ->next for set and shift */
 
 /*
  * Used by ktwalk() and ktnext() routines.
@@ -2511,6 +2514,8 @@ void warningf(bool, const char *, ...)
     MKSH_A_FORMAT(__printf__, 2, 3);
 void bi_errorf(const char *, ...)
     MKSH_A_FORMAT(__printf__, 1, 2);
+void maybe_errorf(int *, int, const char *, ...)
+    MKSH_A_FORMAT(__printf__, 3, 4);
 #define errorfz()	errorf(NULL)
 #define errorfxz(rc)	errorfx((rc), NULL)
 #define bi_errorfz()	bi_errorf(NULL)
--- mksh-57.orig/shf.c
+++ mksh-57/shf.c
@@ -2,7 +2,7 @@
 
 /*-
  * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011,
- *		 2012, 2013, 2015, 2016, 2017, 2018
+ *		 2012, 2013, 2015, 2016, 2017, 2018, 2019
  *	mirabilos <m@mirbsd.org>
  * Copyright (c) 2015
  *	Daniel Richard G. <skunk@iSKUNK.ORG>
@@ -27,7 +27,7 @@
 
 #include "sh.h"
 
-__RCSID("$MirOS: src/bin/mksh/shf.c,v 1.98 2018/08/10 02:53:39 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/shf.c,v 1.100 2019/08/01 20:10:57 tg Exp $");
 
 /* flags to shf_emptybuf() */
 #define EB_READSW	0x01	/* about to switch to reading */
@@ -523,7 +523,8 @@ shf_getse(char *buf, ssize_t bsize, stru
 		buf += ncopy;
 		bsize -= ncopy;
 #ifdef MKSH_WITH_TEXTMODE
-		if (end && buf > orig_buf + 1 && buf[-2] == '\r') {
+		if (buf > orig_buf + 1 && ord(buf[-2]) == ORD('\r') &&
+		    ord(buf[-1]) == ORD('\n')) {
 			buf--;
 			bsize++;
 			buf[-1] = '\n';
@@ -531,9 +532,9 @@ shf_getse(char *buf, ssize_t bsize, stru
 #endif
 	} while (!end && bsize);
 #ifdef MKSH_WITH_TEXTMODE
-	if (!bsize && buf[-1] == '\r') {
+	if (!bsize && ord(buf[-1]) == ORD('\r')) {
 		int c = shf_getc(shf);
-		if (c == '\n')
+		if (ord(c) == ORD('\n'))
 			buf[-1] = '\n';
 		else if (c != -1)
 			shf_ungetc(c, shf);
--- mksh-57.orig/var.c
+++ mksh-57/var.c
@@ -2,7 +2,8 @@
 
 /*-
  * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
- *		 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018
+ *		 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018,
+ *		 2019
  *	mirabilos <m@mirbsd.org>
  *
  * Provided that these terms and disclaimer and all copyright notices
@@ -28,7 +29,7 @@
 #include <sys/sysctl.h>
 #endif
 
-__RCSID("$MirOS: src/bin/mksh/var.c,v 1.226 2018/07/15 17:21:24 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/var.c,v 1.227 2019/08/02 00:21:53 tg Exp $");
 
 /*-
  * Variables
@@ -57,6 +58,7 @@ static void setspec(struct tbl *);
 static void unsetspec(struct tbl *, bool);
 static int getint(struct tbl *, mksh_ari_u *, bool);
 static const char *array_index_calc(const char *, bool *, uint32_t *);
+static struct tbl *vtypeset(int *, const char *, uint32_t, uint32_t, int, int);
 
 /*
  * create a new block for function calls and simple commands
@@ -757,6 +759,12 @@ exportprep(struct tbl *vp, const char *v
 struct tbl *
 typeset(const char *var, uint32_t set, uint32_t clr, int field, int base)
 {
+	return (vtypeset(NULL, var, set, clr, field, base));
+}
+static struct tbl *
+vtypeset(int *ep, const char *var, uint32_t set, uint32_t clr,
+    int field, int base)
+{
 	struct tbl *vp;
 	struct tbl *vpbase, *t;
 	char *tvar;
@@ -765,6 +773,9 @@ typeset(const char *var, uint32_t set, u
 	bool vappend = false;
 	enum namerefflag new_refflag = SRF_NOP;
 
+	if (ep)
+		*ep = 0;
+
 	if ((set & (ARRAY | ASSOC)) == ASSOC) {
 		new_refflag = SRF_ENABLE;
 		set &= ~(ARRAY | ASSOC);
@@ -782,8 +793,8 @@ typeset(const char *var, uint32_t set, u
 	}
 	if (ord(*val) == ORD('[')) {
 		if (new_refflag != SRF_NOP)
-			errorf(Tf_sD_s, var,
-			    "reference variable can't be an array");
+			return (maybe_errorf(ep, 1, Tf_sD_s, var,
+			    "reference variable can't be an array"), NULL);
 		len = array_ref_len(val);
 		if (len == 0)
 			return (NULL);
@@ -833,7 +844,8 @@ typeset(const char *var, uint32_t set, u
 
 		/* bail out on 'nameref foo+=bar' */
 		if (vappend)
-			errorf("appending not allowed for nameref");
+			return (maybe_errorf(ep, 1,
+			    "appending not allowed for nameref"), NULL);
 		/* find value if variable already exists */
 		if ((qval = val) == NULL) {
 			varsearch(e->loc, &vp, tvar, hash(tvar));
@@ -859,7 +871,8 @@ typeset(const char *var, uint32_t set, u
 				goto nameref_rhs_checked;
 			}
  nameref_empty:
-			errorf(Tf_sD_s, var, "empty nameref target");
+			return (maybe_errorf(ep, 1, Tf_sD_s, var,
+			    "empty nameref target"), NULL);
 		}
 		len = (ord(*ccp) == ORD('[')) ? array_ref_len(ccp) : 0;
 		if (ccp[len]) {
@@ -868,15 +881,15 @@ typeset(const char *var, uint32_t set, u
 			 * junk after it" and "invalid array"; in the
 			 * latter case, len is also 0 and points to '['
 			 */
-			errorf(Tf_sD_s, qval,
-			    "nameref target not a valid parameter name");
+			return (maybe_errorf(ep, 1, Tf_sD_s, qval,
+			    "nameref target not a valid parameter name"), NULL);
 		}
  nameref_rhs_checked:
 		/* prevent nameref loops */
 		while (qval) {
 			if (!strcmp(qval, tvar))
-				errorf(Tf_sD_s, qval,
-				    "expression recurses on parameter");
+				return (maybe_errorf(ep, 1, Tf_sD_s, qval,
+				    "expression recurses on parameter"), NULL);
 			varsearch(e->loc, &vp, qval, hash(qval));
 			qval = NULL;
 			if (vp && ((vp->flag & (ARRAY | ASSOC)) == ASSOC))
@@ -887,7 +900,8 @@ typeset(const char *var, uint32_t set, u
 	/* prevent typeset from creating a local PATH/ENV/SHELL */
 	if (Flag(FRESTRICTED) && (strcmp(tvar, TPATH) == 0 ||
 	    strcmp(tvar, "ENV") == 0 || strcmp(tvar, TSHELL) == 0))
-		errorf(Tf_sD_s, tvar, "restricted");
+		return (maybe_errorf(ep, 1, Tf_sD_s,
+		    tvar, "restricted"), NULL);
 
 	innermost_refflag = new_refflag;
 	vp = (set & LOCAL) ? local(tvar, tobool(set & LOCAL_COPY)) :
@@ -923,8 +937,7 @@ typeset(const char *var, uint32_t set, u
 	 */
 	if ((vpbase->flag & RDONLY) &&
 	    (val || clr || (set & ~(EXPORT | RDONLY))))
-		/* XXX check calls - is error here ok by POSIX? */
-		errorfx(2, Tf_ro, tvar);
+		return (maybe_errorf(ep, 2, Tf_ro, tvar), NULL);
 	afree(tvar, ATEMP);
 
 	/* most calls are with set/clr == 0 */
@@ -990,7 +1003,7 @@ typeset(const char *var, uint32_t set, u
 			}
 		}
 		if (!ok)
-			errorfz();
+			return (maybe_errorf(ep, 1, NULL), NULL);
 	}
 
 	if (val != NULL) {
@@ -2026,7 +2039,7 @@ c_typeset(const char **wp)
 	if (wp[builtin_opt.optind] &&
 	    /* not "typeset -p varname" */
 	    !(!func && pflag && !(fset | fclr))) {
-		int rv = 0;
+		int rv = 0, x;
 		struct tbl *f;
 
 		if (localv && !func)
@@ -2049,7 +2062,10 @@ c_typeset(const char **wp)
 					    wp[i], f->val.t);
 					shf_putc('\n', shl_stdout);
 				}
-			} else if (!typeset(wp[i], fset, fclr, field, base)) {
+			} else if (!vtypeset(&x, wp[i], fset, fclr,
+			    field, base)) {
+				if (x)
+					return (x);
 				bi_errorf(Tf_sD_s, wp[i], Tnot_ident);
 				return (1);
 			}
