Merge "Upgrade to mksh R40."

This commit is contained in:
Treehugger Robot 2016-12-09 02:06:25 +00:00 committed by Gerrit Code Review
commit ceb0b57de2
20 changed files with 1025 additions and 739 deletions

View file

@ -83,6 +83,6 @@ LOCAL_CFLAGS += \
-DHAVE_SETGROUPS=1 -DHAVE_STRERROR=1 -DHAVE_STRSIGNAL=0 \ -DHAVE_SETGROUPS=1 -DHAVE_STRERROR=1 -DHAVE_STRSIGNAL=0 \
-DHAVE_STRLCPY=1 -DHAVE_FLOCK_DECL=1 -DHAVE_REVOKE_DECL=1 \ -DHAVE_STRLCPY=1 -DHAVE_FLOCK_DECL=1 -DHAVE_REVOKE_DECL=1 \
-DHAVE_SYS_ERRLIST_DECL=0 -DHAVE_SYS_SIGLIST_DECL=1 \ -DHAVE_SYS_ERRLIST_DECL=0 -DHAVE_SYS_SIGLIST_DECL=1 \
-DHAVE_PERSISTENT_HISTORY=0 -DMKSH_BUILD_R=530 -DHAVE_PERSISTENT_HISTORY=0 -DMKSH_BUILD_R=541
include $(BUILD_EXECUTABLE) include $(BUILD_EXECUTABLE)

View file

