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_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=530
-DHAVE_PERSISTENT_HISTORY=0 -DMKSH_BUILD_R=541
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
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,
# 2011, 2012, 2013, 2014, 2015, 2016
@ -120,7 +120,7 @@ do_genopt() {
state=3
;;
1:@@)
# begin of data block
# start of data block
o_gen=$o_gen$nl"#endif"
o_gen=$o_gen$nl"#ifndef F0"
o_gen=$o_gen$nl"#define F0 FN"
@ -133,7 +133,7 @@ do_genopt() {
o_hdr=$o_hdr$nl$line
;;
0:@*|1:@*)
# begin of a definition block
# start of a definition block
sym=`echo "$line" | sed 's/^@//'`
if test $state = 0; then
o_gen=$o_gen$nl"#if defined($sym)"
@ -584,7 +584,7 @@ if test -d $tfn || test -d $tfn.exe; then
exit 1
fi
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="$SRCS lex.c main.c misc.c shf.c syn.c tree.c var.c"
@ -755,6 +755,24 @@ GNU/kFreeBSD)
Haiku)
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)
;;
Interix)
@ -833,12 +851,14 @@ OpenBSD)
OS/2)
HAVE_TERMIOS_H=0
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"
: "${CC=gcc}"
: "${SIZE=: size}"
add_cppflags -DMKSH_UNEMPLOYED
add_cppflags -DMKSH_NOPROSPECTOFWORK
add_cppflags -DMKSH_NO_LIMITS
;;
OSF1)
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}..."
#
# Begin of mirtoconf checks
# Start of mirtoconf checks
#
$e $bi$me: Scanning for functions... please ignore any errors.$ao
@ -1458,6 +1478,7 @@ gcc)
ac_flags $t_use $t_name "$t_cflags" \
"if gcc supports $t_cflags $t_ldflags" "$t_ldflags"
done
ac_flags 1 data_abi_align -malign-data=abi
i=1
;;
hpcc)
@ -1486,8 +1507,12 @@ msc)
ac_flags 1 wp64 "${ccpc}/Wp64" 'to enable 64-bit warnings'
;;
nwcc)
i=1
#broken# ac_flags 1 ssp -stackprotect
i=1
;;
pcc)
ac_flags 1 fstackprotectorall -fstack-protector-all
i=1
;;
sunpro)
phase=u
@ -2342,7 +2367,7 @@ addsrcs '!' HAVE_STRLCPY strlcpy.c
addsrcs USE_PRINTF_BUILTIN printf.c
test 1 = "$USE_PRINTF_BUILTIN" && add_cppflags -DMKSH_PRINTF_BUILTIN
test 1 = "$HAVE_CAN_VERB" && CFLAGS="$CFLAGS -verbose"
add_cppflags -DMKSH_BUILD_R=530
add_cppflags -DMKSH_BUILD_R=541
$e $bi$me: Finished configuration testing, now producing output.$ao
@ -2588,8 +2613,8 @@ esac
tcfn=$mkshexe
test $cm = combine || v "$CC $CFLAGS $LDFLAGS -o $tcfn $lobjs $LIBS $ccpr"
test -f $tcfn || exit 1
test 1 = $r || v "$NROFF -mdoc <'$srcdir/mksh.1' >$tfn.cat1" || \
rmf $tfn.cat1
test 1 = $r || v "$NROFF -mdoc <'$srcdir/lksh.1' >lksh.cat1" || rmf lksh.cat1
test 1 = $r || v "$NROFF -mdoc <'$srcdir/mksh.1' >mksh.cat1" || rmf mksh.cat1
test 0 = $eq && v $SIZE $tcfn
i=install
test -f /usr/ucb/$i && i=/usr/ucb/$i
@ -2603,12 +2628,14 @@ if test $legacy = 0; then
fi
$e
$e Installing the manual:
if test -f $tfn.cat1; then
$e "# $i -c -o root -g bin -m 444 $tfn.cat1" \
"/usr/share/man/cat1/$tfn.0"
if test -f mksh.cat1; then
$e "# $i -c -o root -g bin -m 444 lksh.cat1" \
"/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
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 Run the regression test suite: ./test.sh
$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 -*-
#-
# 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
expected-stdout:
@(#)MIRBSD KSH R53 2016/08/12
@(#)MIRBSD KSH R54 2016/11/11
description:
Check version of shell.
stdin:
@ -39,7 +39,7 @@ name: KSH_VERSION
category: shell:legacy-no
---
expected-stdout:
@(#)LEGACY KSH R53 2016/08/12
@(#)LEGACY KSH R54 2016/11/11
description:
Check version of legacy shell.
stdin:
@ -340,6 +340,62 @@ expected-stdout:
2
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
description:
Check precedence of ternary operator vs assignment
@ -4892,7 +4948,7 @@ name: integer-base-check-flat
description:
Check behaviour does not match POSuX (except if set -o posix),
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:
echo 1 "$("$__progname" -c 'echo :$((10))/$((010)),$((0x10)):')" .
echo 2 "$("$__progname" -o posix -c 'echo :$((10))/$((010)),$((0x10)):')" .
@ -7152,6 +7208,19 @@ stdin:
db_go
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
description:
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>"
x=${|
local y
echo "begin: x<$x> y<$y> z<$z> R<$REPLY>"
echo "start: x<$x> y<$y> z<$z> R<$REPLY>"
x=5
y=6
z=7
@ -11769,7 +11838,7 @@ stdin:
echo ${|true;}$(true).
expected-stdout:
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>
after: x<8> y<2> z<7> R<4>
typeset t=$'foo\n\n'

View file

@ -28,7 +28,7 @@
#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
@ -238,6 +238,7 @@ x_print_expansions(int nwords, char * const *words, bool is_command)
bool use_copy = false;
size_t prefix_len;
XPtrV l = { NULL, 0, 0 };
struct columnise_opts co;
/*
* 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;
/* All in same directory? */
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--;
use_copy = true;
XPinit(l, nwords + 1);
@ -271,7 +273,11 @@ x_print_expansions(int nwords, char * const *words, bool is_command)
*/
x_putc('\r');
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)
/* 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";
* 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" */
*cp++ = 0;
/* try to expand the tilde */
@ -588,7 +594,7 @@ x_locate_word(const char *buf, int buflen, int pos, int *startp,
* like file globbing.
*/
for (p = start; p < end; p++)
if (buf[p] == '/')
if (mksh_cdirsep(buf[p]))
break;
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') */
*flagsp |= XCF_IS_NOSPACE;
goto dont_add_glob;
@ -741,13 +747,15 @@ x_basename(const char *s, const char *se)
if (s == se)
return (0);
/* Skip trailing slashes */
for (p = se - 1; p > s && *p == '/'; p--)
;
for (; p > s && *p != '/'; p--)
;
if (*p == '/' && p + 1 < se)
p++;
/* skip trailing directory separators */
p = se - 1;
while (p > s && mksh_cdirsep(*p))
--p;
/* drop last component */
while (p > s && !mksh_cdirsep(*p))
--p;
if (mksh_cdirsep(*p) && p + 1 < se)
++p;
return (p - s);
}
@ -1048,7 +1056,7 @@ static struct x_defbindings const x_defbindings[] = {
{ XFUNC_end_hist, 1, '>' },
{ XFUNC_goto_hist, 1, 'g' },
{ 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_cls, 1, CTRL('L') },
{ XFUNC_meta1, 0, CTRL('[') },
@ -1106,8 +1114,8 @@ static struct x_defbindings const x_defbindings[] = {
{ XFUNC_mv_back, 2, 'D' },
#ifndef MKSH_SMALL
{ XFUNC_vt_hack, 2, '1' },
{ XFUNC_mv_begin | 0x80, 2, '7' },
{ XFUNC_mv_begin, 2, 'H' },
{ XFUNC_mv_beg | 0x80, 2, '7' },
{ XFUNC_mv_beg, 2, 'H' },
{ XFUNC_mv_end | 0x80, 2, '4' },
{ XFUNC_mv_end | 0x80, 2, '8' },
{ XFUNC_mv_end, 2, 'F' },
@ -1119,7 +1127,7 @@ static struct x_defbindings const x_defbindings[] = {
/* PC scancodes */
#if !defined(MKSH_SMALL) || defined(__OS2__)
{ XFUNC_meta3, 0, 0 },
{ XFUNC_mv_begin, 3, 71 },
{ XFUNC_mv_beg, 3, 71 },
{ XFUNC_prev_com, 3, 72 },
#ifndef MKSH_SMALL
{ XFUNC_search_hist_up, 3, 73 },
@ -2044,7 +2052,7 @@ x_mv_end(int c MKSH_A_UNUSED)
}
static int
x_mv_begin(int c MKSH_A_UNUSED)
x_mv_beg(int c MKSH_A_UNUSED)
{
x_goto(xbuf);
return (KSTD);
@ -2328,7 +2336,7 @@ x_vt_hack(int c)
case '~':
x_arg = 1;
x_arg_defaulted = true;
return (x_mv_begin(0));
return (x_mv_beg(0));
case ';':
/* "interesting" sequence detected */
break;
@ -2778,7 +2786,7 @@ do_complete(
* append a space if this is a single non-directory match
* 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)) {
x_ins(T1space);
}
@ -4016,7 +4024,7 @@ vi_insert(int ch)
else
return (redo_insert(lastac - 1));
/* { Begin nonstandard vi commands */
/* { start nonstandard vi commands */
case CTRL('x'):
expand_word(0);
break;
@ -4035,7 +4043,7 @@ vi_insert(int ch)
break;
}
/* FALLTHROUGH */
/* End nonstandard vi commands } */
/* end nonstandard vi commands } */
default:
if (es->linelen >= es->cbufsize - 1)
@ -4157,6 +4165,8 @@ vi_cmd(int argcnt, const char *cmd)
case 'Y':
cmd = "y$";
/* ahhhhhh... */
/* FALLTHROUGH */
case 'c':
case 'd':
case 'y':
@ -4393,6 +4403,8 @@ vi_cmd(int argcnt, const char *cmd)
if (hnum == hlast)
hnum = -1;
/* ahhh */
/* FALLTHROUGH */
case '/':
c3 = 1;
srchlen = 0;
@ -4531,6 +4543,7 @@ vi_cmd(int argcnt, const char *cmd)
case CTRL('['):
if (!Flag(FVIESCCOMPLETE))
return (-1);
/* FALLTHROUGH */
/* AT&T ksh */
case '\\':
/* Nonstandard vi/ksh */
@ -4603,8 +4616,7 @@ domove(int argcnt, const char *cmd, int sub)
case 'T':
fsavecmd = *cmd;
fsavech = cmd[1];
/* drop through */
/* FALLTHROUGH */
case ',':
case ';':
if (fsavecmd == ' ')
@ -5399,7 +5411,7 @@ complete_word(int cmd, int count)
* append a space if this is a non-directory match
* 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))
rval = putbuf(T1space, 1, false);
}

View file

@ -19,7 +19,7 @@
*/
#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);
#elif defined(EMACSFN_ENUMS)
#define FN(cname,sname,flags) XFUNC_##cname,
@ -78,7 +78,7 @@ FN(meta2, "prefix-2", XF_PREFIX)
FN(meta3, "prefix-3", XF_PREFIX)
FN(meta_yank, "yank-pop", 0)
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_end, "end-of-line", 0)
FN(mv_forw, "forward-char", XF_ARG)

View file

@ -23,7 +23,7 @@
#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
@ -62,7 +62,7 @@ typedef struct {
#define IFS_WORD 0 /* word has chars (or quotes except "$@") */
#define IFS_WS 1 /* have seen IFS 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 "$@" */
static int varsub(Expand *, const char *, const char *, int *, int *);
@ -198,7 +198,7 @@ typedef struct SubType {
struct tbl *var; /* variable for ${var..} */
struct SubType *prev; /* old type */
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 f; /* saved value of f (DOPAT, etc) */
uint8_t quotep; /* saved value of quote (for ${..[%#]..}) */
@ -1576,7 +1576,7 @@ globit(XString *xs, /* dest string */
* SunOS 4.1.3 does this...
*/
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) ||
stat_check() < 0 || !S_ISDIR(statb.st_mode)))
return;
@ -1586,7 +1586,7 @@ globit(XString *xs, /* dest string */
* directory
*/
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_ISLNK(lstatb.st_mode) && stat_check() > 0 &&
S_ISDIR(statb.st_mode)))) {
@ -1601,11 +1601,11 @@ globit(XString *xs, /* dest string */
if (xp > Xstring(*xs, xp))
*xp++ = '/';
while (*sp == '/') {
while (mksh_cdirsep(*sp)) {
Xcheck(*xs, xp);
*xp++ = *sp++;
}
np = strchr(sp, '/');
np = mksh_sdirsep(sp);
if (np != NULL) {
se = np;
/* 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);
/* : 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);
*tp++ = p[1];
p += 2;

View file

@ -23,7 +23,7 @@
#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
#define MKSH_DEFAULT_EXECSHELL MKSH_UNIXROOT "/bin/sh"
@ -282,7 +282,7 @@ execute(struct op * volatile t,
case TOR:
case TAND:
rv = execute(t->left, XERROK, xerrok);
rv = execute(t->left, XERROK, NULL);
if ((rv == 0) == (t->type == TAND))
rv = execute(t->right, flags & XERROK, xerrok);
else {
@ -339,16 +339,14 @@ execute(struct op * volatile t,
rv = execute(t->left, flags & XERROK, xerrok);
}
} else {
/* TSELECT */
for (;;) {
if (!(ccp = do_selectargs(ap, is_first))) {
rv = 1;
break;
}
do_TSELECT:
if ((ccp = do_selectargs(ap, is_first))) {
is_first = false;
setstr(global(t->str), ccp, KSH_UNWIND_ERROR);
execute(t->left, flags & XERROK, xerrok);
goto do_TSELECT;
}
rv = 1;
}
break;
}
@ -674,7 +672,7 @@ comexec(struct op *t, struct tbl * volatile tp, const char **ap,
rv = subst_exstat;
goto Leave;
} else if (!tp) {
if (Flag(FRESTRICTED) && vstrchr(cp, '/')) {
if (Flag(FRESTRICTED) && mksh_vdirsep(cp)) {
warningf(true, Tf_sD_s, cp, "restricted");
rv = 1;
goto Leave;
@ -913,7 +911,7 @@ scriptexec(struct op *tp, const char **ap)
/* replace newline by NUL */
*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;
/* bail out if no shebang magic found */
if (cp[0] == '#' && cp[1] == '!')
@ -1125,7 +1123,7 @@ findcom(const char *name, int flags)
char *fpath;
union mksh_cchack npath;
if (vstrchr(name, '/')) {
if (mksh_vdirsep(name)) {
insert = 0;
/* prevent FPATH search below */
flags &= ~FC_FUNC;
@ -1242,8 +1240,12 @@ search_access(const char *fn, int mode)
eno = errno;
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) ||
!(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 */
return (S_ISDIR(sb.st_mode) ? EISDIR : EACCES);
return (0);
@ -1265,7 +1267,7 @@ search_path(const char *name, const char *lpath,
size_t namelen;
int ec = 0, ev;
if (vstrchr(name, '/')) {
if (mksh_vdirsep(name)) {
if ((ec = search_access(name, mode)) == 0) {
search_path_ok:
if (errnop)
@ -1658,6 +1660,7 @@ pr_menu(const char * const *ap)
const char * const *pp;
size_t acols = 0, aocts = 0, i;
unsigned int n;
struct columnise_opts co;
/*
* width/column calculations were done once and saved, but this
@ -1686,9 +1689,11 @@ pr_menu(const char * const *ap)
smi.num_width++;
smi.args = ap;
print_columns(shl_out, n, select_fmt_entry, (void *)&smi,
smi.num_width + 2 + aocts, smi.num_width + 2 + acols,
true);
co.shf = shl_out;
co.linesep = '\n';
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
@ -1698,7 +1703,7 @@ plain_fmt_entry(char *buf, size_t buflen, unsigned int i, const void *arg)
}
void
pr_list(char * const *ap)
pr_list(struct columnise_opts *cop, char * const *ap)
{
size_t acols = 0, aocts = 0, i;
unsigned int n;
@ -1713,8 +1718,8 @@ pr_list(char * const *ap)
acols = i;
}
print_columns(shl_out, n, plain_fmt_entry, (const void *)ap,
aocts, acols, false);
print_columns(cop, n, plain_fmt_entry, (const void *)ap,
aocts, acols);
}
/*

View file

@ -23,7 +23,7 @@
#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
#include "exprtok.h"
@ -326,7 +326,15 @@ evalexpr(Expr_state *es, unsigned int prec)
vl = evalexpr(es, prec - 1);
while ((int)(op = es->tok) >= (int)O_EQ && (int)op <= (int)O_COMMA &&
opprec[(int)op] == prec) {
exprtoken(es);
switch ((int)op) {
case O_TERN:
case O_LAND:
case O_LOR:
break;
default:
exprtoken(es);
}
vasn = vl;
if (op != O_ASN)
/* vl may not have a value yet */
@ -340,14 +348,15 @@ evalexpr(Expr_state *es, unsigned int prec)
if (!ev)
es->noassign++;
exprtoken(es);
vl = evalexpr(es, MAX_PREC);
if (!ev)
es->noassign--;
if (es->tok != CTERN)
evalerr(es, ET_STR, "missing :");
exprtoken(es);
if (ev)
es->noassign++;
exprtoken(es);
vr = evalexpr(es, P_TERN);
if (ev)
es->noassign--;
@ -502,6 +511,7 @@ evalexpr(Expr_state *es, unsigned int prec)
case O_LAND:
if (!t1)
es->noassign++;
exprtoken(es);
vr = intvar(es, evalexpr(es, prec - 1));
res = t1 && vr->val.u;
if (!t1)
@ -510,6 +520,7 @@ evalexpr(Expr_state *es, unsigned int prec)
case O_LOR:
if (t1)
es->noassign++;
exprtoken(es);
vr = intvar(es, evalexpr(es, prec - 1));
res = t1 || vr->val.u;
if (t1)
@ -857,7 +868,7 @@ ksh_access(const char *fn, int mode)
}
#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 {
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;
/*
* Generated by MirOS: contrib/code/Snippets/eawparse,v 1.2 2013/11/30 13:45:17 tg Exp $
* from the Unicode Character Database, Version 7.0.0
* Generated from the Unicode Character Database, Version 9.0.0, by
* MirOS: contrib/code/Snippets/eawparse,v 1.3 2014/11/16 12:16:24 tg Exp $
*/
static const struct mb_ucsrange mb_ucs_combining[] = {
@ -899,7 +910,7 @@ static const struct mb_ucsrange mb_ucs_combining[] = {
{ 0x0825, 0x0827 },
{ 0x0829, 0x082D },
{ 0x0859, 0x085B },
{ 0x08E4, 0x0902 },
{ 0x08D4, 0x0902 },
{ 0x093A, 0x093A },
{ 0x093C, 0x093C },
{ 0x0941, 0x0948 },
@ -994,6 +1005,7 @@ static const struct mb_ucsrange mb_ucs_combining[] = {
{ 0x17C9, 0x17D3 },
{ 0x17DD, 0x17DD },
{ 0x180B, 0x180E },
{ 0x1885, 0x1886 },
{ 0x18A9, 0x18A9 },
{ 0x1920, 0x1922 },
{ 0x1927, 0x1928 },
@ -1032,7 +1044,7 @@ static const struct mb_ucsrange mb_ucs_combining[] = {
{ 0x1CF4, 0x1CF4 },
{ 0x1CF8, 0x1CF9 },
{ 0x1DC0, 0x1DF5 },
{ 0x1DFC, 0x1DFF },
{ 0x1DFB, 0x1DFF },
{ 0x200B, 0x200F },
{ 0x202A, 0x202E },
{ 0x2060, 0x2064 },
@ -1045,13 +1057,13 @@ static const struct mb_ucsrange mb_ucs_combining[] = {
{ 0x3099, 0x309A },
{ 0xA66F, 0xA672 },
{ 0xA674, 0xA67D },
{ 0xA69F, 0xA69F },
{ 0xA69E, 0xA69F },
{ 0xA6F0, 0xA6F1 },
{ 0xA802, 0xA802 },
{ 0xA806, 0xA806 },
{ 0xA80B, 0xA80B },
{ 0xA825, 0xA826 },
{ 0xA8C4, 0xA8C4 },
{ 0xA8C4, 0xA8C5 },
{ 0xA8E0, 0xA8F1 },
{ 0xA926, 0xA92D },
{ 0xA947, 0xA951 },
@ -1078,14 +1090,47 @@ static const struct mb_ucsrange mb_ucs_combining[] = {
{ 0xABED, 0xABED },
{ 0xFB1E, 0xFB1E },
{ 0xFE00, 0xFE0F },
{ 0xFE20, 0xFE2D },
{ 0xFE20, 0xFE2F },
{ 0xFEFF, 0xFEFF },
{ 0xFFF9, 0xFFFB }
};
static const struct mb_ucsrange mb_ucs_fullwidth[] = {
{ 0x1100, 0x115F },
{ 0x231A, 0x231B },
{ 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 },
{ 0x3040, 0xA4CF },
{ 0xA960, 0xA97F },

View file

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

View file

@ -27,7 +27,7 @@
#include <sys/file.h>
#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];
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
* kill shell (unless user catches it and exits)
* called by c_print() when writing to a co-process to ensure
* SIGPIPE won't kill shell (unless user catches it and exits)
*/
int
bool
block_pipe(void)
{
int restore_dfl = 0;
bool restore_dfl = false;
Trap *p = &sigtraps[SIGPIPE];
if (!(p->flags & (TF_ORIG_IGN|TF_ORIG_DFL))) {
setsig(p, SIG_IGN, SS_RESTORE_CURR);
if (p->flags & TF_ORIG_DFL)
restore_dfl = 1;
restore_dfl = true;
} else if (p->cursig == SIG_DFL) {
setsig(p, SIG_IGN, SS_RESTORE_CURR);
/* restore to SIG_DFL */
restore_dfl = 1;
restore_dfl = true;
}
return (restore_dfl);
}
/* Called by c_print() to undo whatever block_pipe() did */
/* called by c_print() to undo whatever block_pipe() did */
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
.\" mirabilos <m@mirbsd.org>
@ -74,7 +74,7 @@
.\" with -mandoc, it might implement .Mx itself, but we want to
.\" 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.
.\"
@ -209,9 +209,9 @@ The
string identifies
.Nm
as
.Dq LEGACY KSH
.Dq Li LEGACY KSH
instead of
.Dq MIRBSD KSH .
.Dq Li MIRBSD KSH .
Note that the rest of the version string is identical between
the two shell flavours, and the behaviour and differences can
change between versions; see the accompanying manual page
@ -221,8 +221,8 @@ for the versions this document applies to.
.Nm
uses
.Tn POSIX
arithmetics, which has quite a few implications:
The data type for arithmetics is the host
arithmetic, which has quite a few implications:
The data type for arithmetic operations is the host
.Tn ISO
C
.Vt long

View file

@ -34,7 +34,7 @@
#include <locale.h>
#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;
@ -59,7 +59,12 @@ static void x_sigwinch(int);
static const char initifs[] = "IFS= \t\n";
static const char initsubs[] =
"${PS2=> } ${PS3=#? } ${PS4=+ } ${SECONDS=0} ${TMOUT=0} ${EPOCHREALTIME=}";
"${PS2=> }"
"${PS3=#? }"
"${PS4=+ }"
"${SECONDS=0}"
"${TMOUT=0}"
"${EPOCHREALTIME=}";
static const char *initcoms[] = {
Ttypeset, "-r", initvsn, NULL,
@ -111,10 +116,8 @@ rndsetup(void)
char *cp;
cp = alloc(sizeof(*bufptr) - sizeof(ALLOC_ITEM), APERM);
#ifdef DEBUG
/* clear the allocated space, for valgrind */
/* clear the allocated space, for valgrind and to avoid UB */
memset(cp, 0, sizeof(*bufptr) - sizeof(ALLOC_ITEM));
#endif
/* undo what alloc() did to the malloc result address */
bufptr = (void *)(cp - sizeof(ALLOC_ITEM));
/* 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 */
ccp = kshname;
goto begin_parse_kshname;
goto begin_parsing_kshname;
while ((i = ccp[argi++])) {
if (i == '/') {
if (mksh_cdirsep(i)) {
ccp += argi;
begin_parse_kshname:
begin_parsing_kshname:
argi = 0;
if (*ccp == '-')
++ccp;
@ -563,8 +566,8 @@ main_init(int argc, const char *argv[], Source **sp, struct block **lp)
#endif
if (!isuc(ccp))
ccp = null;
/* FALLTHROUGH */
#endif
/* FALLTHROUGH */
/* auto-detect from environment */
case 3:

View file

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

File diff suppressed because it is too large Load diff

View file

@ -175,9 +175,9 @@
#endif
#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
#define MKSH_VERSION "R53 2016/08/12"
#define MKSH_VERSION "R54 2016/11/11"
/* arithmetic types: C implementation */
#if !HAVE_CAN_INTTYPES
@ -578,7 +578,7 @@ char *ucstrstr(char *, const char *);
#define mkssert(e) do { } while (/* CONSTCOND */ 0)
#endif
#if (!defined(MKSH_BUILDMAKEFILE4BSD) && !defined(MKSH_BUILDSH)) || (MKSH_BUILD_R != 530)
#if (!defined(MKSH_BUILDMAKEFILE4BSD) && !defined(MKSH_BUILDSH)) || (MKSH_BUILD_R != 541)
#error Must run Build.sh to compile this.
extern void thiswillneverbedefinedIhope(void);
int
@ -1350,7 +1350,7 @@ EXTERN mksh_ari_t x_lins E_INIT(24);
/* Determine the location of the system (common) profile */
#ifndef MKSH_DEFAULT_PROFILEDIR
#define MKSH_DEFAULT_PROFILEDIR "/etc"
#define MKSH_DEFAULT_PROFILEDIR MKSH_UNIXROOT "/etc"
#endif
#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 */
typedef struct XString {
/* begin of string */
/* beginning of string */
char *beg;
/* length of allocated area, minus safety margin */
size_t len;
@ -1748,8 +1748,6 @@ typedef struct XString {
Area *areap;
} XString;
typedef char *XStringP;
/* initialise expandable string */
#define XinitN(xs, length, area) do { \
(xs).len = (length); \
@ -1781,7 +1779,7 @@ typedef char *XStringP;
/* close, return string */
#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 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 {
/* begin of allocated area */
/* beginning of allocated area */
void **beg;
/* currently used number of entries */
size_t len;
@ -1825,6 +1823,15 @@ typedef struct {
#define XPclose(x) aresize2((x).beg, XPsize(x), sizeof(void *), 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
*/
@ -2021,7 +2028,7 @@ void flushcom(bool);
int search_access(const char *, int);
const char *search_path(const char *, const char *, int, int *);
void pr_menu(const char * const *);
void pr_list(char * const *);
void pr_list(struct columnise_opts *, char * const *);
int herein(struct ioword *, char **);
/* expr.c */
int evaluate(const char *, mksh_ari_t *, int, bool);
@ -2122,8 +2129,8 @@ void runtrap(Trap *, bool);
void cleartraps(void);
void restoresigs(void);
void settrap(Trap *, const char *);
int block_pipe(void);
void restore_pipe(int);
bool block_pipe(void);
void restore_pipe(void);
int setsig(Trap *, sig_t, int);
void setexecsig(Trap *, int);
#if HAVE_FLOCK || HAVE_LOCK_FCNTL
@ -2237,9 +2244,9 @@ void ksh_getopt_reset(Getopt *, int);
int ksh_getopt(const char **, Getopt *, const char *);
void print_value_quoted(struct shf *, 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 *),
const void *, size_t, size_t, bool);
const void *, size_t, size_t);
void strip_nuls(char *, size_t)
MKSH_A_BOUNDED(__string__, 1, 2);
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__({ \
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] == ':')); \
})
#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
#define binopen2(path,flags) open((path), (flags) | O_BINARY)
#define binopen3(path,flags,mode) open((path), (flags) | O_BINARY, (mode))
#define mksh_abspath(s) ((s)[0] == '/')
#define mksh_cdirsep(c) ((c) == '/')
#define mksh_sdirsep(s) strchr((s), '/')
#define mksh_vdirsep(s) vstrchr((s), '/')
#endif
/* 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"
__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 {
int start_token; /* token than began nesting (eg, FOR) */
@ -287,12 +287,12 @@ get_command(int cf)
syniocf &= ~(KEYWORD|sALIAS);
t = newtp(TCOM);
t->lineno = source->line;
goto get_command_begin;
goto get_command_start;
while (/* CONSTCOND */ 1) {
bool check_assign_cmd;
if (XPsize(args) == 0) {
get_command_begin:
get_command_start:
check_assign_cmd = true;
cf = sALIAS | CMDASN;
} else if (t->u.evalflags)

View file

@ -28,7 +28,7 @@
#include <sys/sysctl.h>
#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
@ -133,7 +133,7 @@ initvar(void)
struct tbl *tp;
ktinit(APERM, &specials,
/* currently 15 specials: 75% of 32 = 2^5 */
/* currently 18 specials: 75% of 32 = 2^5 */
5);
while (i < V_MAX - 1) {
tp = ktenter(&specials, initvar_names[i],
@ -1149,6 +1149,13 @@ makenv(void)
/* setstr can't fail here */
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);
}
if (l->flags & BF_STOPENV)
@ -1274,6 +1281,13 @@ setspec(struct tbl *vp)
int st;
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
case V_HISTFILE:
sethistfile(str_val(vp));
@ -1396,6 +1410,13 @@ unsetspec(struct tbl *vp)
*/
switch (special(vp->name)) {
#ifdef __OS2__
case V_BEGINLIBPATH:
case V_ENDLIBPATH:
case V_LIBPATHSTRICT:
setextlibpath(vp->name, "");
return;
#endif
#if HAVE_PERSISTENT_HISTORY
case V_HISTFILE:
sethistfile(NULL);
@ -1686,10 +1707,8 @@ rndset(unsigned long v)
short r;
} z;
#ifdef DEBUG
/* clear the allocated space, for valgrind */
/* clear the allocated space, for valgrind and to avoid UB */
memset(&z, 0, sizeof(z));
#endif
h = lcg_state;
BAFHFinish_reg(h);

View file

@ -19,7 +19,7 @@
*/
#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 */
#elif defined(VARSPEC_ENUMS)
#define FN(name) V_##name,
@ -40,13 +40,22 @@ F0(NONE)
/* 1 and up are special variables */
FN(BASHPID)
#ifdef __OS2__
FN(BEGINLIBPATH)
#endif
FN(COLUMNS)
#ifdef __OS2__
FN(ENDLIBPATH)
#endif
FN(EPOCHREALTIME)
#if HAVE_PERSISTENT_HISTORY
FN(HISTFILE)
#endif
FN(HISTSIZE)
FN(IFS)
#ifdef __OS2__
FN(LIBPATHSTRICT)
#endif
FN(LINENO)
FN(LINES)
FN(OPTIND)