@ -1,40 +0,0 @@
# Makefile fragment for building mksh R51 2015/07/10
PROG= mksh
MAN= mksh.1
SRCS= lalloc.c eval.c exec.c expr.c funcs.c histrap.c jobs.c lex.c main.c misc.c shf.c syn.c tree.c var.c edit.c
SRCS_FP= ../src/lalloc.c ../src/eval.c ../src/exec.c ../src/expr.c ../src/funcs.c ../src/histrap.c ../src/jobs.c ../src/lex.c ../src/main.c ../src/misc.c ../src/shf.c ../src/syn.c ../src/tree.c ../src/var.c ../src/edit.c
OBJS_BP= lalloc.o eval.o exec.o expr.o funcs.o histrap.o jobs.o lex.o main.o misc.o shf.o syn.o tree.o var.o edit.o
INDSRCS= emacsfn.h rlimits.opt sh.h sh_flags.opt var_spec.h
NONSRCS_INST= dot.mkshrc $(MAN)
NONSRCS_NOINST= Build.sh Makefile Rebuild.sh check.pl check.t test.sh
CC= /huge-ssd/aosp-arm64/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin/*-gcc
CFLAGS= -fno-exceptions -Wno-multichar -fpic -fPIE -ffunction-sections -fdata-sections -funwind-tables -fstack-protector -Wa,--noexecstack -Werror=format-security -fno-short-enums -Wno-unused-but-set-variable -fno-builtin-sin -fno-strict-volatile-bitfields -Wno-psabi -fmessage-length=0 -W -Wall -Wno-unused -Winit-self -Wpointer-arith -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -g -Wstrict-aliasing=2 -fgcse-after-reload -frerun-cse-after-loop -frename-registers -Os -fomit-frame-pointer -fno-strict-aliasing -Wno-deprecated-declarations -fno-asynchronous-unwind-tables -fstack-protector-strong -fwrapv
CPPFLAGS= -I. -I'../src' -isystem /huge-ssd/aosp-arm64/bionic/libc/arch-arm64/include -isystem /huge-ssd/aosp-arm64/bionic/libc/include -isystem /huge-ssd/aosp-arm64/bionic/libc/kernel/uapi -isystem /huge-ssd/aosp-arm64/bionic/libc/kernel/uapi/asm-arm64 -isystem /huge-ssd/aosp-arm64/bionic/libm/include -isystem /huge-ssd/aosp-arm64/bionic/libm/include/arm64 -D_FORTIFY_SOURCE=2 -include /huge-ssd/aosp-arm64/build/core/combo/include/arch/linux-arm64/AndroidConfig.h -I/huge-ssd/aosp-arm64/build/core/combo/include/arch/linux-arm64/ -DANDROID -DNDEBUG -UDEBUG -DDEBUG_LEAKS -DMKSH_ASSUME_UTF8 -DMKSH_CONSERVATIVE_FDS -DMKSH_DONT_EMIT_IDSTRING -DMKSH_NOPWNAM -DMKSH_BUILDSH -D_GNU_SOURCE -DSETUID_CAN_FAIL_WITH_EAGAIN -DHAVE_ATTRIBUTE_BOUNDED=0 -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=1 -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=0 -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_ISSETUGID=0 -DHAVE_KILLPG=1 -DHAVE_MEMMOVE=1 -DHAVE_MKNOD=0 -DHAVE_MMAP=1 -DHAVE_NICE=1 -DHAVE_REVOKE=0 -DHAVE_SETLOCALE_CTYPE=0 -DHAVE_LANGINFO_CODESET=0 -DHAVE_SELECT=1 -DHAVE_SETRESUGID=1 -DHAVE_SETGROUPS=1 -DHAVE_STRERROR=1 -DHAVE_STRSIGNAL=0 -DHAVE_STRLCPY=1 -DHAVE_FLOCK_DECL=1 -DHAVE_REVOKE_DECL=1 -DHAVE_SYS_ERRLIST_DECL=0 -DHAVE_SYS_SIGLIST_DECL=1 -DHAVE_PERSISTENT_HISTORY=0 -DMKSH_BUILD_R=511
LDFLAGS= -nostdlib -Bdynamic -fPIE -pie -Wl,-dynamic-linker,/system/bin/linker -Wl,--gc-sections -Wl,-z,nocopyreloc -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--warn-shared-textrel -Wl,--fatal-warnings -Wl,--no-undefined /huge-ssd/aosp-arm64/out/target/product/flounder/obj/lib/crtbegin_dynamic.o
LIBS= -L/huge-ssd/aosp-arm64/out/target/product/flounder/obj/lib -Wl,-rpath-link=/huge-ssd/aosp-arm64/out/target/product/flounder/obj/lib -Wl,--no-whole-archive /huge-ssd/aosp-arm64/out/target/product/flounder/obj/STATIC_LIBRARIES/libcompiler_rt-extras_intermediates/libcompiler_rt-extras.a -lc /huge-ssd/aosp-arm64/out/target/product/flounder/obj/lib/crtend_android.o
.depend $(OBJS_BP): rlimits.gen sh_flags.gen
rlimits.gen: ../src/Build.sh ../src/rlimits.opt
srcfile=../src/rlimits.opt; BUILDSH_RUN_GENOPT=1; . ../src/Build.sh
sh_flags.gen: ../src/Build.sh ../src/sh_flags.opt
srcfile=../src/sh_flags.opt; BUILDSH_RUN_GENOPT=1; . ../src/Build.sh
# not BSD make only:
#VPATH= ../src
#all: $(PROG)
#$(PROG): $(OBJS_BP)
# $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJS_BP) $(LIBS)
#$(OBJS_BP): $(SRCS_FP) $(NONSRCS)
#.c.o:
# $(CC) $(CFLAGS) $(CPPFLAGS) -c $<
# for all make variants:
#REGRESS_FLAGS= -f
#regress:
# ./test.sh $(REGRESS_FLAGS)
check_categories= shell:legacy-no int:32 android convfds no-histfile
# for BSD make only:
#.PATH: ../src
#.include <bsd.prog.mk>

55
src/Build.sh Normal file → Executable file
View file

@ -1,5 +1,5 @@
#!/bin/sh #!/bin/sh
srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.702 2016/08/10 18:20:16 tg Exp $' srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.707 2016/11/11 23:31:29 tg Exp $'
#- #-
# Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
# 2011, 2012, 2013, 2014, 2015, 2016 # 2011, 2012, 2013, 2014, 2015, 2016
@ -120,7 +120,7 @@ do_genopt() {
state=3 state=3
;; ;;
1:@@) 1:@@)
# begin of data block # start of data block
o_gen=$o_gen$nl"#endif" o_gen=$o_gen$nl"#endif"
o_gen=$o_gen$nl"#ifndef F0" o_gen=$o_gen$nl"#ifndef F0"
o_gen=$o_gen$nl"#define F0 FN" o_gen=$o_gen$nl"#define F0 FN"
@ -133,7 +133,7 @@ do_genopt() {
o_hdr=$o_hdr$nl$line o_hdr=$o_hdr$nl$line
;; ;;
0:@*|1:@*) 0:@*|1:@*)
# begin of a definition block # start of a definition block
sym=`echo "$line" | sed 's/^@//'` sym=`echo "$line" | sed 's/^@//'`
if test $state = 0; then if test $state = 0; then
o_gen=$o_gen$nl"#if defined($sym)" o_gen=$o_gen$nl"#if defined($sym)"
@ -584,7 +584,7 @@ if test -d $tfn || test -d $tfn.exe; then
exit 1 exit 1
fi fi
rmf a.exe* a.out* conftest.c conftest.exe* *core core.* ${tfn}* *.bc *.dbg \ rmf a.exe* a.out* conftest.c conftest.exe* *core core.* ${tfn}* *.bc *.dbg \
*.ll *.o *.gen Rebuild.sh lft no signames.inc test.sh x vv.out *.ll *.o *.gen *.cat1 Rebuild.sh lft no signames.inc test.sh x vv.out
SRCS="lalloc.c eval.c exec.c expr.c funcs.c histrap.c jobs.c" SRCS="lalloc.c eval.c exec.c expr.c funcs.c histrap.c jobs.c"
SRCS="$SRCS lex.c main.c misc.c shf.c syn.c tree.c var.c" SRCS="$SRCS lex.c main.c misc.c shf.c syn.c tree.c var.c"
@ -755,6 +755,24 @@ GNU/kFreeBSD)
Haiku) Haiku)
add_cppflags -DMKSH_ASSUME_UTF8; HAVE_ISSET_MKSH_ASSUME_UTF8=1 add_cppflags -DMKSH_ASSUME_UTF8; HAVE_ISSET_MKSH_ASSUME_UTF8=1
;; ;;
Harvey)
add_cppflags -D_POSIX_SOURCE
add_cppflags -D_LIMITS_EXTENSION
add_cppflags -D_BSD_EXTENSION
add_cppflags -D_SUSV2_SOURCE
add_cppflags -D_GNU_SOURCE
add_cppflags -DMKSH_ASSUME_UTF8; HAVE_ISSET_MKSH_ASSUME_UTF8=1
add_cppflags -DMKSH_NO_CMDLINE_EDITING
add_cppflags -DMKSH__NO_SETEUGID
oswarn=' and will currently not work'
add_cppflags -DMKSH_UNEMPLOYED
add_cppflags -DMKSH_NOPROSPECTOFWORK
# these taken from Harvey-OS github and need re-checking
add_cppflags -D_setjmp=setjmp -D_longjmp=longjmp
: "${HAVE_CAN_NO_EH_FRAME=0}"
: "${HAVE_CAN_FNOSTRICTALIASING=0}"
: "${HAVE_CAN_FSTACKPROTECTORSTRONG=0}"
;;
HP-UX) HP-UX)
;; ;;
Interix) Interix)
@ -833,12 +851,14 @@ OpenBSD)
OS/2) OS/2)
HAVE_TERMIOS_H=0 HAVE_TERMIOS_H=0
HAVE_MKNOD=0 # setmode() incompatible HAVE_MKNOD=0 # setmode() incompatible
oswarn="; it is currently being ported" oswarn="; it is currently being ported, get it from"
oswarn="$oswarn${nl}https://github.com/komh/mksh-os2 in the meanwhile"
check_categories="$check_categories nosymlink" check_categories="$check_categories nosymlink"
: "${CC=gcc}" : "${CC=gcc}"
: "${SIZE=: size}" : "${SIZE=: size}"
add_cppflags -DMKSH_UNEMPLOYED add_cppflags -DMKSH_UNEMPLOYED
add_cppflags -DMKSH_NOPROSPECTOFWORK add_cppflags -DMKSH_NOPROSPECTOFWORK
add_cppflags -DMKSH_NO_LIMITS
;; ;;
OSF1) OSF1)
HAVE_SIG_T=0 # incompatible HAVE_SIG_T=0 # incompatible
@ -980,7 +1000,7 @@ drop us a success or failure notice or even send in diffs.
$e "$bi$me: Building the MirBSD Korn Shell$ao $ui$dstversion$ao on $TARGET_OS ${TARGET_OSREV}..." $e "$bi$me: Building the MirBSD Korn Shell$ao $ui$dstversion$ao on $TARGET_OS ${TARGET_OSREV}..."
# #
# Begin of mirtoconf checks # Start of mirtoconf checks
# #
$e $bi$me: Scanning for functions... please ignore any errors.$ao $e $bi$me: Scanning for functions... please ignore any errors.$ao
@ -1458,6 +1478,7 @@ gcc)
ac_flags $t_use $t_name "$t_cflags" \ ac_flags $t_use $t_name "$t_cflags" \
"if gcc supports $t_cflags $t_ldflags" "$t_ldflags" "if gcc supports $t_cflags $t_ldflags" "$t_ldflags"
done done
ac_flags 1 data_abi_align -malign-data=abi
i=1 i=1
;; ;;
hpcc) hpcc)
@ -1486,8 +1507,12 @@ msc)
ac_flags 1 wp64 "${ccpc}/Wp64" 'to enable 64-bit warnings' ac_flags 1 wp64 "${ccpc}/Wp64" 'to enable 64-bit warnings'
;; ;;
nwcc) nwcc)
i=1
#broken# ac_flags 1 ssp -stackprotect #broken# ac_flags 1 ssp -stackprotect
i=1
;;
pcc)
ac_flags 1 fstackprotectorall -fstack-protector-all
i=1
;; ;;
sunpro) sunpro)
phase=u phase=u
@ -2342,7 +2367,7 @@ addsrcs '!' HAVE_STRLCPY strlcpy.c
addsrcs USE_PRINTF_BUILTIN printf.c addsrcs USE_PRINTF_BUILTIN printf.c
test 1 = "$USE_PRINTF_BUILTIN" && add_cppflags -DMKSH_PRINTF_BUILTIN test 1 = "$USE_PRINTF_BUILTIN" && add_cppflags -DMKSH_PRINTF_BUILTIN
test 1 = "$HAVE_CAN_VERB" && CFLAGS="$CFLAGS -verbose" test 1 = "$HAVE_CAN_VERB" && CFLAGS="$CFLAGS -verbose"
add_cppflags -DMKSH_BUILD_R=530 add_cppflags -DMKSH_BUILD_R=541
$e $bi$me: Finished configuration testing, now producing output.$ao $e $bi$me: Finished configuration testing, now producing output.$ao
@ -2588,8 +2613,8 @@ esac
tcfn=$mkshexe tcfn=$mkshexe
test $cm = combine || v "$CC $CFLAGS $LDFLAGS -o $tcfn $lobjs $LIBS $ccpr" test $cm = combine || v "$CC $CFLAGS $LDFLAGS -o $tcfn $lobjs $LIBS $ccpr"
test -f $tcfn || exit 1 test -f $tcfn || exit 1
test 1 = $r || v "$NROFF -mdoc <'$srcdir/mksh.1' >$tfn.cat1" || \ test 1 = $r || v "$NROFF -mdoc <'$srcdir/lksh.1' >lksh.cat1" || rmf lksh.cat1
rmf $tfn.cat1 test 1 = $r || v "$NROFF -mdoc <'$srcdir/mksh.1' >mksh.cat1" || rmf mksh.cat1
test 0 = $eq && v $SIZE $tcfn test 0 = $eq && v $SIZE $tcfn
i=install i=install
test -f /usr/ucb/$i && i=/usr/ucb/$i test -f /usr/ucb/$i && i=/usr/ucb/$i
@ -2603,12 +2628,14 @@ if test $legacy = 0; then
fi fi
$e $e
$e Installing the manual: $e Installing the manual:
if test -f $tfn.cat1; then if test -f mksh.cat1; then
$e "# $i -c -o root -g bin -m 444 $tfn.cat1" \ $e "# $i -c -o root -g bin -m 444 lksh.cat1" \
"/usr/share/man/cat1/$tfn.0" "/usr/share/man/cat1/lksh.0"
$e "# $i -c -o root -g bin -m 444 mksh.cat1" \
"/usr/share/man/cat1/mksh.0"
$e or $e or
fi fi
$e "# $i -c -o root -g bin -m 444 $tfn.1 /usr/share/man/man1/$tfn.1" $e "# $i -c -o root -g bin -m 444 lksh.1 mksh.1 /usr/share/man/man1/"
$e $e
$e Run the regression test suite: ./test.sh $e Run the regression test suite: ./test.sh
$e Please also read the sample file dot.mkshrc and the fine manual. $e Please also read the sample file dot.mkshrc and the fine manual.

View file

@ -1,4 +1,4 @@
# $MirOS: src/bin/mksh/check.t,v 1.751 2016/08/12 16:48:02 tg Exp $ # $MirOS: src/bin/mksh/check.t,v 1.756 2016/11/11 23:31:31 tg Exp $
# -*- mode: sh -*- # -*- mode: sh -*-
#- #-
# Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
@ -30,7 +30,7 @@
# (2013/12/02 20:39:44) http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/regress/bin/ksh/?sortby=date # (2013/12/02 20:39:44) http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/regress/bin/ksh/?sortby=date
expected-stdout: expected-stdout:
@(#)MIRBSD KSH R53 2016/08/12 @(#)MIRBSD KSH R54 2016/11/11
description: description:
Check version of shell. Check version of shell.
stdin: stdin:
@ -39,7 +39,7 @@ name: KSH_VERSION
category: shell:legacy-no category: shell:legacy-no
--- ---
expected-stdout: expected-stdout:
@(#)LEGACY KSH R53 2016/08/12 @(#)LEGACY KSH R54 2016/11/11
description: description:
Check version of legacy shell. Check version of legacy shell.
stdin: stdin:
@ -340,6 +340,62 @@ expected-stdout:
2 2
0 0
--- ---
name: arith-lazy-5-arr-n
description: Check lazy evaluation with side effects
stdin:
a=0; echo "$((0&&b[a++],a))"
expected-stdout:
0
---
name: arith-lazy-5-arr-p
description: Check lazy evaluation with side effects
stdin:
a=0; echo "$((0&&(b[a++]),a))"
expected-stdout:
0
---
name: arith-lazy-5-str-n
description: Check lazy evaluation with side effects
stdin:
a=0 b=a++; ((0&&b)); echo $a
expected-stdout:
0
---
name: arith-lazy-5-str-p
description: Check lazy evaluation with side effects
stdin:
a=0 b=a++; ((0&&(b))); echo $a
expected-stdout:
0
---
name: arith-lazy-5-tern-l-n
description: Check lazy evaluation with side effects
stdin:
a=0; echo "$((0?b[a++]:999,a))"
expected-stdout:
0
---
name: arith-lazy-5-tern-l-p
description: Check lazy evaluation with side effects
stdin:
a=0; echo "$((0?(b[a++]):999,a))"
expected-stdout:
0
---
name: arith-lazy-5-tern-r-n
description: Check lazy evaluation with side effects
stdin:
a=0; echo "$((1?999:b[a++],a))"
expected-stdout:
0
---
name: arith-lazy-5-tern-r-p
description: Check lazy evaluation with side effects
stdin:
a=0; echo "$((1?999:(b[a++]),a))"
expected-stdout:
0
---
name: arith-ternary-prec-1 name: arith-ternary-prec-1
description: description:
Check precedence of ternary operator vs assignment Check precedence of ternary operator vs assignment
@ -4892,7 +4948,7 @@ name: integer-base-check-flat
description: description:
Check behaviour does not match POSuX (except if set -o posix), Check behaviour does not match POSuX (except if set -o posix),
because a not type-safe scripting language has *no* business because a not type-safe scripting language has *no* business
interpreting the string "010" as octal numer eight (dangerous). interpreting the string "010" as octal number eight (dangerous).
stdin: stdin:
echo 1 "$("$__progname" -c 'echo :$((10))/$((010)),$((0x10)):')" . echo 1 "$("$__progname" -c 'echo :$((10))/$((010)),$((0x10)):')" .
echo 2 "$("$__progname" -o posix -c 'echo :$((10))/$((010)),$((0x10)):')" . echo 2 "$("$__progname" -o posix -c 'echo :$((10))/$((010)),$((0x10)):')" .
@ -7152,6 +7208,19 @@ stdin:
db_go db_go
exit 0 exit 0
--- ---
name: exit-err-9
description:
"set -e" versus bang pipelines
stdin:
set -e
! false | false
echo 1 ok
! false && false
echo 2 wrong
expected-stdout:
1 ok
expected-exit: 1
---
name: exit-enoent-1 name: exit-enoent-1
description: description:
SUSv4 says that the shell should exit with 126/127 in some situations SUSv4 says that the shell should exit with 126/127 in some situations
@ -11754,7 +11823,7 @@ stdin:
echo "before: x<$x> y<$y> z<$z> R<$REPLY>" echo "before: x<$x> y<$y> z<$z> R<$REPLY>"
x=${| x=${|
local y local y
echo "begin: x<$x> y<$y> z<$z> R<$REPLY>" echo "start: x<$x> y<$y> z<$z> R<$REPLY>"
x=5 x=5
y=6 y=6
z=7 z=7
@ -11769,7 +11838,7 @@ stdin:
echo ${|true;}$(true). echo ${|true;}$(true).
expected-stdout: expected-stdout:
before: x<1> y<2> z<3> R<4> before: x<1> y<2> z<3> R<4>
begin: x<1> y<> z<3> R<> start: x<1> y<> z<3> R<>
end: x<5> y<6> z<7> R<8> end: x<5> y<6> z<7> R<8>
after: x<8> y<2> z<7> R<4> after: x<8> y<2> z<7> R<4>
typeset t=$'foo\n\n' typeset t=$'foo\n\n'

View file

@ -28,7 +28,7 @@
#ifndef MKSH_NO_CMDLINE_EDITING #ifndef MKSH_NO_CMDLINE_EDITING
__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.306 2016/08/01 18:42:40 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/edit.c,v 1.312 2016/11/11 23:48:28 tg Exp $");
/* /*
* in later versions we might use libtermcap for this, but since external * in later versions we might use libtermcap for this, but since external
@ -238,6 +238,7 @@ x_print_expansions(int nwords, char * const *words, bool is_command)
bool use_copy = false; bool use_copy = false;
size_t prefix_len; size_t prefix_len;
XPtrV l = { NULL, 0, 0 }; XPtrV l = { NULL, 0, 0 };
struct columnise_opts co;
/* /*
* Check if all matches are in the same directory (in this * Check if all matches are in the same directory (in this
@ -257,7 +258,8 @@ x_print_expansions(int nwords, char * const *words, bool is_command)
break; break;
/* All in same directory? */ /* All in same directory? */
if (i == nwords) { if (i == nwords) {
while (prefix_len > 0 && words[0][prefix_len - 1] != '/') while (prefix_len > 0 &&
!mksh_cdirsep(words[0][prefix_len - 1]))
prefix_len--; prefix_len--;
use_copy = true; use_copy = true;
XPinit(l, nwords + 1); XPinit(l, nwords + 1);
@ -271,7 +273,11 @@ x_print_expansions(int nwords, char * const *words, bool is_command)
*/ */
x_putc('\r'); x_putc('\r');
x_putc('\n'); x_putc('\n');
pr_list(use_copy ? (char **)XPptrv(l) : words); co.shf = shl_out;
co.linesep = '\n';
co.do_last = true;
co.prefcol = false;
pr_list(&co, use_copy ? (char **)XPptrv(l) : words);
if (use_copy) if (use_copy)
/* not x_free_words() */ /* not x_free_words() */
@ -333,7 +339,7 @@ x_glob_hlp_tilde_and_rem_qchar(char *s, bool magic_flag)
* and if so, discern "~foo/bar" and "~/baz" from "~blah"; * and if so, discern "~foo/bar" and "~/baz" from "~blah";
* if we have a directory part (the former), try to expand * if we have a directory part (the former), try to expand
*/ */
if (*s == '~' && (cp = strchr(s, '/')) != NULL) { if (*s == '~' && (cp = mksh_sdirsep(s)) != NULL) {
/* ok, so split into "~foo"/"bar" or "~"/"baz" */ /* ok, so split into "~foo"/"bar" or "~"/"baz" */
*cp++ = 0; *cp++ = 0;
/* try to expand the tilde */ /* try to expand the tilde */
@ -588,7 +594,7 @@ x_locate_word(const char *buf, int buflen, int pos, int *startp,
* like file globbing. * like file globbing.
*/ */
for (p = start; p < end; p++) for (p = start; p < end; p++)
if (buf[p] == '/') if (mksh_cdirsep(buf[p]))
break; break;
iscmd = p == end; iscmd = p == end;
} }
@ -652,7 +658,7 @@ x_cf_glob(int *flagsp, const char *buf, int buflen, int pos, int *startp,
} }
} }
if (*toglob == '~' && !vstrchr(toglob, '/')) { if (*toglob == '~' && !mksh_vdirsep(toglob)) {
/* neither for '~foo' (but '~foo/bar') */ /* neither for '~foo' (but '~foo/bar') */
*flagsp |= XCF_IS_NOSPACE; *flagsp |= XCF_IS_NOSPACE;
goto dont_add_glob; goto dont_add_glob;
@ -741,13 +747,15 @@ x_basename(const char *s, const char *se)
if (s == se) if (s == se)
return (0); return (0);
/* Skip trailing slashes */ /* skip trailing directory separators */
for (p = se - 1; p > s && *p == '/'; p--) p = se - 1;
; while (p > s && mksh_cdirsep(*p))
for (; p > s && *p != '/'; p--) --p;
; /* drop last component */
if (*p == '/' && p + 1 < se) while (p > s && !mksh_cdirsep(*p))
p++; --p;
if (mksh_cdirsep(*p) && p + 1 < se)
++p;
return (p - s); return (p - s);
} }
@ -1048,7 +1056,7 @@ static struct x_defbindings const x_defbindings[] = {
{ XFUNC_end_hist, 1, '>' }, { XFUNC_end_hist, 1, '>' },
{ XFUNC_goto_hist, 1, 'g' }, { XFUNC_goto_hist, 1, 'g' },
{ XFUNC_mv_end, 0, CTRL('E') }, { XFUNC_mv_end, 0, CTRL('E') },
{ XFUNC_mv_begin, 0, CTRL('A') }, { XFUNC_mv_beg, 0, CTRL('A') },
{ XFUNC_draw_line, 0, CTRL('L') }, { XFUNC_draw_line, 0, CTRL('L') },
{ XFUNC_cls, 1, CTRL('L') }, { XFUNC_cls, 1, CTRL('L') },
{ XFUNC_meta1, 0, CTRL('[') }, { XFUNC_meta1, 0, CTRL('[') },
@ -1106,8 +1114,8 @@ static struct x_defbindings const x_defbindings[] = {
{ XFUNC_mv_back, 2, 'D' }, { XFUNC_mv_back, 2, 'D' },
#ifndef MKSH_SMALL #ifndef MKSH_SMALL
{ XFUNC_vt_hack, 2, '1' }, { XFUNC_vt_hack, 2, '1' },
{ XFUNC_mv_begin | 0x80, 2, '7' }, { XFUNC_mv_beg | 0x80, 2, '7' },
{ XFUNC_mv_begin, 2, 'H' }, { XFUNC_mv_beg, 2, 'H' },
{ XFUNC_mv_end | 0x80, 2, '4' }, { XFUNC_mv_end | 0x80, 2, '4' },
{ XFUNC_mv_end | 0x80, 2, '8' }, { XFUNC_mv_end | 0x80, 2, '8' },
{ XFUNC_mv_end, 2, 'F' }, { XFUNC_mv_end, 2, 'F' },
@ -1119,7 +1127,7 @@ static struct x_defbindings const x_defbindings[] = {
/* PC scancodes */ /* PC scancodes */
#if !defined(MKSH_SMALL) || defined(__OS2__) #if !defined(MKSH_SMALL) || defined(__OS2__)
{ XFUNC_meta3, 0, 0 }, { XFUNC_meta3, 0, 0 },
{ XFUNC_mv_begin, 3, 71 }, { XFUNC_mv_beg, 3, 71 },
{ XFUNC_prev_com, 3, 72 }, { XFUNC_prev_com, 3, 72 },
#ifndef MKSH_SMALL #ifndef MKSH_SMALL
{ XFUNC_search_hist_up, 3, 73 }, { XFUNC_search_hist_up, 3, 73 },
@ -2044,7 +2052,7 @@ x_mv_end(int c MKSH_A_UNUSED)
} }
static int static int
x_mv_begin(int c MKSH_A_UNUSED) x_mv_beg(int c MKSH_A_UNUSED)
{ {
x_goto(xbuf); x_goto(xbuf);
return (KSTD); return (KSTD);
@ -2328,7 +2336,7 @@ x_vt_hack(int c)
case '~': case '~':
x_arg = 1; x_arg = 1;
x_arg_defaulted = true; x_arg_defaulted = true;
return (x_mv_begin(0)); return (x_mv_beg(0));
case ';': case ';':
/* "interesting" sequence detected */ /* "interesting" sequence detected */
break; break;
@ -2778,7 +2786,7 @@ do_complete(
* append a space if this is a single non-directory match * append a space if this is a single non-directory match
* and not a parameter or homedir substitution * and not a parameter or homedir substitution
*/ */
if (nwords == 1 && words[0][nlen - 1] != '/' && if (nwords == 1 && !mksh_cdirsep(words[0][nlen - 1]) &&
!(flags & XCF_IS_NOSPACE)) { !(flags & XCF_IS_NOSPACE)) {
x_ins(T1space); x_ins(T1space);
} }
@ -4016,7 +4024,7 @@ vi_insert(int ch)
else else
return (redo_insert(lastac - 1)); return (redo_insert(lastac - 1));
/* { Begin nonstandard vi commands */ /* { start nonstandard vi commands */
case CTRL('x'): case CTRL('x'):
expand_word(0); expand_word(0);
break; break;
@ -4035,7 +4043,7 @@ vi_insert(int ch)
break; break;
} }
/* FALLTHROUGH */ /* FALLTHROUGH */
/* End nonstandard vi commands } */ /* end nonstandard vi commands } */
default: default:
if (es->linelen >= es->cbufsize - 1) if (es->linelen >= es->cbufsize - 1)
@ -4157,6 +4165,8 @@ vi_cmd(int argcnt, const char *cmd)
case 'Y': case 'Y':
cmd = "y$"; cmd = "y$";
/* ahhhhhh... */ /* ahhhhhh... */
/* FALLTHROUGH */
case 'c': case 'c':
case 'd': case 'd':
case 'y': case 'y':
@ -4393,6 +4403,8 @@ vi_cmd(int argcnt, const char *cmd)
if (hnum == hlast) if (hnum == hlast)
hnum = -1; hnum = -1;
/* ahhh */ /* ahhh */
/* FALLTHROUGH */
case '/': case '/':
c3 = 1; c3 = 1;
srchlen = 0; srchlen = 0;
@ -4531,6 +4543,7 @@ vi_cmd(int argcnt, const char *cmd)
case CTRL('['): case CTRL('['):
if (!Flag(FVIESCCOMPLETE)) if (!Flag(FVIESCCOMPLETE))
return (-1); return (-1);
/* FALLTHROUGH */
/* AT&T ksh */ /* AT&T ksh */
case '\\': case '\\':
/* Nonstandard vi/ksh */ /* Nonstandard vi/ksh */
@ -4603,8 +4616,7 @@ domove(int argcnt, const char *cmd, int sub)
case 'T': case 'T':
fsavecmd = *cmd; fsavecmd = *cmd;
fsavech = cmd[1]; fsavech = cmd[1];
/* drop through */ /* FALLTHROUGH */
case ',': case ',':
case ';': case ';':
if (fsavecmd == ' ') if (fsavecmd == ' ')
@ -5399,7 +5411,7 @@ complete_word(int cmd, int count)
* append a space if this is a non-directory match * append a space if this is a non-directory match
* and not a parameter or homedir substitution * and not a parameter or homedir substitution
*/ */
if (match_len > 0 && match[match_len - 1] != '/' && if (match_len > 0 && !mksh_cdirsep(match[match_len - 1]) &&
!(flags & XCF_IS_NOSPACE)) !(flags & XCF_IS_NOSPACE))
rval = putbuf(T1space, 1, false); rval = putbuf(T1space, 1, false);
} }

View file

@ -19,7 +19,7 @@
*/ */
#if defined(EMACSFN_DEFNS) #if defined(EMACSFN_DEFNS)
__RCSID("$MirOS: src/bin/mksh/emacsfn.h,v 1.9 2016/07/26 21:50:30 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/emacsfn.h,v 1.10 2016/09/01 12:59:09 tg Exp $");
#define FN(cname,sname,flags) static int x_##cname(int); #define FN(cname,sname,flags) static int x_##cname(int);
#elif defined(EMACSFN_ENUMS) #elif defined(EMACSFN_ENUMS)
#define FN(cname,sname,flags) XFUNC_##cname, #define FN(cname,sname,flags) XFUNC_##cname,
@ -78,7 +78,7 @@ FN(meta2, "prefix-2", XF_PREFIX)
FN(meta3, "prefix-3", XF_PREFIX) FN(meta3, "prefix-3", XF_PREFIX)
FN(meta_yank, "yank-pop", 0) FN(meta_yank, "yank-pop", 0)
FN(mv_back, "backward-char", XF_ARG) FN(mv_back, "backward-char", XF_ARG)
FN(mv_begin, "beginning-of-line", 0) FN(mv_beg, "beginning-of-line", 0)
FN(mv_bword, "backward-word", XF_ARG) FN(mv_bword, "backward-word", XF_ARG)
FN(mv_end, "end-of-line", 0) FN(mv_end, "end-of-line", 0)
FN(mv_forw, "forward-char", XF_ARG) FN(mv_forw, "forward-char", XF_ARG)

View file

@ -23,7 +23,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.192 2016/08/01 21:38:01 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/eval.c,v 1.194 2016/11/11 23:31:34 tg Exp $");
/* /*
* string expansion * string expansion
@ -62,7 +62,7 @@ typedef struct {
#define IFS_WORD 0 /* word has chars (or quotes except "$@") */ #define IFS_WORD 0 /* word has chars (or quotes except "$@") */
#define IFS_WS 1 /* have seen IFS white-space */ #define IFS_WS 1 /* have seen IFS white-space */
#define IFS_NWS 2 /* have seen IFS non-white-space */ #define IFS_NWS 2 /* have seen IFS non-white-space */
#define IFS_IWS 3 /* begin of word, ignore IFS WS */ #define IFS_IWS 3 /* beginning of word, ignore IFS WS */
#define IFS_QUOTE 4 /* beg.w/quote, become IFS_WORD unless "$@" */ #define IFS_QUOTE 4 /* beg.w/quote, become IFS_WORD unless "$@" */
static int varsub(Expand *, const char *, const char *, int *, int *); static int varsub(Expand *, const char *, const char *, int *, int *);
@ -198,7 +198,7 @@ typedef struct SubType {
struct tbl *var; /* variable for ${var..} */ struct tbl *var; /* variable for ${var..} */
struct SubType *prev; /* old type */ struct SubType *prev; /* old type */
struct SubType *next; /* poped type (to avoid re-allocating) */ struct SubType *next; /* poped type (to avoid re-allocating) */
size_t base; /* begin position of expanded word */ size_t base; /* start position of expanded word */
short stype; /* [=+-?%#] action after expanded word */ short stype; /* [=+-?%#] action after expanded word */
short f; /* saved value of f (DOPAT, etc) */ short f; /* saved value of f (DOPAT, etc) */
uint8_t quotep; /* saved value of quote (for ${..[%#]..}) */ uint8_t quotep; /* saved value of quote (for ${..[%#]..}) */
@ -1576,7 +1576,7 @@ globit(XString *xs, /* dest string */
* SunOS 4.1.3 does this... * SunOS 4.1.3 does this...
*/ */
if ((check & GF_EXCHECK) && xp > Xstring(*xs, xp) && if ((check & GF_EXCHECK) && xp > Xstring(*xs, xp) &&
xp[-1] == '/' && !S_ISDIR(lstatb.st_mode) && mksh_cdirsep(xp[-1]) && !S_ISDIR(lstatb.st_mode) &&
(!S_ISLNK(lstatb.st_mode) || (!S_ISLNK(lstatb.st_mode) ||
stat_check() < 0 || !S_ISDIR(statb.st_mode))) stat_check() < 0 || !S_ISDIR(statb.st_mode)))
return; return;
@ -1586,7 +1586,7 @@ globit(XString *xs, /* dest string */
* directory * directory
*/ */
if (((check & GF_MARKDIR) && (check & GF_GLOBBED)) && if (((check & GF_MARKDIR) && (check & GF_GLOBBED)) &&
xp > Xstring(*xs, xp) && xp[-1] != '/' && xp > Xstring(*xs, xp) && !mksh_cdirsep(xp[-1]) &&
(S_ISDIR(lstatb.st_mode) || (S_ISDIR(lstatb.st_mode) ||
(S_ISLNK(lstatb.st_mode) && stat_check() > 0 && (S_ISLNK(lstatb.st_mode) && stat_check() > 0 &&
S_ISDIR(statb.st_mode)))) { S_ISDIR(statb.st_mode)))) {
@ -1601,11 +1601,11 @@ globit(XString *xs, /* dest string */
if (xp > Xstring(*xs, xp)) if (xp > Xstring(*xs, xp))
*xp++ = '/'; *xp++ = '/';
while (*sp == '/') { while (mksh_cdirsep(*sp)) {
Xcheck(*xs, xp); Xcheck(*xs, xp);
*xp++ = *sp++; *xp++ = *sp++;
} }
np = strchr(sp, '/'); np = mksh_sdirsep(sp);
if (np != NULL) { if (np != NULL) {
se = np; se = np;
/* don't assume '/', can be multiple kinds */ /* don't assume '/', can be multiple kinds */
@ -1713,8 +1713,8 @@ maybe_expand_tilde(const char *p, XString *dsp, char **dpp, bool isassign)
Xinit(ts, tp, 16, ATEMP); Xinit(ts, tp, 16, ATEMP);
/* : only for DOASNTILDE form */ /* : only for DOASNTILDE form */
while (p[0] == CHAR && p[1] != '/' && (!isassign || p[1] != ':')) while (p[0] == CHAR && !mksh_cdirsep(p[1]) &&
{ (!isassign || p[1] != ':')) {
Xcheck(ts, tp); Xcheck(ts, tp);
*tp++ = p[1]; *tp++ = p[1];
p += 2; p += 2;

View file

@ -23,7 +23,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.179 2016/08/01 21:38:02 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/exec.c,v 1.186 2016/11/11 23:31:34 tg Exp $");
#ifndef MKSH_DEFAULT_EXECSHELL #ifndef MKSH_DEFAULT_EXECSHELL
#define MKSH_DEFAULT_EXECSHELL MKSH_UNIXROOT "/bin/sh" #define MKSH_DEFAULT_EXECSHELL MKSH_UNIXROOT "/bin/sh"
@ -282,7 +282,7 @@ execute(struct op * volatile t,
case TOR: case TOR:
case TAND: case TAND:
rv = execute(t->left, XERROK, xerrok); rv = execute(t->left, XERROK, NULL);
if ((rv == 0) == (t->type == TAND)) if ((rv == 0) == (t->type == TAND))
rv = execute(t->right, flags & XERROK, xerrok); rv = execute(t->right, flags & XERROK, xerrok);
else { else {
@ -339,16 +339,14 @@ execute(struct op * volatile t,
rv = execute(t->left, flags & XERROK, xerrok); rv = execute(t->left, flags & XERROK, xerrok);
} }
} else { } else {
/* TSELECT */ do_TSELECT:
for (;;) { if ((ccp = do_selectargs(ap, is_first))) {
if (!(ccp = do_selectargs(ap, is_first))) {
rv = 1;
break;
}
is_first = false; is_first = false;
setstr(global(t->str), ccp, KSH_UNWIND_ERROR); setstr(global(t->str), ccp, KSH_UNWIND_ERROR);
execute(t->left, flags & XERROK, xerrok); execute(t->left, flags & XERROK, xerrok);
goto do_TSELECT;
} }
rv = 1;
} }
break; break;
} }
@ -674,7 +672,7 @@ comexec(struct op *t, struct tbl * volatile tp, const char **ap,
rv = subst_exstat; rv = subst_exstat;
goto Leave; goto Leave;
} else if (!tp) { } else if (!tp) {
if (Flag(FRESTRICTED) && vstrchr(cp, '/')) { if (Flag(FRESTRICTED) && mksh_vdirsep(cp)) {
warningf(true, Tf_sD_s, cp, "restricted"); warningf(true, Tf_sD_s, cp, "restricted");
rv = 1; rv = 1;
goto Leave; goto Leave;
@ -913,7 +911,7 @@ scriptexec(struct op *tp, const char **ap)
/* replace newline by NUL */ /* replace newline by NUL */
*cp = '\0'; *cp = '\0';
/* restore begin of shebang position (buf+0 or buf+3) */ /* restore start of shebang position (buf+0 or buf+3) */
cp = buf + n; cp = buf + n;
/* bail out if no shebang magic found */ /* bail out if no shebang magic found */
if (cp[0] == '#' && cp[1] == '!') if (cp[0] == '#' && cp[1] == '!')
@ -1125,7 +1123,7 @@ findcom(const char *name, int flags)
char *fpath; char *fpath;
union mksh_cchack npath; union mksh_cchack npath;
if (vstrchr(name, '/')) { if (mksh_vdirsep(name)) {
insert = 0; insert = 0;
/* prevent FPATH search below */ /* prevent FPATH search below */
flags &= ~FC_FUNC; flags &= ~FC_FUNC;
@ -1242,8 +1240,12 @@ search_access(const char *fn, int mode)
eno = errno; eno = errno;
return (eno ? eno : EACCES); return (eno ? eno : EACCES);
} }
#ifdef __OS2__
/* treat all files as executable on OS/2 */
sb.st_mode &= S_IXUSR | S_IXGRP | S_IXOTH;
#endif
if (mode == X_OK && (!S_ISREG(sb.st_mode) || if (mode == X_OK && (!S_ISREG(sb.st_mode) ||
!(sb.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)))) !(sb.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))))
/* access(2) may say root can execute everything */ /* access(2) may say root can execute everything */
return (S_ISDIR(sb.st_mode) ? EISDIR : EACCES); return (S_ISDIR(sb.st_mode) ? EISDIR : EACCES);
return (0); return (0);
@ -1265,7 +1267,7 @@ search_path(const char *name, const char *lpath,
size_t namelen; size_t namelen;
int ec = 0, ev; int ec = 0, ev;
if (vstrchr(name, '/')) { if (mksh_vdirsep(name)) {
if ((ec = search_access(name, mode)) == 0) { if ((ec = search_access(name, mode)) == 0) {
search_path_ok: search_path_ok:
if (errnop) if (errnop)
@ -1658,6 +1660,7 @@ pr_menu(const char * const *ap)
const char * const *pp; const char * const *pp;
size_t acols = 0, aocts = 0, i; size_t acols = 0, aocts = 0, i;
unsigned int n; unsigned int n;
struct columnise_opts co;
/* /*
* width/column calculations were done once and saved, but this * width/column calculations were done once and saved, but this
@ -1686,9 +1689,11 @@ pr_menu(const char * const *ap)
smi.num_width++; smi.num_width++;
smi.args = ap; smi.args = ap;
print_columns(shl_out, n, select_fmt_entry, (void *)&smi, co.shf = shl_out;
smi.num_width + 2 + aocts, smi.num_width + 2 + acols, co.linesep = '\n';
true); co.prefcol = co.do_last = true;
print_columns(&co, n, select_fmt_entry, (void *)&smi,
smi.num_width + 2 + aocts, smi.num_width + 2 + acols);
} }
static void static void
@ -1698,7 +1703,7 @@ plain_fmt_entry(char *buf, size_t buflen, unsigned int i, const void *arg)
} }
void void
pr_list(char * const *ap) pr_list(struct columnise_opts *cop, char * const *ap)
{ {
size_t acols = 0, aocts = 0, i; size_t acols = 0, aocts = 0, i;
unsigned int n; unsigned int n;
@ -1713,8 +1718,8 @@ pr_list(char * const *ap)
acols = i; acols = i;
} }
print_columns(shl_out, n, plain_fmt_entry, (const void *)ap, print_columns(cop, n, plain_fmt_entry, (const void *)ap,
aocts, acols, false); aocts, acols);
} }
/* /*

View file

@ -23,7 +23,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/expr.c,v 1.88 2016/07/27 00:55:27 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/expr.c,v 1.90 2016/11/07 16:58:48 tg Exp $");
#define EXPRTOK_DEFNS #define EXPRTOK_DEFNS
#include "exprtok.h" #include "exprtok.h"
@ -326,7 +326,15 @@ evalexpr(Expr_state *es, unsigned int prec)
vl = evalexpr(es, prec - 1); vl = evalexpr(es, prec - 1);
while ((int)(op = es->tok) >= (int)O_EQ && (int)op <= (int)O_COMMA && while ((int)(op = es->tok) >= (int)O_EQ && (int)op <= (int)O_COMMA &&
opprec[(int)op] == prec) { opprec[(int)op] == prec) {
exprtoken(es); switch ((int)op) {
case O_TERN:
case O_LAND:
case O_LOR:
break;
default:
exprtoken(es);
}
vasn = vl; vasn = vl;
if (op != O_ASN) if (op != O_ASN)
/* vl may not have a value yet */ /* vl may not have a value yet */
@ -340,14 +348,15 @@ evalexpr(Expr_state *es, unsigned int prec)
if (!ev) if (!ev)
es->noassign++; es->noassign++;
exprtoken(es);
vl = evalexpr(es, MAX_PREC); vl = evalexpr(es, MAX_PREC);
if (!ev) if (!ev)
es->noassign--; es->noassign--;
if (es->tok != CTERN) if (es->tok != CTERN)
evalerr(es, ET_STR, "missing :"); evalerr(es, ET_STR, "missing :");
exprtoken(es);
if (ev) if (ev)
es->noassign++; es->noassign++;
exprtoken(es);
vr = evalexpr(es, P_TERN); vr = evalexpr(es, P_TERN);
if (ev) if (ev)
es->noassign--; es->noassign--;
@ -502,6 +511,7 @@ evalexpr(Expr_state *es, unsigned int prec)
case O_LAND: case O_LAND:
if (!t1) if (!t1)
es->noassign++; es->noassign++;
exprtoken(es);
vr = intvar(es, evalexpr(es, prec - 1)); vr = intvar(es, evalexpr(es, prec - 1));
res = t1 && vr->val.u; res = t1 && vr->val.u;
if (!t1) if (!t1)
@ -510,6 +520,7 @@ evalexpr(Expr_state *es, unsigned int prec)
case O_LOR: case O_LOR:
if (t1) if (t1)
es->noassign++; es->noassign++;
exprtoken(es);
vr = intvar(es, evalexpr(es, prec - 1)); vr = intvar(es, evalexpr(es, prec - 1));
res = t1 || vr->val.u; res = t1 || vr->val.u;
if (t1) if (t1)
@ -857,7 +868,7 @@ ksh_access(const char *fn, int mode)
} }
#ifndef MIRBSD_BOOTFLOPPY #ifndef MIRBSD_BOOTFLOPPY
/* From: X11/xc/programs/xterm/wcwidth.c,v 1.8 2014/06/24 19:53:53 tg Exp $ */ /* From: X11/xc/programs/xterm/wcwidth.c,v 1.9 */
struct mb_ucsrange { struct mb_ucsrange {
unsigned short beg; unsigned short beg;
@ -868,8 +879,8 @@ static int mb_ucsbsearch(const struct mb_ucsrange arr[], size_t elems,
unsigned int val) MKSH_A_PURE; unsigned int val) MKSH_A_PURE;
/* /*
* Generated by MirOS: contrib/code/Snippets/eawparse,v 1.2 2013/11/30 13:45:17 tg Exp $ * Generated from the Unicode Character Database, Version 9.0.0, by
* from the Unicode Character Database, Version 7.0.0 * MirOS: contrib/code/Snippets/eawparse,v 1.3 2014/11/16 12:16:24 tg Exp $
*/ */
static const struct mb_ucsrange mb_ucs_combining[] = { static const struct mb_ucsrange mb_ucs_combining[] = {
@ -899,7 +910,7 @@ static const struct mb_ucsrange mb_ucs_combining[] = {
{ 0x0825, 0x0827 }, { 0x0825, 0x0827 },
{ 0x0829, 0x082D }, { 0x0829, 0x082D },
{ 0x0859, 0x085B }, { 0x0859, 0x085B },
{ 0x08E4, 0x0902 }, { 0x08D4, 0x0902 },
{ 0x093A, 0x093A }, { 0x093A, 0x093A },
{ 0x093C, 0x093C }, { 0x093C, 0x093C },
{ 0x0941, 0x0948 }, { 0x0941, 0x0948 },
@ -994,6 +1005,7 @@ static const struct mb_ucsrange mb_ucs_combining[] = {
{ 0x17C9, 0x17D3 }, { 0x17C9, 0x17D3 },
{ 0x17DD, 0x17DD }, { 0x17DD, 0x17DD },
{ 0x180B, 0x180E }, { 0x180B, 0x180E },
{ 0x1885, 0x1886 },
{ 0x18A9, 0x18A9 }, { 0x18A9, 0x18A9 },
{ 0x1920, 0x1922 }, { 0x1920, 0x1922 },
{ 0x1927, 0x1928 }, { 0x1927, 0x1928 },
@ -1032,7 +1044,7 @@ static const struct mb_ucsrange mb_ucs_combining[] = {
{ 0x1CF4, 0x1CF4 }, { 0x1CF4, 0x1CF4 },
{ 0x1CF8, 0x1CF9 }, { 0x1CF8, 0x1CF9 },
{ 0x1DC0, 0x1DF5 }, { 0x1DC0, 0x1DF5 },
{ 0x1DFC, 0x1DFF }, { 0x1DFB, 0x1DFF },
{ 0x200B, 0x200F }, { 0x200B, 0x200F },
{ 0x202A, 0x202E }, { 0x202A, 0x202E },
{ 0x2060, 0x2064 }, { 0x2060, 0x2064 },
@ -1045,13 +1057,13 @@ static const struct mb_ucsrange mb_ucs_combining[] = {
{ 0x3099, 0x309A }, { 0x3099, 0x309A },
{ 0xA66F, 0xA672 }, { 0xA66F, 0xA672 },
{ 0xA674, 0xA67D }, { 0xA674, 0xA67D },
{ 0xA69F, 0xA69F }, { 0xA69E, 0xA69F },
{ 0xA6F0, 0xA6F1 }, { 0xA6F0, 0xA6F1 },
{ 0xA802, 0xA802 }, { 0xA802, 0xA802 },
{ 0xA806, 0xA806 }, { 0xA806, 0xA806 },
{ 0xA80B, 0xA80B }, { 0xA80B, 0xA80B },
{ 0xA825, 0xA826 }, { 0xA825, 0xA826 },
{ 0xA8C4, 0xA8C4 }, { 0xA8C4, 0xA8C5 },
{ 0xA8E0, 0xA8F1 }, { 0xA8E0, 0xA8F1 },
{ 0xA926, 0xA92D }, { 0xA926, 0xA92D },
{ 0xA947, 0xA951 }, { 0xA947, 0xA951 },
@ -1078,14 +1090,47 @@ static const struct mb_ucsrange mb_ucs_combining[] = {
{ 0xABED, 0xABED }, { 0xABED, 0xABED },
{ 0xFB1E, 0xFB1E }, { 0xFB1E, 0xFB1E },
{ 0xFE00, 0xFE0F }, { 0xFE00, 0xFE0F },
{ 0xFE20, 0xFE2D }, { 0xFE20, 0xFE2F },
{ 0xFEFF, 0xFEFF }, { 0xFEFF, 0xFEFF },
{ 0xFFF9, 0xFFFB } { 0xFFF9, 0xFFFB }
}; };
static const struct mb_ucsrange mb_ucs_fullwidth[] = { static const struct mb_ucsrange mb_ucs_fullwidth[] = {
{ 0x1100, 0x115F }, { 0x1100, 0x115F },
{ 0x231A, 0x231B },
{ 0x2329, 0x232A }, { 0x2329, 0x232A },
{ 0x23E9, 0x23EC },
{ 0x23F0, 0x23F0 },
{ 0x23F3, 0x23F3 },
{ 0x25FD, 0x25FE },
{ 0x2614, 0x2615 },
{ 0x2648, 0x2653 },
{ 0x267F, 0x267F },
{ 0x2693, 0x2693 },
{ 0x26A1, 0x26A1 },
{ 0x26AA, 0x26AB },
{ 0x26BD, 0x26BE },
{ 0x26C4, 0x26C5 },
{ 0x26CE, 0x26CE },
{ 0x26D4, 0x26D4 },
{ 0x26EA, 0x26EA },
{ 0x26F2, 0x26F3 },
{ 0x26F5, 0x26F5 },
{ 0x26FA, 0x26FA },
{ 0x26FD, 0x26FD },
{ 0x2705, 0x2705 },
{ 0x270A, 0x270B },
{ 0x2728, 0x2728 },
{ 0x274C, 0x274C },
{ 0x274E, 0x274E },
{ 0x2753, 0x2755 },
{ 0x2757, 0x2757 },
{ 0x2795, 0x2797 },
{ 0x27B0, 0x27B0 },
{ 0x27BF, 0x27BF },
{ 0x2B1B, 0x2B1C },
{ 0x2B50, 0x2B50 },
{ 0x2B55, 0x2B55 },
{ 0x2E80, 0x303E }, { 0x2E80, 0x303E },
{ 0x3040, 0xA4CF }, { 0x3040, 0xA4CF },
{ 0xA960, 0xA97F }, { 0xA960, 0xA97F },

View file

@ -38,7 +38,7 @@
#endif #endif
#endif #endif
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.305 2016/08/01 21:38:02 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.319 2016/11/11 23:48:29 tg Exp $");
#if HAVE_KILLPG #if HAVE_KILLPG
/* /*
@ -122,7 +122,9 @@ const struct builtin mkshbuiltins[] = {
{"kill", c_kill}, {"kill", c_kill},
{"let", c_let}, {"let", c_let},
{"let]", c_let}, {"let]", c_let},
#if !defined(__ANDROID__)
{"print", c_print}, {"print", c_print},
#endif
{"pwd", c_pwd}, {"pwd", c_pwd},
{Tread, c_read}, {Tread, c_read},
{Tsgreadonly, c_typeset}, {Tsgreadonly, c_typeset},
@ -162,9 +164,9 @@ const struct builtin mkshbuiltins[] = {
{"~printf", c_printf}, {"~printf", c_printf},
#endif #endif
#if HAVE_SELECT #if HAVE_SELECT
# if !defined(__ANDROID__) #if !defined(__ANDROID__)
{"sleep", c_sleep}, {"sleep", c_sleep},
# endif #endif
#endif #endif
#ifdef __MirBSD__ #ifdef __MirBSD__
/* alias to "true" for historical reasons */ /* alias to "true" for historical reasons */
@ -286,17 +288,46 @@ static void s_put(int);
int int
c_print(const char **wp) c_print(const char **wp)
{ {
int fd = 1, c; int c;
const char *s; const char *s;
XString xs;
char *xp; char *xp;
/* print newline; expand backslash sequences */ XString xs;
bool po_nl = true, po_exp = true; struct {
/* print to history instead of file descriptor / stdout */ /* storage for columnisation */
bool po_hist = false; XPtrV words;
/* print characters */ /* temporary storage for a wide character */
bool po_char = false; mksh_ari_t wc;
char ts[4]; /* output file descriptor (if any) */
int fd;
/* temporary storage for a multibyte character */
char ts[4];
/* output word separator */
char ws;
/* output line separator */
char ls;
/* output a trailing line separator? */
bool nl;
/* expand backslash sequences? */
bool exp;
/* columnise output? */
bool col;
/* print to history instead of file descriptor / stdout? */
bool hist;
/* print words as wide characters? */
bool chars;
/* print a "--" argument? */
bool pminusminus;
/* writing to a coprocess (SIGPIPE blocked)? */
bool coproc;
bool copipe;
} po;
memset(&po, 0, sizeof(po));
po.fd = 1;
po.ws = ' ';
po.ls = '\n';
po.nl = true;
po.exp = true;
if (wp[0][0] == 'e') { if (wp[0][0] == 'e') {
/* "echo" builtin */ /* "echo" builtin */
@ -308,7 +339,7 @@ c_print(const char **wp)
* one that supports -e but does not enable it by * one that supports -e but does not enable it by
* default * default
*/ */
po_exp = false; po.exp = false;
} }
#endif #endif
if (Flag(FPOSIX) || if (Flag(FPOSIX) ||
@ -319,13 +350,13 @@ c_print(const char **wp)
/* Debian Policy 10.4 compliant "echo" builtin */ /* Debian Policy 10.4 compliant "echo" builtin */
if (*wp && !strcmp(*wp, "-n")) { if (*wp && !strcmp(*wp, "-n")) {
/* recognise "-n" only as the first arg */ /* recognise "-n" only as the first arg */
po_nl = false; po.nl = false;
++wp; ++wp;
} }
/* print everything as-is */ /* print everything as-is */
po_exp = false; po.exp = false;
} else { } else {
bool new_exp = po_exp, new_nl = po_nl; bool new_exp = po.exp, new_nl = po.nl;
/** /**
* a compromise between sysV and BSD echo commands: * a compromise between sysV and BSD echo commands:
@ -352,8 +383,8 @@ c_print(const char **wp)
new_nl = false; new_nl = false;
goto print_tradparse_ch; goto print_tradparse_ch;
case '\0': case '\0':
po_exp = new_exp; po.exp = new_exp;
po_nl = new_nl; po.nl = new_nl;
++wp; ++wp;
goto print_tradparse_arg; goto print_tradparse_arg;
} }
@ -361,44 +392,54 @@ c_print(const char **wp)
} }
} else { } else {
/* "print" builtin */ /* "print" builtin */
const char *opts = "AnpRrsu,"; const char *opts = "AclNnpRrsu,";
const char *emsg; const char *emsg;
/* print a "--" argument */
bool po_pminusminus = false; po.pminusminus = false;
while ((c = ksh_getopt(wp, &builtin_opt, opts)) != -1) while ((c = ksh_getopt(wp, &builtin_opt, opts)) != -1)
switch (c) { switch (c) {
case 'A': case 'A':
po_char = true; po.chars = true;
break;
case 'c':
po.col = true;
break; break;
case 'e': case 'e':
po_exp = true; po.exp = true;
break;
case 'l':
po.ws = '\n';
break;
case 'N':
po.ws = '\0';
po.ls = '\0';
break; break;
case 'n': case 'n':
po_nl = false; po.nl = false;
break; break;
case 'p': case 'p':
if ((fd = coproc_getfd(W_OK, &emsg)) < 0) { if ((po.fd = coproc_getfd(W_OK, &emsg)) < 0) {
bi_errorf(Tf_coproc, emsg); bi_errorf(Tf_coproc, emsg);
return (1); return (1);
} }
break; break;
case 'R': case 'R':
/* fake BSD echo command */ /* fake BSD echo command */
po_pminusminus = true; po.pminusminus = true;
po_exp = false; po.exp = false;
opts = "en"; opts = "en";
break; break;
case 'r': case 'r':
po_exp = false; po.exp = false;
break; break;
case 's': case 's':
po_hist = true; po.hist = true;
break; break;
case 'u': case 'u':
if (!*(s = builtin_opt.optarg)) if (!*(s = builtin_opt.optarg))
fd = 0; po.fd = 0;
else if ((fd = check_fd(s, W_OK, &emsg)) < 0) { else if ((po.fd = check_fd(s, W_OK, &emsg)) < 0) {
bi_errorf("-u%s: %s", s, emsg); bi_errorf("-u%s: %s", s, emsg);
return (1); return (1);
} }
@ -412,35 +453,45 @@ c_print(const char **wp)
if (wp[builtin_opt.optind] && if (wp[builtin_opt.optind] &&
ksh_isdash(wp[builtin_opt.optind])) ksh_isdash(wp[builtin_opt.optind]))
builtin_opt.optind++; builtin_opt.optind++;
} else if (po_pminusminus) } else if (po.pminusminus)
builtin_opt.optind--; builtin_opt.optind--;
wp += builtin_opt.optind; wp += builtin_opt.optind;
} }
if (po.col) {
if (*wp == NULL)
return (0);
XPinit(po.words, 16);
}
Xinit(xs, xp, 128, ATEMP); Xinit(xs, xp, 128, ATEMP);
if (*wp != NULL && po_char) { if (*wp == NULL)
mksh_ari_t wc; goto print_no_arg;
print_read_arg:
do { if (po.chars) {
if (!evaluate(*wp, &wc, KSH_RETURN_ERROR, true)) while (*wp != NULL) {
s = *wp++;
if (*s == '\0')
break;
if (!evaluate(s, &po.wc, KSH_RETURN_ERROR, true))
return (1); return (1);
Xcheck(xs, xp); Xcheck(xs, xp);
if (UTFMODE) { if (UTFMODE) {
ts[utf_wctomb(ts, wc)] = 0; po.ts[utf_wctomb(po.ts, po.wc)] = 0;
c = 0; c = 0;
do { do {
Xput(xs, xp, ts[c]); Xput(xs, xp, po.ts[c]);
} while (ts[++c]); } while (po.ts[++c]);
} else } else
Xput(xs, xp, wc & 0xFF); Xput(xs, xp, po.wc & 0xFF);
} while (*++wp); }
} else if (*wp != NULL) { } else {
print_read_arg: s = *wp++;
s = *wp;
while ((c = *s++) != '\0') { while ((c = *s++) != '\0') {
Xcheck(xs, xp); Xcheck(xs, xp);
if (po_exp && c == '\\') { if (po.exp && c == '\\') {
s_ptr = s; s_ptr = s;
c = unbksl(false, s_get, s_put); c = unbksl(false, s_get, s_put);
s = s_ptr; s = s_ptr;
@ -448,7 +499,7 @@ c_print(const char **wp)
/* rejected by generic function */ /* rejected by generic function */
switch ((c = *s++)) { switch ((c = *s++)) {
case 'c': case 'c':
po_nl = false; po.nl = false;
/* AT&T brain damage */ /* AT&T brain damage */
continue; continue;
case '\0': case '\0':
@ -460,33 +511,55 @@ c_print(const char **wp)
} }
} else if ((unsigned int)c > 0xFF) { } else if ((unsigned int)c > 0xFF) {
/* generic function returned Unicode */ /* generic function returned Unicode */
ts[utf_wctomb(ts, c - 0x100)] = 0; po.ts[utf_wctomb(po.ts, c - 0x100)] = 0;
c = 0; c = 0;
do { do {
Xput(xs, xp, ts[c]); Xput(xs, xp, po.ts[c]);
} while (ts[++c]); } while (po.ts[++c]);
continue; continue;
} }
} }
Xput(xs, xp, c); Xput(xs, xp, c);
} }
if (*++wp != NULL) {
Xput(xs, xp, ' ');
goto print_read_arg;
}
} }
if (po_nl) if (po.col) {
Xput(xs, xp, '\n'); Xput(xs, xp, '\0');
XPput(po.words, Xclose(xs, xp));
Xinit(xs, xp, 128, ATEMP);
}
if (*wp != NULL) {
if (!po.col)
Xput(xs, xp, po.ws);
goto print_read_arg;
}
if (po.col) {
size_t w = XPsize(po.words);
struct columnise_opts co;
XPput(po.words, NULL);
co.shf = shf_sopen(NULL, 128, SHF_WR | SHF_DYNAMIC, NULL);
co.linesep = po.ls;
co.prefcol = co.do_last = false;
pr_list(&co, (char **)XPptrv(po.words));
while (w--)
afree(XPptrv(po.words)[w], ATEMP);
XPfree(po.words);
w = co.shf->wp - co.shf->buf;
XcheckN(xs, xp, w);
memcpy(xp, co.shf->buf, w);
xp += w;
shf_sclose(co.shf);
}
print_no_arg:
if (po.nl)
Xput(xs, xp, po.ls);
c = 0; c = 0;
if (po_hist) { if (po.hist) {
Xput(xs, xp, '\0'); Xput(xs, xp, '\0');
histsave(&source->line, Xstring(xs, xp), HIST_STORE, false); histsave(&source->line, Xstring(xs, xp), HIST_STORE, false);
Xfree(xs, xp);
} else { } else {
size_t len = Xlength(xs, xp); size_t len = Xlength(xs, xp);
bool po_coproc = false;
int opipe = 0;
/* /*
* Ensure we aren't killed by a SIGPIPE while writing to * Ensure we aren't killed by a SIGPIPE while writing to
@ -494,24 +567,25 @@ c_print(const char **wp)
* to just check that the co-process is alive which is * to just check that the co-process is alive which is
* not enough). * not enough).
*/ */
if (coproc.write >= 0 && coproc.write == fd) { if (coproc.write >= 0 && coproc.write == po.fd) {
po_coproc = true; po.coproc = true;
opipe = block_pipe(); po.copipe = block_pipe();
} } else
po.coproc = po.copipe = false;
s = Xstring(xs, xp); s = Xstring(xs, xp);
while (len > 0) { while (len > 0) {
ssize_t nwritten; ssize_t nwritten;
if ((nwritten = write(fd, s, len)) < 0) { if ((nwritten = write(po.fd, s, len)) < 0) {
if (errno == EINTR) { if (errno == EINTR) {
if (po_coproc) if (po.copipe)
restore_pipe(opipe); restore_pipe();
/* give the user a chance to ^C out */ /* give the user a chance to ^C out */
intrcheck(); intrcheck();
/* interrupted, try again */ /* interrupted, try again */
if (po_coproc) if (po.coproc)
opipe = block_pipe(); po.copipe = block_pipe();
continue; continue;
} }
c = 1; c = 1;
@ -520,9 +594,10 @@ c_print(const char **wp)
s += nwritten; s += nwritten;
len -= nwritten; len -= nwritten;
} }
if (po_coproc) if (po.copipe)
restore_pipe(opipe); restore_pipe();
} }
Xfree(xs, xp);
return (c); return (c);
} }
@ -1431,6 +1506,7 @@ c_kill(const char **wp)
ssize_t w, mess_cols = 0, mess_octs = 0; ssize_t w, mess_cols = 0, mess_octs = 0;
int j = ksh_NSIG - 1; int j = ksh_NSIG - 1;
struct kill_info ki = { 0, 0 }; struct kill_info ki = { 0, 0 };
struct columnise_opts co;
do { do {
ki.num_width++; ki.num_width++;
@ -1448,11 +1524,14 @@ c_kill(const char **wp)
mess_cols = w; mess_cols = w;
} }
print_columns(shl_stdout, (unsigned int)(ksh_NSIG - 1), co.shf = shl_stdout;
co.linesep = '\n';
co.prefcol = co.do_last = true;
print_columns(&co, (unsigned int)(ksh_NSIG - 1),
kill_fmt_entry, (void *)&ki, kill_fmt_entry, (void *)&ki,
ki.num_width + 1 + ki.name_width + 1 + mess_octs, ki.num_width + 1 + ki.name_width + 1 + mess_octs,
ki.num_width + 1 + ki.name_width + 1 + mess_cols, ki.num_width + 1 + ki.name_width + 1 + mess_cols);
true);
} }
return (0); return (0);
} }
@ -2013,7 +2092,7 @@ c_read(const char **wp)
timersub(&tvlim, &tv, &tv); timersub(&tvlim, &tv, &tv);
if (tv.tv_sec < 0) { if (tv.tv_sec < 0) {
/* timeout expired globally */ /* timeout expired globally */
rv = 1; rv = 3;
goto c_read_out; goto c_read_out;
} }
@ -2023,8 +2102,8 @@ c_read(const char **wp)
case 0: case 0:
/* timeout expired for this call */ /* timeout expired for this call */
bytesread = 0; bytesread = 0;
/* fake EOF read; all cases return 1 */ rv = 3;
goto c_read_didread; goto c_read_readdone;
default: default:
bi_errorf(Tf_sD_s, Tselect, cstrerror(errno)); bi_errorf(Tf_sD_s, Tselect, cstrerror(errno));
rv = 2; rv = 2;
@ -2049,7 +2128,6 @@ c_read(const char **wp)
goto c_read_out; goto c_read_out;
} }
c_read_didread:
switch (readmode) { switch (readmode) {
case READALL: case READALL:
if (bytesread == 0) { if (bytesread == 0) {
@ -2123,13 +2201,13 @@ c_read(const char **wp)
/*- /*-
* state: we finished reading the input and NUL terminated it * state: we finished reading the input and NUL terminated it
* Xstring(xs, xp) -> xp-1 = input string without trailing delim * Xstring(xs, xp) -> xp-1 = input string without trailing delim
* rv = 1 if EOF, 0 otherwise (errors handled already) * rv = 3 if timeout, 1 if EOF, 0 otherwise (errors handled already)
*/ */
if (rv == 1) { if (rv) {
/* clean up coprocess if needed, on EOF */ /* clean up coprocess if needed, on EOF/error/timeout */
coproc_read_close(fd); coproc_read_close(fd);
if (readmode == READALL) if (readmode == READALL && (rv == 1 || (rv == 3 && bytesread)))
/* EOF is no error here */ /* EOF is no error here */
rv = 0; rv = 0;
} }
@ -2295,7 +2373,7 @@ c_read(const char **wp)
Xfree(xs, xp); Xfree(xs, xp);
if (restore_tios) if (restore_tios)
mksh_tcset(fd, &tios); mksh_tcset(fd, &tios);
return (rv); return (rv == 3 ? ksh_sigmask(SIGALRM) : rv);
#undef is_ifsws #undef is_ifsws
} }
@ -3727,7 +3805,7 @@ c_cat(const char **wp)
ssize_t n, w; ssize_t n, w;
const char *fn = "<stdin>"; const char *fn = "<stdin>";
char *buf, *cp; char *buf, *cp;
int opipe = 0; bool opipe;
#define MKSH_CAT_BUFSIZ 4096 #define MKSH_CAT_BUFSIZ 4096
/* parse options: POSIX demands we support "-u" as no-op */ /* parse options: POSIX demands we support "-u" as no-op */
@ -3767,7 +3845,8 @@ c_cat(const char **wp)
if ((n = blocking_read(fd, (cp = buf), if ((n = blocking_read(fd, (cp = buf),
MKSH_CAT_BUFSIZ)) == -1) { MKSH_CAT_BUFSIZ)) == -1) {
if (errno == EINTR) { if (errno == EINTR) {
restore_pipe(opipe); if (opipe)
restore_pipe();
/* give the user a chance to ^C out */ /* give the user a chance to ^C out */
intrcheck(); intrcheck();
/* interrupted, try again */ /* interrupted, try again */
@ -3782,13 +3861,17 @@ c_cat(const char **wp)
/* end of file reached */ /* end of file reached */
break; break;
while (n) { while (n) {
if (intrsig)
goto has_intrsig;
if ((w = write(STDOUT_FILENO, cp, n)) != -1) { if ((w = write(STDOUT_FILENO, cp, n)) != -1) {
n -= w; n -= w;
cp += w; cp += w;
continue; continue;
} }
if (errno == EINTR) { if (errno == EINTR) {
restore_pipe(opipe); has_intrsig:
if (opipe)
restore_pipe();
/* give the user a chance to ^C out */ /* give the user a chance to ^C out */
intrcheck(); intrcheck();
/* interrupted, try again */ /* interrupted, try again */
@ -3814,7 +3897,8 @@ c_cat(const char **wp)
} while (*wp); } while (*wp);
out: out:
restore_pipe(opipe); if (opipe)
restore_pipe();
free_osfunc(buf); free_osfunc(buf);
return (rv); return (rv);
} }

View file

@ -27,7 +27,7 @@
#include <sys/file.h> #include <sys/file.h>
#endif #endif
__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.158 2016/08/04 20:31:00 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.159 2016/11/11 18:44:32 tg Exp $");
Trap sigtraps[ksh_NSIG + 1]; Trap sigtraps[ksh_NSIG + 1];
static struct sigaction Sigact_ign; static struct sigaction Sigact_ign;
@ -1399,33 +1399,32 @@ settrap(Trap *p, const char *s)
} }
/* /*
* Called by c_print() when writing to a co-process to ensure SIGPIPE won't * called by c_print() when writing to a co-process to ensure
* kill shell (unless user catches it and exits) * SIGPIPE won't kill shell (unless user catches it and exits)
*/ */
int bool
block_pipe(void) block_pipe(void)
{ {
int restore_dfl = 0; bool restore_dfl = false;
Trap *p = &sigtraps[SIGPIPE]; Trap *p = &sigtraps[SIGPIPE];
if (!(p->flags & (TF_ORIG_IGN|TF_ORIG_DFL))) { if (!(p->flags & (TF_ORIG_IGN|TF_ORIG_DFL))) {
setsig(p, SIG_IGN, SS_RESTORE_CURR); setsig(p, SIG_IGN, SS_RESTORE_CURR);
if (p->flags & TF_ORIG_DFL) if (p->flags & TF_ORIG_DFL)
restore_dfl = 1; restore_dfl = true;
} else if (p->cursig == SIG_DFL) { } else if (p->cursig == SIG_DFL) {
setsig(p, SIG_IGN, SS_RESTORE_CURR); setsig(p, SIG_IGN, SS_RESTORE_CURR);
/* restore to SIG_DFL */ /* restore to SIG_DFL */
restore_dfl = 1; restore_dfl = true;
} }
return (restore_dfl); return (restore_dfl);
} }
/* Called by c_print() to undo whatever block_pipe() did */ /* called by c_print() to undo whatever block_pipe() did */
void void
restore_pipe(int restore_dfl) restore_pipe(void)
{ {
if (restore_dfl) setsig(&sigtraps[SIGPIPE], SIG_DFL, SS_RESTORE_CURR);
setsig(&sigtraps[SIGPIPE], SIG_DFL, SS_RESTORE_CURR);
} }
/* /*

View file

@ -1,4 +1,4 @@
.\" $MirOS: src/bin/mksh/lksh.1,v 1.18 2016/08/10 18:20:05 tg Exp $ .\" $MirOS: src/bin/mksh/lksh.1,v 1.20 2016/11/11 23:31:35 tg Exp $
.\"- .\"-
.\" Copyright (c) 2008, 2009, 2010, 2012, 2013, 2015, 2016 .\" Copyright (c) 2008, 2009, 2010, 2012, 2013, 2015, 2016
.\" mirabilos <m@mirbsd.org> .\" mirabilos <m@mirbsd.org>
@ -74,7 +74,7 @@
.\" with -mandoc, it might implement .Mx itself, but we want to .\" with -mandoc, it might implement .Mx itself, but we want to
.\" use our own definition. And .Dd must come *first*, always. .\" use our own definition. And .Dd must come *first*, always.
.\" .\"
.Dd $Mdocdate: August 10 2016 $ .Dd $Mdocdate: November 11 2016 $
.\" .\"
.\" Check which macro package we use, and do other -mdoc setup. .\" Check which macro package we use, and do other -mdoc setup.
.\" .\"
@ -209,9 +209,9 @@ The
string identifies string identifies
.Nm .Nm
as as
.Dq LEGACY KSH .Dq Li LEGACY KSH
instead of instead of
.Dq MIRBSD KSH . .Dq Li MIRBSD KSH .
Note that the rest of the version string is identical between Note that the rest of the version string is identical between
the two shell flavours, and the behaviour and differences can the two shell flavours, and the behaviour and differences can
change between versions; see the accompanying manual page change between versions; see the accompanying manual page
@ -221,8 +221,8 @@ for the versions this document applies to.
.Nm .Nm
uses uses
.Tn POSIX .Tn POSIX
arithmetics, which has quite a few implications: arithmetic, which has quite a few implications:
The data type for arithmetics is the host The data type for arithmetic operations is the host
.Tn ISO .Tn ISO
C C
.Vt long .Vt long

View file

@ -34,7 +34,7 @@
#include <locale.h> #include <locale.h>
#endif #endif
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.317 2016/08/04 20:51:35 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/main.c,v 1.322 2016/11/11 23:48:30 tg Exp $");
extern char **environ; extern char **environ;
@ -59,7 +59,12 @@ static void x_sigwinch(int);
static const char initifs[] = "IFS= \t\n"; static const char initifs[] = "IFS= \t\n";
static const char initsubs[] = static const char initsubs[] =
"${PS2=> } ${PS3=#? } ${PS4=+ } ${SECONDS=0} ${TMOUT=0} ${EPOCHREALTIME=}"; "${PS2=> }"
"${PS3=#? }"
"${PS4=+ }"
"${SECONDS=0}"
"${TMOUT=0}"
"${EPOCHREALTIME=}";
static const char *initcoms[] = { static const char *initcoms[] = {
Ttypeset, "-r", initvsn, NULL, Ttypeset, "-r", initvsn, NULL,
@ -111,10 +116,8 @@ rndsetup(void)
char *cp; char *cp;
cp = alloc(sizeof(*bufptr) - sizeof(ALLOC_ITEM), APERM); cp = alloc(sizeof(*bufptr) - sizeof(ALLOC_ITEM), APERM);
#ifdef DEBUG /* clear the allocated space, for valgrind and to avoid UB */
/* clear the allocated space, for valgrind */
memset(cp, 0, sizeof(*bufptr) - sizeof(ALLOC_ITEM)); memset(cp, 0, sizeof(*bufptr) - sizeof(ALLOC_ITEM));
#endif
/* undo what alloc() did to the malloc result address */ /* undo what alloc() did to the malloc result address */
bufptr = (void *)(cp - sizeof(ALLOC_ITEM)); bufptr = (void *)(cp - sizeof(ALLOC_ITEM));
/* PIE or something similar provides us with deltas here */ /* PIE or something similar provides us with deltas here */
@ -222,11 +225,11 @@ main_init(int argc, const char *argv[], Source **sp, struct block **lp)
/* determine the basename (without '-' or path) of the executable */ /* determine the basename (without '-' or path) of the executable */
ccp = kshname; ccp = kshname;
goto begin_parse_kshname; goto begin_parsing_kshname;
while ((i = ccp[argi++])) { while ((i = ccp[argi++])) {
if (i == '/') { if (mksh_cdirsep(i)) {
ccp += argi; ccp += argi;
begin_parse_kshname: begin_parsing_kshname:
argi = 0; argi = 0;
if (*ccp == '-') if (*ccp == '-')
++ccp; ++ccp;
@ -563,8 +566,8 @@ main_init(int argc, const char *argv[], Source **sp, struct block **lp)
#endif #endif
if (!isuc(ccp)) if (!isuc(ccp))
ccp = null; ccp = null;
/* FALLTHROUGH */
#endif #endif
/* FALLTHROUGH */
/* auto-detect from environment */ /* auto-detect from environment */
case 3: case 3:

View file

@ -30,7 +30,7 @@
#include <grp.h> #include <grp.h>
#endif #endif
__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.245 2016/08/01 18:42:42 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/misc.c,v 1.249 2016/11/11 23:31:35 tg Exp $");
#define KSH_CHVT_FLAG #define KSH_CHVT_FLAG
#ifdef MKSH_SMALL #ifdef MKSH_SMALL
@ -195,6 +195,7 @@ printoptions(bool verbose)
if (verbose) { if (verbose) {
size_t n = 0, len, octs = 0; size_t n = 0, len, octs = 0;
struct options_info oi; struct options_info oi;
struct columnise_opts co;
/* verbose version */ /* verbose version */
shf_puts("Current option settings\n", shl_stdout); shf_puts("Current option settings\n", shl_stdout);
@ -211,8 +212,11 @@ printoptions(bool verbose)
} }
++i; ++i;
} }
print_columns(shl_stdout, n, options_fmt_entry, &oi, co.shf = shl_stdout;
octs + 4, oi.opt_width + 4, true); co.linesep = '\n';
co.prefcol = co.do_last = true;
print_columns(&co, n, options_fmt_entry, &oi,
octs + 4, oi.opt_width + 4);
} else { } else {
/* short version like AT&T ksh93 */ /* short version like AT&T ksh93 */
shf_puts(Tset, shl_stdout); shf_puts(Tset, shl_stdout);
@ -387,7 +391,7 @@ parse_args(const char **argv,
*/ */
if (*p != '-') if (*p != '-')
for (q = p; *q; ) for (q = p; *q; )
if (*q++ == '/') if (mksh_cdirsep(*q++))
p = q; p = q;
Flag(FLOGIN) = (*p == '-'); Flag(FLOGIN) = (*p == '-');
opts = cmd_opts; opts = cmd_opts;
@ -1226,11 +1230,11 @@ print_value_quoted(struct shf *shf, const char *s)
* the i-th element * the i-th element
*/ */
void void
print_columns(struct shf *shf, unsigned int n, print_columns(struct columnise_opts *opts, unsigned int n,
void (*func)(char *, size_t, unsigned int, const void *), void (*func)(char *, size_t, unsigned int, const void *),
const void *arg, size_t max_oct, size_t max_colz, bool prefcol) const void *arg, size_t max_oct, size_t max_colz)
{ {
unsigned int i, r, c, rows, cols, nspace, max_col; unsigned int i, r = 0, c, rows, cols, nspace, max_col;
char *str; char *str;
if (!n) if (!n)
@ -1265,16 +1269,18 @@ print_columns(struct shf *shf, unsigned int n,
/* if we can only print one column anyway, skip the goo */ /* if we can only print one column anyway, skip the goo */
if (cols < 2) { if (cols < 2) {
for (i = 0; i < n; ++i) { goto prcols_easy;
(*func)(str, max_oct, i, arg); while (r < n) {
shf_puts(str, shf); shf_putc(opts->linesep, opts->shf);
shf_putc('\n', shf); prcols_easy:
(*func)(str, max_oct, r++, arg);
shf_puts(str, opts->shf);
} }
goto out; goto out;
} }
rows = (n + cols - 1) / cols; rows = (n + cols - 1) / cols;
if (prefcol && cols > rows) { if (opts->prefcol && cols > rows) {
cols = rows; cols = rows;
rows = (n + cols - 1) / cols; rows = (n + cols - 1) / cols;
} }
@ -1283,20 +1289,25 @@ print_columns(struct shf *shf, unsigned int n,
if (nspace < 2) if (nspace < 2)
nspace = 2; nspace = 2;
max_col = -max_col; max_col = -max_col;
for (r = 0; r < rows; r++) { goto prcols_hard;
while (r < rows) {
shf_putchar(opts->linesep, opts->shf);
prcols_hard:
for (c = 0; c < cols; c++) { for (c = 0; c < cols; c++) {
if ((i = c * rows + r) >= n) if ((i = c * rows + r) >= n)
break; break;
(*func)(str, max_oct, i, arg); (*func)(str, max_oct, i, arg);
if (i + rows >= n) if (i + rows >= n)
shf_puts(str, shf); shf_puts(str, opts->shf);
else else
shf_fprintf(shf, "%*s%*s", shf_fprintf(opts->shf, "%*s%*s",
(int)max_col, str, (int)nspace, null); (int)max_col, str, (int)nspace, null);
} }
shf_putchar('\n', shf); ++r;
} }
out: out:
if (opts->do_last)
shf_putchar(opts->linesep, opts->shf);
afree(str, ATEMP); afree(str, ATEMP);
} }
@ -1432,14 +1443,14 @@ do_realpath(const char *upath)
while (*ip) { while (*ip) {
/* skip slashes in input */ /* skip slashes in input */
while (*ip == '/') while (mksh_cdirsep(*ip))
++ip; ++ip;
if (!*ip) if (!*ip)
break; break;
/* get next pathname component from input */ /* get next pathname component from input */
tp = ip; tp = ip;
while (*ip && *ip != '/') while (*ip && !mksh_cdirsep(*ip))
++ip; ++ip;
len = ip - tp; len = ip - tp;
@ -1451,7 +1462,7 @@ do_realpath(const char *upath)
else if (len == 2 && tp[1] == '.') { else if (len == 2 && tp[1] == '.') {
/* strip off last pathname component */ /* strip off last pathname component */
while (xp > Xstring(xs, xp)) while (xp > Xstring(xs, xp))
if (*--xp == '/') if (mksh_cdirsep(*--xp))
break; break;
/* then continue with the next one */ /* then continue with the next one */
continue; continue;
@ -1474,7 +1485,7 @@ do_realpath(const char *upath)
/* lstat failed */ /* lstat failed */
if (errno == ENOENT) { if (errno == ENOENT) {
/* because the pathname does not exist */ /* because the pathname does not exist */
while (*ip == '/') while (mksh_cdirsep(*ip))
/* skip any trailing slashes */ /* skip any trailing slashes */
++ip; ++ip;
/* no more components left? */ /* no more components left? */
@ -1534,6 +1545,7 @@ do_realpath(const char *upath)
/* assert: xp == xs.beg => start of path */ /* assert: xp == xs.beg => start of path */
/* exactly two leading slashes? (SUSv4 3.266) */ /* exactly two leading slashes? (SUSv4 3.266) */
/* @komh do NOT use mksh_cdirsep() here */
if (ip[1] == '/' && ip[2] != '/') { if (ip[1] == '/' && ip[2] != '/') {
/* keep them, e.g. for UNC pathnames */ /* keep them, e.g. for UNC pathnames */
Xput(xs, xp, '/'); Xput(xs, xp, '/');
@ -1559,7 +1571,7 @@ do_realpath(const char *upath)
* if source path had a trailing slash, check if target path * if source path had a trailing slash, check if target path
* is not a non-directory existing file * is not a non-directory existing file
*/ */
if (ip > ipath && ip[-1] == '/') { if (ip > ipath && mksh_cdirsep(ip[-1])) {
if (stat(Xstring(xs, xp), &sb)) { if (stat(Xstring(xs, xp), &sb)) {
if (errno != ENOENT) if (errno != ENOENT)
goto notfound; goto notfound;
@ -1628,7 +1640,7 @@ make_path(const char *cwd, const char *file,
if (c == '.') if (c == '.')
c = file[2]; c = file[2];
if (c == '/' || c == '\0') if (mksh_cdirsep(c) || c == '\0')
use_cdpath = false; use_cdpath = false;
} }
@ -1650,7 +1662,7 @@ make_path(const char *cwd, const char *file,
XcheckN(*xsp, xp, len); XcheckN(*xsp, xp, len);
memcpy(xp, cwd, len); memcpy(xp, cwd, len);
xp += len; xp += len;
if (cwd[len - 1] != '/') if (!mksh_cdirsep(cwd[len - 1]))
Xput(*xsp, xp, '/'); Xput(*xsp, xp, '/');
} }
*phys_pathp = Xlength(*xsp, xp); *phys_pathp = Xlength(*xsp, xp);
@ -1658,7 +1670,7 @@ make_path(const char *cwd, const char *file,
XcheckN(*xsp, xp, plen); XcheckN(*xsp, xp, plen);
memcpy(xp, plist, plen); memcpy(xp, plist, plen);
xp += plen; xp += plen;
if (plist[plen - 1] != '/') if (!mksh_cdirsep(plist[plen - 1]))
Xput(*xsp, xp, '/'); Xput(*xsp, xp, '/');
rval = 1; rval = 1;
} }
@ -1700,9 +1712,14 @@ simplify_path(char *p)
return; return;
case '/': case '/':
/* exactly two leading slashes? (SUSv4 3.266) */ /* exactly two leading slashes? (SUSv4 3.266) */
/* @komh no mksh_cdirsep() here! */
if (p[1] == '/' && p[2] != '/') if (p[1] == '/' && p[2] != '/')
/* keep them, e.g. for UNC pathnames */ /* keep them, e.g. for UNC pathnames */
++p; ++p;
#ifdef __OS2__
/* FALLTHROUGH */
case '\\':
#endif
needslash = true; needslash = true;
break; break;
default: default:
@ -1712,14 +1729,14 @@ simplify_path(char *p)
while (*ip) { while (*ip) {
/* skip slashes in input */ /* skip slashes in input */
while (*ip == '/') while (mksh_cdirsep(*ip))
++ip; ++ip;
if (!*ip) if (!*ip)
break; break;
/* get next pathname component from input */ /* get next pathname component from input */
tp = ip; tp = ip;
while (*ip && *ip != '/') while (*ip && !mksh_cdirsep(*ip))
++ip; ++ip;
len = ip - tp; len = ip - tp;
@ -1739,7 +1756,7 @@ simplify_path(char *p)
strip_last_component: strip_last_component:
/* strip off last pathname component */ /* strip off last pathname component */
while (dp > sp) while (dp > sp)
if (*--dp == '/') if (mksh_cdirsep(*--dp))
break; break;
} else { } else {
/* relative path, at its beginning */ /* relative path, at its beginning */

File diff suppressed because it is too large Load diff

View file

@ -175,9 +175,9 @@
#endif #endif
#ifdef EXTERN #ifdef EXTERN
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.786 2016/08/12 16:48:05 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/sh.h,v 1.791 2016/11/11 23:31:38 tg Exp $");
#endif #endif
#define MKSH_VERSION "R53 2016/08/12" #define MKSH_VERSION "R54 2016/11/11"
/* arithmetic types: C implementation */ /* arithmetic types: C implementation */
#if !HAVE_CAN_INTTYPES #if !HAVE_CAN_INTTYPES
@ -578,7 +578,7 @@ char *ucstrstr(char *, const char *);
#define mkssert(e) do { } while (/* CONSTCOND */ 0) #define mkssert(e) do { } while (/* CONSTCOND */ 0)
#endif #endif
#if (!defined(MKSH_BUILDMAKEFILE4BSD) && !defined(MKSH_BUILDSH)) || (MKSH_BUILD_R != 530) #if (!defined(MKSH_BUILDMAKEFILE4BSD) && !defined(MKSH_BUILDSH)) || (MKSH_BUILD_R != 541)
#error Must run Build.sh to compile this. #error Must run Build.sh to compile this.
extern void thiswillneverbedefinedIhope(void); extern void thiswillneverbedefinedIhope(void);
int int
@ -1350,7 +1350,7 @@ EXTERN mksh_ari_t x_lins E_INIT(24);
/* Determine the location of the system (common) profile */ /* Determine the location of the system (common) profile */
#ifndef MKSH_DEFAULT_PROFILEDIR #ifndef MKSH_DEFAULT_PROFILEDIR
#define MKSH_DEFAULT_PROFILEDIR "/etc" #define MKSH_DEFAULT_PROFILEDIR MKSH_UNIXROOT "/etc"
#endif #endif
#define MKSH_SYSTEM_PROFILE MKSH_DEFAULT_PROFILEDIR "/profile" #define MKSH_SYSTEM_PROFILE MKSH_DEFAULT_PROFILEDIR "/profile"
@ -1738,7 +1738,7 @@ struct ioword {
#define X_EXTRA 20 /* this many extra bytes in X string */ #define X_EXTRA 20 /* this many extra bytes in X string */
typedef struct XString { typedef struct XString {
/* begin of string */ /* beginning of string */
char *beg; char *beg;
/* length of allocated area, minus safety margin */ /* length of allocated area, minus safety margin */
size_t len; size_t len;
@ -1748,8 +1748,6 @@ typedef struct XString {
Area *areap; Area *areap;
} XString; } XString;
typedef char *XStringP;
/* initialise expandable string */ /* initialise expandable string */
#define XinitN(xs, length, area) do { \ #define XinitN(xs, length, area) do { \
(xs).len = (length); \ (xs).len = (length); \
@ -1781,7 +1779,7 @@ typedef char *XStringP;
/* close, return string */ /* close, return string */
#define Xclose(xs, xp) aresize((xs).beg, (xp) - (xs).beg, (xs).areap) #define Xclose(xs, xp) aresize((xs).beg, (xp) - (xs).beg, (xs).areap)
/* begin of string */ /* beginning of string */
#define Xstring(xs, xp) ((xs).beg) #define Xstring(xs, xp) ((xs).beg)
#define Xnleft(xs, xp) ((xs).end - (xp)) /* may be less than 0 */ #define Xnleft(xs, xp) ((xs).end - (xp)) /* may be less than 0 */
@ -1797,7 +1795,7 @@ char *Xcheck_grow(XString *, const char *, size_t);
*/ */
typedef struct { typedef struct {
/* begin of allocated area */ /* beginning of allocated area */
void **beg; void **beg;
/* currently used number of entries */ /* currently used number of entries */
size_t len; size_t len;
@ -1825,6 +1823,15 @@ typedef struct {
#define XPclose(x) aresize2((x).beg, XPsize(x), sizeof(void *), ATEMP) #define XPclose(x) aresize2((x).beg, XPsize(x), sizeof(void *), ATEMP)
#define XPfree(x) afree((x).beg, ATEMP) #define XPfree(x) afree((x).beg, ATEMP)
/* for print_columns */
struct columnise_opts {
struct shf *shf;
char linesep;
bool do_last;
bool prefcol;
};
/* /*
* Lexer internals * Lexer internals
*/ */
@ -2021,7 +2028,7 @@ void flushcom(bool);
int search_access(const char *, int); int search_access(const char *, int);
const char *search_path(const char *, const char *, int, int *); const char *search_path(const char *, const char *, int, int *);
void pr_menu(const char * const *); void pr_menu(const char * const *);
void pr_list(char * const *); void pr_list(struct columnise_opts *, char * const *);
int herein(struct ioword *, char **); int herein(struct ioword *, char **);
/* expr.c */ /* expr.c */
int evaluate(const char *, mksh_ari_t *, int, bool); int evaluate(const char *, mksh_ari_t *, int, bool);
@ -2122,8 +2129,8 @@ void runtrap(Trap *, bool);
void cleartraps(void); void cleartraps(void);
void restoresigs(void); void restoresigs(void);
void settrap(Trap *, const char *); void settrap(Trap *, const char *);
int block_pipe(void); bool block_pipe(void);
void restore_pipe(int); void restore_pipe(void);
int setsig(Trap *, sig_t, int); int setsig(Trap *, sig_t, int);
void setexecsig(Trap *, int); void setexecsig(Trap *, int);
#if HAVE_FLOCK || HAVE_LOCK_FCNTL #if HAVE_FLOCK || HAVE_LOCK_FCNTL
@ -2237,9 +2244,9 @@ void ksh_getopt_reset(Getopt *, int);
int ksh_getopt(const char **, Getopt *, const char *); int ksh_getopt(const char **, Getopt *, const char *);
void print_value_quoted(struct shf *, const char *); void print_value_quoted(struct shf *, const char *);
char *quote_value(const char *); char *quote_value(const char *);
void print_columns(struct shf *, unsigned int, void print_columns(struct columnise_opts *, unsigned int,
void (*)(char *, size_t, unsigned int, const void *), void (*)(char *, size_t, unsigned int, const void *),
const void *, size_t, size_t, bool); const void *, size_t, size_t);
void strip_nuls(char *, size_t) void strip_nuls(char *, size_t)
MKSH_A_BOUNDED(__string__, 1, 2); MKSH_A_BOUNDED(__string__, 1, 2);
ssize_t blocking_read(int, char *, size_t) ssize_t blocking_read(int, char *, size_t)
@ -2420,13 +2427,26 @@ extern int tty_init_fd(void); /* initialise tty_fd, tty_devtty */
}) })
#define mksh_abspath(s) __extension__({ \ #define mksh_abspath(s) __extension__({ \
const char *mksh_abspath_s = (s); \ const char *mksh_abspath_s = (s); \
(mksh_abspath_s[0] == '/' || (ksh_isalphx(mksh_abspath_s[0]) && \ (mksh_cdirsep(mksh_abspath_s[0]) || \
(ksh_isalphx(mksh_abspath_s[0]) && \
mksh_abspath_s[1] == ':')); \ mksh_abspath_s[1] == ':')); \
}) })
#define mksh_cdirsep(c) __extension__({ \
char mksh_cdirsep_c = (c); \
(mksh_cdirsep_c == '/' || mksh_cdirsep_c == '\\'); \
})
/*
* I've seen mksh_sdirsep(s) and mksh_vdirsep(s) but need to think
* more about the OS/2 port (and, possibly, toy with it) before I
* can merge this upstream, but good job so far @komh, thanks!
*/
#else #else
#define binopen2(path,flags) open((path), (flags) | O_BINARY) #define binopen2(path,flags) open((path), (flags) | O_BINARY)
#define binopen3(path,flags,mode) open((path), (flags) | O_BINARY, (mode)) #define binopen3(path,flags,mode) open((path), (flags) | O_BINARY, (mode))
#define mksh_abspath(s) ((s)[0] == '/') #define mksh_abspath(s) ((s)[0] == '/')
#define mksh_cdirsep(c) ((c) == '/')
#define mksh_sdirsep(s) strchr((s), '/')
#define mksh_vdirsep(s) vstrchr((s), '/')
#endif #endif
/* be sure not to interfere with anyone else's idea about EXTERN */ /* be sure not to interfere with anyone else's idea about EXTERN */

31
src/signames.inc Normal file
View file

@ -0,0 +1,31 @@
{ "ABRT", 6 },
{ "FPE", 8 },
{ "ILL", 4 },
{ "INT", 2 },
{ "SEGV", 11 },
{ "TERM", 15 },
{ "ALRM", 14 },
{ "BUS", 7 },
{ "CHLD", 17 },
{ "CONT", 18 },
{ "HUP", 1 },
{ "KILL", 9 },
{ "PIPE", 13 },
{ "QUIT", 3 },
{ "STOP", 19 },
{ "TSTP", 20 },
{ "TTIN", 21 },
{ "TTOU", 22 },
{ "USR1", 10 },
{ "USR2", 12 },
{ "POLL", 29 },
{ "PROF", 27 },
{ "SYS", 31 },
{ "TRAP", 5 },
{ "URG", 23 },
{ "VTALRM", 26 },
{ "XCPU", 24 },
{ "XFSZ", 25 },
{ "WINCH", 28 },
{ "PWR", 30 },
{ "STKFLT", 16 },

View file

@ -23,7 +23,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.114 2016/08/04 20:32:14 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/syn.c,v 1.115 2016/09/01 12:59:12 tg Exp $");
struct nesting_state { struct nesting_state {
int start_token; /* token than began nesting (eg, FOR) */ int start_token; /* token than began nesting (eg, FOR) */
@ -287,12 +287,12 @@ get_command(int cf)
syniocf &= ~(KEYWORD|sALIAS); syniocf &= ~(KEYWORD|sALIAS);
t = newtp(TCOM); t = newtp(TCOM);
t->lineno = source->line; t->lineno = source->line;
goto get_command_begin; goto get_command_start;
while (/* CONSTCOND */ 1) { while (/* CONSTCOND */ 1) {
bool check_assign_cmd; bool check_assign_cmd;
if (XPsize(args) == 0) { if (XPsize(args) == 0) {
get_command_begin: get_command_start:
check_assign_cmd = true; check_assign_cmd = true;
cf = sALIAS | CMDASN; cf = sALIAS | CMDASN;
} else if (t->u.evalflags) } else if (t->u.evalflags)

View file

@ -28,7 +28,7 @@
#include <sys/sysctl.h> #include <sys/sysctl.h>
#endif #endif
__RCSID("$MirOS: src/bin/mksh/var.c,v 1.207 2016/08/01 21:38:07 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/var.c,v 1.209 2016/11/11 23:31:39 tg Exp $");
/*- /*-
* Variables * Variables
@ -133,7 +133,7 @@ initvar(void)
struct tbl *tp; struct tbl *tp;
ktinit(APERM, &specials, ktinit(APERM, &specials,
/* currently 15 specials: 75% of 32 = 2^5 */ /* currently 18 specials: 75% of 32 = 2^5 */
5); 5);
while (i < V_MAX - 1) { while (i < V_MAX - 1) {
tp = ktenter(&specials, initvar_names[i], tp = ktenter(&specials, initvar_names[i],
@ -1149,6 +1149,13 @@ makenv(void)
/* setstr can't fail here */ /* setstr can't fail here */
setstr(vp, val, KSH_RETURN_ERROR); setstr(vp, val, KSH_RETURN_ERROR);
} }
#ifdef __OS2__
/* these special variables are not exported */
if (!strcmp(vp->name, "BEGINLIBPATH") ||
!strcmp(vp->name, "ENDLIBPATH") ||
!strcmp(vp->name, "LIBPATHSTRICT"))
continue;
#endif
XPput(denv, vp->val.s); XPput(denv, vp->val.s);
} }
if (l->flags & BF_STOPENV) if (l->flags & BF_STOPENV)
@ -1274,6 +1281,13 @@ setspec(struct tbl *vp)
int st; int st;
switch ((st = special(vp->name))) { switch ((st = special(vp->name))) {
#ifdef __OS2__
case V_BEGINLIBPATH:
case V_ENDLIBPATH:
case V_LIBPATHSTRICT:
setextlibpath(vp->name, str_val(vp));
return;
#endif
#if HAVE_PERSISTENT_HISTORY #if HAVE_PERSISTENT_HISTORY
case V_HISTFILE: case V_HISTFILE:
sethistfile(str_val(vp)); sethistfile(str_val(vp));
@ -1396,6 +1410,13 @@ unsetspec(struct tbl *vp)
*/ */
switch (special(vp->name)) { switch (special(vp->name)) {
#ifdef __OS2__
case V_BEGINLIBPATH:
case V_ENDLIBPATH:
case V_LIBPATHSTRICT:
setextlibpath(vp->name, "");
return;
#endif
#if HAVE_PERSISTENT_HISTORY #if HAVE_PERSISTENT_HISTORY
case V_HISTFILE: case V_HISTFILE:
sethistfile(NULL); sethistfile(NULL);
@ -1686,10 +1707,8 @@ rndset(unsigned long v)
short r; short r;
} z; } z;
#ifdef DEBUG /* clear the allocated space, for valgrind and to avoid UB */
/* clear the allocated space, for valgrind */
memset(&z, 0, sizeof(z)); memset(&z, 0, sizeof(z));
#endif
h = lcg_state; h = lcg_state;
BAFHFinish_reg(h); BAFHFinish_reg(h);

View file

@ -19,7 +19,7 @@
*/ */
#if defined(VARSPEC_DEFNS) #if defined(VARSPEC_DEFNS)
__RCSID("$MirOS: src/bin/mksh/var_spec.h,v 1.9 2016/07/25 21:02:13 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/var_spec.h,v 1.10 2016/11/11 23:31:39 tg Exp $");
#define FN(name) /* nothing */ #define FN(name) /* nothing */
#elif defined(VARSPEC_ENUMS) #elif defined(VARSPEC_ENUMS)
#define FN(name) V_##name, #define FN(name) V_##name,
@ -40,13 +40,22 @@ F0(NONE)
/* 1 and up are special variables */ /* 1 and up are special variables */
FN(BASHPID) FN(BASHPID)
#ifdef __OS2__
FN(BEGINLIBPATH)
#endif
FN(COLUMNS) FN(COLUMNS)
#ifdef __OS2__
FN(ENDLIBPATH)
#endif
FN(EPOCHREALTIME) FN(EPOCHREALTIME)
#if HAVE_PERSISTENT_HISTORY #if HAVE_PERSISTENT_HISTORY
FN(HISTFILE) FN(HISTFILE)
#endif #endif
FN(HISTSIZE) FN(HISTSIZE)
FN(IFS) FN(IFS)
#ifdef __OS2__
FN(LIBPATHSTRICT)
#endif
FN(LINENO) FN(LINENO)
FN(LINES) FN(LINES)
FN(OPTIND) FN(OPTIND)