Upgrade to mksh 50e.
Change-Id: I341673d83c67f83761aa02c8372da6bbc419286f
This commit is contained in:
parent
948ca12d46
commit
50012061ca
22 changed files with 889 additions and 479 deletions
|
@ -45,7 +45,7 @@ LOCAL_CFLAGS += \
|
|||
-Wno-deprecated-declarations \
|
||||
-fno-asynchronous-unwind-tables \
|
||||
-fno-strict-aliasing \
|
||||
-fstack-protector -fwrapv \
|
||||
-fstack-protector-strong -fwrapv \
|
||||
|
||||
# ...and CPPFLAGS.
|
||||
LOCAL_CFLAGS += \
|
||||
|
@ -79,6 +79,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=504
|
||||
-DHAVE_PERSISTENT_HISTORY=0 -DMKSH_BUILD_R=505
|
||||
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
|
12
Makefrag.inc
12
Makefrag.inc
|
@ -1,4 +1,4 @@
|
|||
# Makefile fragment for building mksh R50 2014/10/03
|
||||
# Makefile fragment for building mksh R50 2015/03/01
|
||||
|
||||
PROG= mksh
|
||||
MAN= mksh.1
|
||||
|
@ -8,11 +8,11 @@ OBJS_BP= lalloc.o eval.o exec.o expr.o funcs.o histrap.o jobs.o lex.o main.o mi
|
|||
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-x86_64/prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.8/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 -fwrapv
|
||||
CPPFLAGS= -I. -I'../src' -isystem /huge-ssd/aosp-x86_64/bionic/libc/arch-x86/include -isystem /huge-ssd/aosp-x86_64/bionic/libc/include -isystem /huge-ssd/aosp-x86_64/bionic/libc/kernel/uapi -isystem /huge-ssd/aosp-x86_64/bionic/libc/kernel/uapi/asm-x86 -isystem /huge-ssd/aosp-x86_64/bionic/libm/include -isystem /huge-ssd/aosp-x86_64/bionic/libm/include/x86 -D_FORTIFY_SOURCE=2 -I/huge-ssd/aosp-x86_64/build/core/combo/include/arch/linux-x86/ -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_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=503
|
||||
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-x86_64/out/target/product/generic_x86_64/obj/lib/crtbegin_dynamic.o
|
||||
LIBS= -L/huge-ssd/aosp-x86_64/out/target/product/generic_x86_64/obj/lib -Wl,-rpath-link=/huge-ssd/aosp-x86_64/out/target/product/generic_x86_64/obj/lib -Wl,--no-whole-archive /huge-ssd/aosp-x86_64/out/target/product/generic_x86_64/obj/STATIC_LIBRARIES/libcompiler_rt-extras_intermediates/libcompiler_rt-extras.a -lc /huge-ssd/aosp-x86_64/out/target/product/generic_x86_64/obj/lib/crtend_android.o
|
||||
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_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=505
|
||||
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
|
||||
|
|
4
mkshrc
4
mkshrc
|
@ -31,7 +31,7 @@ function hd {
|
|||
local dasc line i
|
||||
|
||||
cat "$@" | { set +U; if read -arN -1 line; then
|
||||
typeset -i1 line
|
||||
typeset -i1 'line[*]'
|
||||
i=0
|
||||
while (( i < ${#line[*]} )); do
|
||||
hv=${line[i++]}
|
||||
|
@ -60,7 +60,7 @@ function setenv {
|
|||
eval export "\"$1\""'="$2"'
|
||||
}
|
||||
|
||||
for p in ~/.bin; do
|
||||
for p in ~/bin; do
|
||||
[[ -d $p/. ]] || continue
|
||||
[[ :$PATH: = *:$p:* ]] || PATH=$p:$PATH
|
||||
done
|
||||
|
|
56
src/Build.sh
56
src/Build.sh
|
@ -1,5 +1,5 @@
|
|||
#!/bin/sh
|
||||
srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.669 2014/10/07 15:22:12 tg Exp $'
|
||||
srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.669.2.2 2015/03/01 15:42:50 tg Exp $'
|
||||
#-
|
||||
# Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||
# 2011, 2012, 2013, 2014
|
||||
|
@ -1700,22 +1700,22 @@ rmf lft* # end of large file support test
|
|||
ac_test can_inttypes '!' stdint_h 1 "for standard 32-bit integer types" <<-'EOF'
|
||||
#include <sys/types.h>
|
||||
#include <stddef.h>
|
||||
int main(int ac, char **av) { return ((uint32_t)(ptrdiff_t)*av + (int32_t)ac); }
|
||||
int main(int ac, char **av) { return ((uint32_t)(size_t)*av + (int32_t)ac); }
|
||||
EOF
|
||||
ac_test can_ucbints '!' can_inttypes 1 "for UCB 32-bit integer types" <<-'EOF'
|
||||
#include <sys/types.h>
|
||||
#include <stddef.h>
|
||||
int main(int ac, char **av) { return ((u_int32_t)(ptrdiff_t)*av + (int32_t)ac); }
|
||||
int main(int ac, char **av) { return ((u_int32_t)(size_t)*av + (int32_t)ac); }
|
||||
EOF
|
||||
ac_test can_int8type '!' stdint_h 1 "for standard 8-bit integer type" <<-'EOF'
|
||||
#include <sys/types.h>
|
||||
#include <stddef.h>
|
||||
int main(int ac, char **av) { return ((uint8_t)(ptrdiff_t)av[ac]); }
|
||||
int main(int ac, char **av) { return ((uint8_t)(size_t)av[ac]); }
|
||||
EOF
|
||||
ac_test can_ucbint8 '!' can_int8type 1 "for UCB 8-bit integer type" <<-'EOF'
|
||||
#include <sys/types.h>
|
||||
#include <stddef.h>
|
||||
int main(int ac, char **av) { return ((u_int8_t)(ptrdiff_t)av[ac]); }
|
||||
int main(int ac, char **av) { return ((u_int8_t)(size_t)av[ac]); }
|
||||
EOF
|
||||
|
||||
ac_test rlim_t <<-'EOF'
|
||||
|
@ -1784,7 +1784,7 @@ else
|
|||
#define EXTERN
|
||||
#define MKSH_INCLUDES_ONLY
|
||||
#include "sh.h"
|
||||
__RCSID("$MirOS: src/bin/mksh/Build.sh,v 1.669 2014/10/07 15:22:12 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/Build.sh,v 1.669.2.2 2015/03/01 15:42:50 tg Exp $");
|
||||
int main(void) { printf("Hello, World!\n"); return (isatty(0)); }
|
||||
EOF
|
||||
case $cm in
|
||||
|
@ -1969,13 +1969,13 @@ EOF
|
|||
ac_test setlocale_ctype '' 'setlocale(LC_CTYPE, "")' <<-'EOF'
|
||||
#include <locale.h>
|
||||
#include <stddef.h>
|
||||
int main(void) { return ((int)(ptrdiff_t)(void *)setlocale(LC_CTYPE, "")); }
|
||||
int main(void) { return ((int)(size_t)(void *)setlocale(LC_CTYPE, "")); }
|
||||
EOF
|
||||
|
||||
ac_test langinfo_codeset setlocale_ctype 0 'nl_langinfo(CODESET)' <<-'EOF'
|
||||
#include <langinfo.h>
|
||||
#include <stddef.h>
|
||||
int main(void) { return ((int)(ptrdiff_t)(void *)nl_langinfo(CODESET)); }
|
||||
int main(void) { return ((int)(size_t)(void *)nl_langinfo(CODESET)); }
|
||||
EOF
|
||||
|
||||
ac_test select <<-'EOF'
|
||||
|
@ -2150,9 +2150,9 @@ cta(uari_has_32_bit, 0 < (mksh_uari_t)(((((mksh_uari_t)1 << 15) << 15) - 1) * 4
|
|||
cta(uari_wrap_32_bit,
|
||||
(mksh_uari_t)(((((mksh_uari_t)1 << 15) << 15) - 1) * 4 + 3) >
|
||||
(mksh_uari_t)(((((mksh_uari_t)1 << 15) << 15) - 1) * 4 + 4));
|
||||
#define NUM 22
|
||||
#define NUM 21
|
||||
#else
|
||||
#define NUM 16
|
||||
#define NUM 15
|
||||
#endif
|
||||
/* these are always required */
|
||||
cta(ari_is_signed, (mksh_ari_t)-1 < (mksh_ari_t)0);
|
||||
|
@ -2161,11 +2161,10 @@ cta(uari_is_unsigned, (mksh_uari_t)-1 > (mksh_uari_t)0);
|
|||
cta(ari_size_no_matter_of_signedness, sizeof(mksh_ari_t) == sizeof(mksh_uari_t));
|
||||
|
||||
cta(sizet_size_no_matter_of_signedness, sizeof(ssize_t) == sizeof(size_t));
|
||||
cta(ptrdifft_sizet_same_size, sizeof(ptrdiff_t) == sizeof(size_t));
|
||||
cta(ptrdifft_voidptr_same_size, sizeof(ptrdiff_t) == sizeof(void *));
|
||||
cta(ptrdifft_funcptr_same_size, sizeof(ptrdiff_t) == sizeof(void (*)(void)));
|
||||
cta(sizet_voidptr_same_size, sizeof(size_t) == sizeof(void *));
|
||||
cta(sizet_funcptr_same_size, sizeof(size_t) == sizeof(void (*)(void)));
|
||||
/* our formatting routines assume this */
|
||||
cta(ptr_fits_in_long, sizeof(ptrdiff_t) <= sizeof(long));
|
||||
cta(ptr_fits_in_long, sizeof(size_t) <= sizeof(long));
|
||||
/* for struct alignment people */
|
||||
char padding[64 - NUM];
|
||||
};
|
||||
|
@ -2264,6 +2263,11 @@ mksh_cfg= NSIG
|
|||
;' >conftest.c
|
||||
# GNU sed 2.03 segfaults when optimising this to sed -n
|
||||
NSIG=`vq "$CPP $CFLAGS $CPPFLAGS $NOWARN conftest.c" | \
|
||||
grep -v '^#' | \
|
||||
sed '/mksh_cfg.*= *$/{
|
||||
N
|
||||
s/\n/ /
|
||||
}' | \
|
||||
grep '^ *mksh_cfg *=' | \
|
||||
sed 's/^ *mksh_cfg *=[ ]*\([()0-9x+-][()0-9x+ -]*\).*$/\1/'`
|
||||
case $NSIG in
|
||||
|
@ -2295,6 +2299,11 @@ mksh_cfg= NSIG
|
|||
echo ';' >>conftest.c
|
||||
# GNU sed 2.03 croaks on optimising this, too
|
||||
vq "$CPP $CFLAGS $CPPFLAGS $NOWARN conftest.c" | \
|
||||
grep -v '^#' | \
|
||||
sed '/mksh_cfg.*= *$/{
|
||||
N
|
||||
s/\n/ /
|
||||
}' | \
|
||||
grep '^ *mksh_cfg *=' | \
|
||||
sed 's/^ *mksh_cfg *=[ ]*\([0-9][0-9x]*\).*$/:\1 '$name/
|
||||
done | sed -n '/^:[^ ]/s/^://p' | while read nr name; do
|
||||
|
@ -2316,7 +2325,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=504
|
||||
add_cppflags -DMKSH_BUILD_R=505
|
||||
|
||||
$e $bi$me: Finished configuration testing, now producing output.$ao
|
||||
|
||||
|
@ -2431,9 +2440,12 @@ llvm)
|
|||
;;
|
||||
esac
|
||||
echo ": # work around NeXTstep bug" >Rebuild.sh
|
||||
for file in "$srcdir"/*.opt; do
|
||||
cd "$srcdir"
|
||||
optfiles=`echo *.opt`
|
||||
cd "$curdir"
|
||||
for file in $optfiles; do
|
||||
echo "echo + Running genopt on '$file'..."
|
||||
echo "(srcfile='$file'; BUILDSH_RUN_GENOPT=1; . '$srcdir/Build.sh')"
|
||||
echo "(srcfile='$srcdir/$file'; BUILDSH_RUN_GENOPT=1; . '$srcdir/Build.sh')"
|
||||
done >>Rebuild.sh
|
||||
echo set -x >>Rebuild.sh
|
||||
for file in $SRCS; do
|
||||
|
@ -2467,11 +2479,11 @@ if test $cm = makefile; then
|
|||
extras='emacsfn.h rlimits.opt sh.h sh_flags.opt var_spec.h'
|
||||
test 0 = $HAVE_SYS_SIGNAME && extras="$extras signames.inc"
|
||||
gens= genq=
|
||||
for file in "$srcdir"/*.opt; do
|
||||
for file in $optfiles; do
|
||||
genf=`basename "$file" | sed 's/.opt$/.gen/'`
|
||||
gens="$gens $genf"
|
||||
genq="$genq$nl$genf: $srcdir/Build.sh $file
|
||||
srcfile=$file; BUILDSH_RUN_GENOPT=1; . $srcdir/Build.sh"
|
||||
genq="$genq$nl$genf: $srcdir/Build.sh $srcdir/$file
|
||||
srcfile=$srcdir/$file; BUILDSH_RUN_GENOPT=1; . $srcdir/Build.sh"
|
||||
done
|
||||
cat >Makefrag.inc <<EOF
|
||||
# Makefile fragment for building mksh $dstversion
|
||||
|
@ -2515,9 +2527,9 @@ EOF
|
|||
$e Generated Makefrag.inc successfully.
|
||||
exit 0
|
||||
fi
|
||||
for file in "$srcdir"/*.opt; do
|
||||
for file in $optfiles; do
|
||||
$e "+ Running genopt on '$file'..."
|
||||
do_genopt "$file" || exit 1
|
||||
do_genopt "$srcdir/$file" || exit 1
|
||||
done
|
||||
if test $cm = combine; then
|
||||
objs="-o $mkshexe"
|
||||
|
|
537
src/check.t
537
src/check.t
|
@ -1,8 +1,8 @@
|
|||
# $MirOS: src/bin/mksh/check.t,v 1.661 2014/10/07 15:22:14 tg Exp $
|
||||
# OpenBSD src/regress/bin/ksh updated: 2013/12/02 20:39:44
|
||||
# $MirOS: src/bin/mksh/check.t,v 1.667.2.3 2015/03/01 15:42:51 tg Exp $
|
||||
# -*- mode: sh -*-
|
||||
#-
|
||||
# Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||
# 2011, 2012, 2013, 2014
|
||||
# 2011, 2012, 2013, 2014, 2015
|
||||
# Thorsten Glaser <tg@mirbsd.org>
|
||||
#
|
||||
# Provided that these terms and disclaimer and all copyright notices
|
||||
|
@ -24,10 +24,13 @@
|
|||
# http://www.research.att.com/~gsf/public/ifs.sh
|
||||
#
|
||||
# More testsuites at:
|
||||
# http://www.freebsd.org/cgi/cvsweb.cgi/src/tools/regression/bin/test/regress.sh?rev=HEAD
|
||||
# http://svnweb.freebsd.org/base/head/bin/test/tests/legacy_test.sh?view=co&content-type=text%2Fplain
|
||||
#
|
||||
# Integrated testsuites from:
|
||||
# (2013/12/02 20:39:44) http://openbsd.cs.toronto.edu/cgi-bin/cvsweb/src/regress/bin/ksh/?sortby=date
|
||||
|
||||
expected-stdout:
|
||||
@(#)MIRBSD KSH R50 2014/10/07
|
||||
@(#)MIRBSD KSH R50 2015/03/01
|
||||
description:
|
||||
Check version of shell.
|
||||
stdin:
|
||||
|
@ -36,7 +39,7 @@ name: KSH_VERSION
|
|||
category: shell:legacy-no
|
||||
---
|
||||
expected-stdout:
|
||||
@(#)LEGACY KSH R50 2014/10/07
|
||||
@(#)LEGACY KSH R50 2015/03/01
|
||||
description:
|
||||
Check version of legacy shell.
|
||||
stdin:
|
||||
|
@ -2359,6 +2362,14 @@ stdin:
|
|||
expected-stdout:
|
||||
baz
|
||||
---
|
||||
name: heredoc-9f
|
||||
description:
|
||||
Check long here strings
|
||||
stdin:
|
||||
cat <<< "$( : )aa"
|
||||
expected-stdout:
|
||||
aa
|
||||
---
|
||||
name: heredoc-10
|
||||
description:
|
||||
Check direct here document assignment
|
||||
|
@ -2389,6 +2400,14 @@ stdin:
|
|||
vf=<<<$'=f $x \x40='
|
||||
# now check
|
||||
print -r -- "| va={$va} vb={$vb} vc={$vc} vd={$vd} ve={$ve} vf={$vf} |"
|
||||
# check append
|
||||
v=<<-EOF
|
||||
vapp1
|
||||
EOF
|
||||
v+=<<-EOF
|
||||
vapp2
|
||||
EOF
|
||||
print -r -- "| ${v//$'\n'/^} |"
|
||||
expected-stdout:
|
||||
function foo {
|
||||
vc=<<-EOF
|
||||
|
@ -2404,6 +2423,7 @@ expected-stdout:
|
|||
} ve={=e $x \x40=
|
||||
} vf={=f $x @=
|
||||
} |
|
||||
| vapp1^vapp2^ |
|
||||
---
|
||||
name: heredoc-11
|
||||
description:
|
||||
|
@ -2433,6 +2453,14 @@ stdin:
|
|||
eval "$fnd"
|
||||
foo
|
||||
print -r -- "| va={$va} vb={$vb} vc={$vc} vd={$vd} |"
|
||||
# check append
|
||||
v=<<-
|
||||
vapp1
|
||||
<<
|
||||
v+=<<-''
|
||||
vapp2
|
||||
|
||||
print -r -- "| ${v//$'\n'/^} |"
|
||||
expected-stdout:
|
||||
function foo {
|
||||
vc=<<-
|
||||
|
@ -2450,6 +2478,52 @@ expected-stdout:
|
|||
} vc={=c u \x40=
|
||||
} vd={=d $x \x40=
|
||||
} |
|
||||
| vapp1^vapp2^ |
|
||||
---
|
||||
name: heredoc-12
|
||||
description:
|
||||
Check here documents can use $* and $@; note shells vary:
|
||||
• pdksh 5.2.14 acts the same
|
||||
• dash has 1 and 2 the same but 3 lacks the space
|
||||
• ksh93, bash4 differ in 2 by using space ipv colon
|
||||
stdin:
|
||||
set -- a b
|
||||
nl='
|
||||
'
|
||||
IFS=" $nl"; n=1
|
||||
cat <<EOF
|
||||
$n foo $* foo
|
||||
$n bar "$*" bar
|
||||
$n baz $@ baz
|
||||
$n bla "$@" bla
|
||||
EOF
|
||||
IFS=":"; n=2
|
||||
cat <<EOF
|
||||
$n foo $* foo
|
||||
$n bar "$*" bar
|
||||
$n baz $@ baz
|
||||
$n bla "$@" bla
|
||||
EOF
|
||||
IFS=; n=3
|
||||
cat <<EOF
|
||||
$n foo $* foo
|
||||
$n bar "$*" bar
|
||||
$n baz $@ baz
|
||||
$n bla "$@" bla
|
||||
EOF
|
||||
expected-stdout:
|
||||
1 foo a b foo
|
||||
1 bar "a b" bar
|
||||
1 baz a b baz
|
||||
1 bla "a b" bla
|
||||
2 foo a:b foo
|
||||
2 bar "a:b" bar
|
||||
2 baz a:b baz
|
||||
2 bla "a:b" bla
|
||||
3 foo a b foo
|
||||
3 bar "a b" bar
|
||||
3 baz a b baz
|
||||
3 bla "a b" bla
|
||||
---
|
||||
name: heredoc-comsub-1
|
||||
description:
|
||||
|
@ -3585,23 +3659,23 @@ name: IFS-space-1
|
|||
description:
|
||||
Simple test, default IFS
|
||||
stdin:
|
||||
showargs() { for i; do echo -n " <$i>"; done; echo; }
|
||||
showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
|
||||
set -- A B C
|
||||
showargs 1 $*
|
||||
showargs 2 "$*"
|
||||
showargs 3 $@
|
||||
showargs 4 "$@"
|
||||
expected-stdout:
|
||||
<1> <A> <B> <C>
|
||||
<2> <A B C>
|
||||
<3> <A> <B> <C>
|
||||
<4> <A> <B> <C>
|
||||
<1> <A> <B> <C> .
|
||||
<2> <A B C> .
|
||||
<3> <A> <B> <C> .
|
||||
<4> <A> <B> <C> .
|
||||
---
|
||||
name: IFS-colon-1
|
||||
description:
|
||||
Simple test, IFS=:
|
||||
stdin:
|
||||
showargs() { for i; do echo -n " <$i>"; done; echo; }
|
||||
showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
|
||||
IFS=:
|
||||
set -- A B C
|
||||
showargs 1 $*
|
||||
|
@ -3609,16 +3683,16 @@ stdin:
|
|||
showargs 3 $@
|
||||
showargs 4 "$@"
|
||||
expected-stdout:
|
||||
<1> <A> <B> <C>
|
||||
<2> <A:B:C>
|
||||
<3> <A> <B> <C>
|
||||
<4> <A> <B> <C>
|
||||
<1> <A> <B> <C> .
|
||||
<2> <A:B:C> .
|
||||
<3> <A> <B> <C> .
|
||||
<4> <A> <B> <C> .
|
||||
---
|
||||
name: IFS-null-1
|
||||
description:
|
||||
Simple test, IFS=""
|
||||
stdin:
|
||||
showargs() { for i; do echo -n " <$i>"; done; echo; }
|
||||
showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
|
||||
IFS=""
|
||||
set -- A B C
|
||||
showargs 1 $*
|
||||
|
@ -3626,16 +3700,16 @@ stdin:
|
|||
showargs 3 $@
|
||||
showargs 4 "$@"
|
||||
expected-stdout:
|
||||
<1> <A> <B> <C>
|
||||
<2> <ABC>
|
||||
<3> <A> <B> <C>
|
||||
<4> <A> <B> <C>
|
||||
<1> <A> <B> <C> .
|
||||
<2> <ABC> .
|
||||
<3> <A> <B> <C> .
|
||||
<4> <A> <B> <C> .
|
||||
---
|
||||
name: IFS-space-colon-1
|
||||
description:
|
||||
Simple test, IFS=<white-space>:
|
||||
stdin:
|
||||
showargs() { for i; do echo -n " <$i>"; done; echo; }
|
||||
showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
|
||||
IFS="$IFS:"
|
||||
set --
|
||||
showargs 1 $*
|
||||
|
@ -3644,52 +3718,52 @@ stdin:
|
|||
showargs 4 "$@"
|
||||
showargs 5 : "$@"
|
||||
expected-stdout:
|
||||
<1>
|
||||
<2> <>
|
||||
<3>
|
||||
<4>
|
||||
<5> <:>
|
||||
<1> .
|
||||
<2> <> .
|
||||
<3> .
|
||||
<4> .
|
||||
<5> <:> .
|
||||
---
|
||||
name: IFS-space-colon-2
|
||||
description:
|
||||
Simple test, IFS=<white-space>:
|
||||
AT&T ksh fails this, POSIX says the test is correct.
|
||||
stdin:
|
||||
showargs() { for i; do echo -n " <$i>"; done; echo; }
|
||||
showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
|
||||
IFS="$IFS:"
|
||||
set --
|
||||
showargs :"$@"
|
||||
expected-stdout:
|
||||
<:>
|
||||
<:> .
|
||||
---
|
||||
name: IFS-space-colon-4
|
||||
description:
|
||||
Simple test, IFS=<white-space>:
|
||||
stdin:
|
||||
showargs() { for i; do echo -n " <$i>"; done; echo; }
|
||||
showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
|
||||
IFS="$IFS:"
|
||||
set --
|
||||
showargs "$@$@"
|
||||
expected-stdout:
|
||||
|
||||
.
|
||||
---
|
||||
name: IFS-space-colon-5
|
||||
description:
|
||||
Simple test, IFS=<white-space>:
|
||||
Don't know what POSIX thinks of this. AT&T ksh does not do this.
|
||||
stdin:
|
||||
showargs() { for i; do echo -n " <$i>"; done; echo; }
|
||||
showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
|
||||
IFS="$IFS:"
|
||||
set --
|
||||
showargs "${@:-}"
|
||||
expected-stdout:
|
||||
<>
|
||||
<> .
|
||||
---
|
||||
name: IFS-subst-1
|
||||
description:
|
||||
Simple test, IFS=<white-space>:
|
||||
stdin:
|
||||
showargs() { for i; do echo -n " <$i>"; done; echo; }
|
||||
showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
|
||||
IFS="$IFS:"
|
||||
x=":b: :"
|
||||
echo -n '1:'; for i in $x ; do echo -n " [$i]" ; done ; echo
|
||||
|
@ -3711,53 +3785,80 @@ stdin:
|
|||
expected-stdout:
|
||||
1: [] [b] []
|
||||
2: [:b::]
|
||||
<3> <> <b> <>
|
||||
<4> <:b::>
|
||||
<3> <> <b> <> .
|
||||
<4> <:b::> .
|
||||
5: [a] [b]
|
||||
<6> <a> <b>
|
||||
<6> <a> <b> .
|
||||
7: [a] [] [c]
|
||||
<8> <a> <> <c>
|
||||
<8> <a> <> <c> .
|
||||
9: [h] [ith] [ere]
|
||||
<10> <h> <ith> <ere>
|
||||
<11> <h:ith:ere>
|
||||
<10> <h> <ith> <ere> .
|
||||
<11> <h:ith:ere> .
|
||||
12: [A] [B] [] [D]
|
||||
<13> <A> <B> <> <D>
|
||||
<13> <A> <B> <> <D> .
|
||||
---
|
||||
name: IFS-subst-2
|
||||
description:
|
||||
Check leading whitespace after trim does not make a field
|
||||
stdin:
|
||||
showargs() { for i; do echo -n " <$i>"; done; echo; }
|
||||
showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
|
||||
x="X 1 2"
|
||||
showargs 1 shift ${x#X}
|
||||
expected-stdout:
|
||||
<1> <shift> <1> <2>
|
||||
<1> <shift> <1> <2> .
|
||||
---
|
||||
name: IFS-subst-3
|
||||
name: IFS-subst-3-arr
|
||||
description:
|
||||
Check leading IFS non-whitespace after trim does make a field
|
||||
but leading IFS whitespace does not, nor empty replacements
|
||||
stdin:
|
||||
showargs() { for i; do echo -n " <$i>"; done; echo; }
|
||||
showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
|
||||
showargs 0 ${-+}
|
||||
IFS=:
|
||||
showargs 1 ${-+:foo:bar}
|
||||
IFS=' '
|
||||
showargs 2 ${-+ foo bar}
|
||||
expected-stdout:
|
||||
<0>
|
||||
<1> <> <foo> <bar>
|
||||
<2> <foo> <bar>
|
||||
<0> .
|
||||
<1> <> <foo> <bar> .
|
||||
<2> <foo> <bar> .
|
||||
---
|
||||
name: IFS-subst-3-ass
|
||||
description:
|
||||
Check non-field semantics
|
||||
stdin:
|
||||
showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
|
||||
showargs 0 x=${-+}
|
||||
IFS=:
|
||||
showargs 1 x=${-+:foo:bar}
|
||||
IFS=' '
|
||||
showargs 2 x=${-+ foo bar}
|
||||
expected-stdout:
|
||||
<0> <x=> .
|
||||
<1> <x=> <foo> <bar> .
|
||||
<2> <x=> <foo> <bar> .
|
||||
---
|
||||
name: IFS-subst-3-lcl
|
||||
description:
|
||||
Check non-field semantics, smaller corner case (LP#1381965)
|
||||
stdin:
|
||||
set -x
|
||||
local regex=${2:-}
|
||||
exit 1
|
||||
expected-exit: e != 0
|
||||
expected-stderr-pattern:
|
||||
/regex=/
|
||||
---
|
||||
name: IFS-subst-4-1
|
||||
description:
|
||||
reported by mikeserv
|
||||
stdin:
|
||||
pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; }
|
||||
a='space divded argument
|
||||
here'
|
||||
IFS=\ ; set -- $a
|
||||
IFS= ; q="$*" ; nq=$*
|
||||
printf '<%s>\n' "$*" $* "$q" "$nq"
|
||||
pfn "$*" $* "$q" "$nq"
|
||||
[ "$q" = "$nq" ] && echo =true || echo =false
|
||||
expected-stdout:
|
||||
<spacedivdedargument
|
||||
|
@ -3776,11 +3877,12 @@ name: IFS-subst-4-2
|
|||
description:
|
||||
extended testsuite based on problem by mikeserv
|
||||
stdin:
|
||||
pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; }
|
||||
a='space divded argument
|
||||
here'
|
||||
IFS=\ ; set -- $a
|
||||
IFS= ; q="$@" ; nq=$@
|
||||
printf '<%s>\n' "$*" $* "$q" "$nq"
|
||||
pfn "$*" $* "$q" "$nq"
|
||||
[ "$q" = "$nq" ] && echo =true || echo =false
|
||||
expected-stdout:
|
||||
<spacedivdedargument
|
||||
|
@ -3799,6 +3901,7 @@ name: IFS-subst-4-3
|
|||
description:
|
||||
extended testsuite based on problem by mikeserv
|
||||
stdin:
|
||||
pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; }
|
||||
a='space divded argument
|
||||
here'
|
||||
IFS=\ ; set -- $a; IFS=
|
||||
|
@ -3806,14 +3909,14 @@ stdin:
|
|||
nqs=$*
|
||||
qk="$@"
|
||||
nqk=$@
|
||||
printf '= qs '; printf '<%s>\n' "$qs"
|
||||
printf '=nqs '; printf '<%s>\n' "$nqs"
|
||||
printf '= qk '; printf '<%s>\n' "$qk"
|
||||
printf '=nqk '; printf '<%s>\n' "$nqk"
|
||||
printf '~ qs '; printf '<%s>\n' "$*"
|
||||
printf '~nqs '; printf '<%s>\n' $*
|
||||
printf '~ qk '; printf '<%s>\n' "$@"
|
||||
printf '~nqk '; printf '<%s>\n' $@
|
||||
print -nr -- '= qs '; pfn "$qs"
|
||||
print -nr -- '=nqs '; pfn "$nqs"
|
||||
print -nr -- '= qk '; pfn "$qk"
|
||||
print -nr -- '=nqk '; pfn "$nqk"
|
||||
print -nr -- '~ qs '; pfn "$*"
|
||||
print -nr -- '~nqs '; pfn $*
|
||||
print -nr -- '~ qk '; pfn "$@"
|
||||
print -nr -- '~nqk '; pfn $@
|
||||
expected-stdout:
|
||||
= qs <spacedivdedargument
|
||||
here>
|
||||
|
@ -3842,21 +3945,22 @@ name: IFS-subst-4-4
|
|||
description:
|
||||
extended testsuite based on problem by mikeserv
|
||||
stdin:
|
||||
pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; }
|
||||
a='space divded argument
|
||||
here'
|
||||
IFS=\ ; set -- $a; IFS=
|
||||
qs="$*"
|
||||
printf '= qs '; printf '<%s>\n' "$qs"
|
||||
printf '~ qs '; printf '<%s>\n' "$*"
|
||||
print -nr -- '= qs '; pfn "$qs"
|
||||
print -nr -- '~ qs '; pfn "$*"
|
||||
nqs=$*
|
||||
printf '=nqs '; printf '<%s>\n' "$nqs"
|
||||
printf '~nqs '; printf '<%s>\n' $*
|
||||
print -nr -- '=nqs '; pfn "$nqs"
|
||||
print -nr -- '~nqs '; pfn $*
|
||||
qk="$@"
|
||||
printf '= qk '; printf '<%s>\n' "$qk"
|
||||
printf '~ qk '; printf '<%s>\n' "$@"
|
||||
print -nr -- '= qk '; pfn "$qk"
|
||||
print -nr -- '~ qk '; pfn "$@"
|
||||
nqk=$@
|
||||
printf '=nqk '; printf '<%s>\n' "$nqk"
|
||||
printf '~nqk '; printf '<%s>\n' $@
|
||||
print -nr -- '=nqk '; pfn "$nqk"
|
||||
print -nr -- '~nqk '; pfn $@
|
||||
expected-stdout:
|
||||
= qs <spacedivdedargument
|
||||
here>
|
||||
|
@ -3885,22 +3989,23 @@ name: IFS-subst-4-4p
|
|||
description:
|
||||
extended testsuite based on problem by mikeserv
|
||||
stdin:
|
||||
pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; }
|
||||
a='space divded argument
|
||||
here'
|
||||
IFS=\ ; set -- $a; IFS=
|
||||
unset v
|
||||
qs=${v:-"$*"}
|
||||
printf '= qs '; printf '<%s>\n' "$qs"
|
||||
printf '~ qs '; printf '<%s>\n' ${v:-"$*"}
|
||||
print -nr -- '= qs '; pfn "$qs"
|
||||
print -nr -- '~ qs '; pfn ${v:-"$*"}
|
||||
nqs=${v:-$*}
|
||||
printf '=nqs '; printf '<%s>\n' "$nqs"
|
||||
printf '~nqs '; printf '<%s>\n' ${v:-$*}
|
||||
print -nr -- '=nqs '; pfn "$nqs"
|
||||
print -nr -- '~nqs '; pfn ${v:-$*}
|
||||
qk=${v:-"$@"}
|
||||
printf '= qk '; printf '<%s>\n' "$qk"
|
||||
printf '~ qk '; printf '<%s>\n' ${v:-"$@"}
|
||||
print -nr -- '= qk '; pfn "$qk"
|
||||
print -nr -- '~ qk '; pfn ${v:-"$@"}
|
||||
nqk=${v:-$@}
|
||||
printf '=nqk '; printf '<%s>\n' "$nqk"
|
||||
printf '~nqk '; printf '<%s>\n' ${v:-$@}
|
||||
print -nr -- '=nqk '; pfn "$nqk"
|
||||
print -nr -- '~nqk '; pfn ${v:-$@}
|
||||
expected-stdout:
|
||||
= qs <spacedivdedargument
|
||||
here>
|
||||
|
@ -3929,21 +4034,22 @@ name: IFS-subst-4-5
|
|||
description:
|
||||
extended testsuite based on problem by mikeserv
|
||||
stdin:
|
||||
pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; }
|
||||
a='space divded argument
|
||||
here'
|
||||
IFS=\ ; set -- $a; IFS=,
|
||||
qs="$*"
|
||||
printf '= qs '; printf '<%s>\n' "$qs"
|
||||
printf '~ qs '; printf '<%s>\n' "$*"
|
||||
print -nr -- '= qs '; pfn "$qs"
|
||||
print -nr -- '~ qs '; pfn "$*"
|
||||
nqs=$*
|
||||
printf '=nqs '; printf '<%s>\n' "$nqs"
|
||||
printf '~nqs '; printf '<%s>\n' $*
|
||||
print -nr -- '=nqs '; pfn "$nqs"
|
||||
print -nr -- '~nqs '; pfn $*
|
||||
qk="$@"
|
||||
printf '= qk '; printf '<%s>\n' "$qk"
|
||||
printf '~ qk '; printf '<%s>\n' "$@"
|
||||
print -nr -- '= qk '; pfn "$qk"
|
||||
print -nr -- '~ qk '; pfn "$@"
|
||||
nqk=$@
|
||||
printf '=nqk '; printf '<%s>\n' "$nqk"
|
||||
printf '~nqk '; printf '<%s>\n' $@
|
||||
print -nr -- '=nqk '; pfn "$nqk"
|
||||
print -nr -- '~nqk '; pfn $@
|
||||
expected-stdout:
|
||||
= qs <space,divded,argument
|
||||
here>
|
||||
|
@ -3972,22 +4078,23 @@ name: IFS-subst-4-5p
|
|||
description:
|
||||
extended testsuite based on problem by mikeserv
|
||||
stdin:
|
||||
pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; }
|
||||
a='space divded argument
|
||||
here'
|
||||
IFS=\ ; set -- $a; IFS=,
|
||||
unset v
|
||||
qs=${v:-"$*"}
|
||||
printf '= qs '; printf '<%s>\n' "$qs"
|
||||
printf '~ qs '; printf '<%s>\n' ${v:-"$*"}
|
||||
print -nr -- '= qs '; pfn "$qs"
|
||||
print -nr -- '~ qs '; pfn ${v:-"$*"}
|
||||
nqs=${v:-$*}
|
||||
printf '=nqs '; printf '<%s>\n' "$nqs"
|
||||
printf '~nqs '; printf '<%s>\n' ${v:-$*}
|
||||
print -nr -- '=nqs '; pfn "$nqs"
|
||||
print -nr -- '~nqs '; pfn ${v:-$*}
|
||||
qk=${v:-"$@"}
|
||||
printf '= qk '; printf '<%s>\n' "$qk"
|
||||
printf '~ qk '; printf '<%s>\n' ${v:-"$@"}
|
||||
print -nr -- '= qk '; pfn "$qk"
|
||||
print -nr -- '~ qk '; pfn ${v:-"$@"}
|
||||
nqk=${v:-$@}
|
||||
printf '=nqk '; printf '<%s>\n' "$nqk"
|
||||
printf '~nqk '; printf '<%s>\n' ${v:-$@}
|
||||
print -nr -- '=nqk '; pfn "$nqk"
|
||||
print -nr -- '~nqk '; pfn ${v:-$@}
|
||||
expected-stdout:
|
||||
= qs <space,divded,argument
|
||||
here>
|
||||
|
@ -4026,38 +4133,55 @@ description:
|
|||
'emulate sh' zsh has extra fields in
|
||||
- a5ins (IFS_NWS unquoted $*)
|
||||
- b5ins, matching mksh’s
|
||||
!!WARNING!! more to come: http://austingroupbugs.net/view.php?id=888
|
||||
stdin:
|
||||
"$__progname" -c 'IFS=; set -- "" 2 ""; printf "[%s]\n" $*; x=$*; printf "<%s>\n" "$x"'
|
||||
"$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
|
||||
IFS=; set -- "" 2 ""; pfb $*; x=$*; pfn "$x"'
|
||||
echo '=a1zns'
|
||||
"$__progname" -c 'IFS=; set -- "" 2 ""; printf "[%s]\n" "$*"; x="$*"; printf "<%s>\n" "$x"'
|
||||
"$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
|
||||
IFS=; set -- "" 2 ""; pfb "$*"; x="$*"; pfn "$x"'
|
||||
echo '=a2zqs'
|
||||
"$__progname" -c 'IFS=; set -- "" 2 ""; printf "[%s]\n" $@; x=$@; printf "<%s>\n" "$x"'
|
||||
"$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
|
||||
IFS=; set -- "" 2 ""; pfb $@; x=$@; pfn "$x"'
|
||||
echo '=a3zna'
|
||||
"$__progname" -c 'IFS=; set -- "" 2 ""; printf "[%s]\n" "$@"; x="$@"; printf "<%s>\n" "$x"'
|
||||
"$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
|
||||
IFS=; set -- "" 2 ""; pfb "$@"; x="$@"; pfn "$x"'
|
||||
echo '=a4zqa'
|
||||
"$__progname" -c 'IFS=,; set -- "" 2 ""; printf "[%s]\n" $*; x=$*; printf "<%s>\n" "$x"'
|
||||
"$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
|
||||
IFS=,; set -- "" 2 ""; pfb $*; x=$*; pfn "$x"'
|
||||
echo '=a5ins'
|
||||
"$__progname" -c 'IFS=,; set -- "" 2 ""; printf "[%s]\n" "$*"; x="$*"; printf "<%s>\n" "$x"'
|
||||
"$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
|
||||
IFS=,; set -- "" 2 ""; pfb "$*"; x="$*"; pfn "$x"'
|
||||
echo '=a6iqs'
|
||||
"$__progname" -c 'IFS=,; set -- "" 2 ""; printf "[%s]\n" $@; x=$@; printf "<%s>\n" "$x"'
|
||||
"$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
|
||||
IFS=,; set -- "" 2 ""; pfb $@; x=$@; pfn "$x"'
|
||||
echo '=a7ina'
|
||||
"$__progname" -c 'IFS=,; set -- "" 2 ""; printf "[%s]\n" "$@"; x="$@"; printf "<%s>\n" "$x"'
|
||||
"$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
|
||||
IFS=,; set -- "" 2 ""; pfb "$@"; x="$@"; pfn "$x"'
|
||||
echo '=a8iqa'
|
||||
"$__progname" -c 'IFS=; set -- A B "" "" C; printf "[%s]\n" $*; x=$*; printf "<%s>\n" "$x"'
|
||||
"$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
|
||||
IFS=; set -- A B "" "" C; pfb $*; x=$*; pfn "$x"'
|
||||
echo '=b1zns'
|
||||
"$__progname" -c 'IFS=; set -- A B "" "" C; printf "[%s]\n" "$*"; x="$*"; printf "<%s>\n" "$x"'
|
||||
"$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
|
||||
IFS=; set -- A B "" "" C; pfb "$*"; x="$*"; pfn "$x"'
|
||||
echo '=b2zqs'
|
||||
"$__progname" -c 'IFS=; set -- A B "" "" C; printf "[%s]\n" $@; x=$@; printf "<%s>\n" "$x"'
|
||||
"$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
|
||||
IFS=; set -- A B "" "" C; pfb $@; x=$@; pfn "$x"'
|
||||
echo '=b3zna'
|
||||
"$__progname" -c 'IFS=; set -- A B "" "" C; printf "[%s]\n" "$@"; x="$@"; printf "<%s>\n" "$x"'
|
||||
"$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
|
||||
IFS=; set -- A B "" "" C; pfb "$@"; x="$@"; pfn "$x"'
|
||||
echo '=b4zqa'
|
||||
"$__progname" -c 'IFS=,; set -- A B "" "" C; printf "[%s]\n" $*; x=$*; printf "<%s>\n" "$x"'
|
||||
"$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
|
||||
IFS=,; set -- A B "" "" C; pfb $*; x=$*; pfn "$x"'
|
||||
echo '=b5ins'
|
||||
"$__progname" -c 'IFS=,; set -- A B "" "" C; printf "[%s]\n" "$*"; x="$*"; printf "<%s>\n" "$x"'
|
||||
"$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
|
||||
IFS=,; set -- A B "" "" C; pfb "$*"; x="$*"; pfn "$x"'
|
||||
echo '=b6iqs'
|
||||
"$__progname" -c 'IFS=,; set -- A B "" "" C; printf "[%s]\n" $@; x=$@; printf "<%s>\n" "$x"'
|
||||
"$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
|
||||
IFS=,; set -- A B "" "" C; pfb $@; x=$@; pfn "$x"'
|
||||
echo '=b7ina'
|
||||
"$__progname" -c 'IFS=,; set -- A B "" "" C; printf "[%s]\n" "$@"; x="$@"; printf "<%s>\n" "$x"'
|
||||
"$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
|
||||
IFS=,; set -- A B "" "" C; pfb "$@"; x="$@"; pfn "$x"'
|
||||
echo '=b8iqa'
|
||||
expected-stdout:
|
||||
[2]
|
||||
|
@ -4133,13 +4257,69 @@ expected-stdout:
|
|||
<A B C>
|
||||
=b8iqa
|
||||
---
|
||||
name: IFS-subst-6
|
||||
description:
|
||||
Regression wrt. vector expansion in trim
|
||||
stdin:
|
||||
showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
|
||||
IFS=
|
||||
x=abc
|
||||
set -- a b
|
||||
showargs ${x#$*}
|
||||
expected-stdout:
|
||||
<c> .
|
||||
---
|
||||
name: IFS-subst-7
|
||||
description:
|
||||
ksh93 bug wrt. vector expansion in trim
|
||||
stdin:
|
||||
showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
|
||||
IFS="*"
|
||||
a=abcd
|
||||
set -- '' c
|
||||
showargs "$*" ${a##"$*"}
|
||||
expected-stdout:
|
||||
<*c> <abcd> .
|
||||
---
|
||||
name: IFS-subst-8
|
||||
description:
|
||||
http://austingroupbugs.net/view.php?id=221
|
||||
stdin:
|
||||
n() { echo "$#"; }; n "${foo-$@}"
|
||||
expected-stdout:
|
||||
1
|
||||
---
|
||||
name: IFS-subst-9
|
||||
description:
|
||||
Scalar context for $*/$@ in [[ and case
|
||||
stdin:
|
||||
"$__progname" -c 'IFS=; set a b; [[ $* = "$1$2" ]]; echo 1 $?' sh a b
|
||||
"$__progname" -c 'IFS=; [[ $* = ab ]]; echo 2 "$?"' sh a b
|
||||
"$__progname" -c 'IFS=; [[ "$*" = ab ]]; echo 3 "$?"' sh a b
|
||||
"$__progname" -c 'IFS=; [[ $* = a ]]; echo 4 "$?"' sh a b
|
||||
"$__progname" -c 'IFS=; [[ "$*" = a ]]; echo 5 "$?"' sh a b
|
||||
"$__progname" -c 'IFS=; [[ "$@" = a ]]; echo 6 "$?"' sh a b
|
||||
"$__progname" -c 'IFS=; case "$@" in a) echo 7 a;; ab) echo 7 b;; a\ b) echo 7 ok;; esac' sh a b
|
||||
"$__progname" -c 'IFS=; case $* in a) echo 8 a;; ab) echo 8 ok;; esac' sh a b
|
||||
"$__progname" -c 'pfsp() { for s_arg in "$@"; do print -nr -- "<$s_arg> "; done; print .; }; IFS=; star=$* at="$@"; pfsp 9 "$star" "$at"' sh a b
|
||||
expected-stdout:
|
||||
1 0
|
||||
2 0
|
||||
3 0
|
||||
4 1
|
||||
5 1
|
||||
6 1
|
||||
7 ok
|
||||
8 ok
|
||||
<9> <ab> <a b> .
|
||||
---
|
||||
name: IFS-arith-1
|
||||
description:
|
||||
http://austingroupbugs.net/view.php?id=832
|
||||
stdin:
|
||||
${ZSH_VERSION+false} || emulate sh
|
||||
${BASH_VERSION+set -o posix}
|
||||
showargs() { for x in "$@"; do echo -n "<$x> "; done; echo .; }
|
||||
showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
|
||||
IFS=0
|
||||
showargs $((1230456))
|
||||
expected-stdout:
|
||||
|
@ -7063,6 +7243,7 @@ description:
|
|||
XXX if the OS can already execute them, we lose
|
||||
note: cygwin execve(2) doesn't return to us with ENOEXEC, we lose
|
||||
note: Ultrix perl5 t4 returns 65280 (exit-code 255) and no text
|
||||
XXX fails when LD_PRELOAD is set with -e and Perl chokes it (ASan)
|
||||
need-pass: no
|
||||
category: !os:cygwin,!os:msys,!os:ultrix,!os:uwin-nt,!smksh
|
||||
env-setup: !FOO=BAR!
|
||||
|
@ -8013,6 +8194,66 @@ expected-stdout:
|
|||
.fnr:f:
|
||||
.f2r:f:
|
||||
---
|
||||
name: unset-fnc-local-ksh
|
||||
description:
|
||||
Check that “unset” removes a previous “local”
|
||||
(ksh93 syntax compatible version); apparently,
|
||||
there are shells which fail this?
|
||||
stdin:
|
||||
function f {
|
||||
echo f0: $x
|
||||
typeset x
|
||||
echo f1: $x
|
||||
x=fa
|
||||
echo f2: $x
|
||||
unset x
|
||||
echo f3: $x
|
||||
x=fb
|
||||
echo f4: $x
|
||||
}
|
||||
x=o
|
||||
echo before: $x
|
||||
f
|
||||
echo after: $x
|
||||
expected-stdout:
|
||||
before: o
|
||||
f0: o
|
||||
f1:
|
||||
f2: fa
|
||||
f3: o
|
||||
f4: fb
|
||||
after: fb
|
||||
---
|
||||
name: unset-fnc-local-sh
|
||||
description:
|
||||
Check that “unset” removes a previous “local”
|
||||
(Debian Policy §10.4 sh version); apparently,
|
||||
there are shells which fail this?
|
||||
stdin:
|
||||
f() {
|
||||
echo f0: $x
|
||||
local x
|
||||
echo f1: $x
|
||||
x=fa
|
||||
echo f2: $x
|
||||
unset x
|
||||
echo f3: $x
|
||||
x=fb
|
||||
echo f4: $x
|
||||
}
|
||||
x=o
|
||||
echo before: $x
|
||||
f
|
||||
echo after: $x
|
||||
expected-stdout:
|
||||
before: o
|
||||
f0: o
|
||||
f1:
|
||||
f2: fa
|
||||
f3: o
|
||||
f4: fb
|
||||
after: fb
|
||||
---
|
||||
name: varexpand-substr-1
|
||||
description:
|
||||
Check if bash-style substring expansion works
|
||||
|
@ -8172,13 +8413,21 @@ name: varexpand-null-1
|
|||
description:
|
||||
Ensure empty strings expand emptily
|
||||
stdin:
|
||||
print x ${a} ${b} y
|
||||
print z ${a#?} ${b%?} w
|
||||
print v ${a=} ${b/c/d} u
|
||||
print s ${a} . ${b} S
|
||||
print t ${a#?} . ${b%?} T
|
||||
print r ${a=} . ${b/c/d} R
|
||||
print q
|
||||
print s "${a}" . "${b}" S
|
||||
print t "${a#?}" . "${b%?}" T
|
||||
print r "${a=}" . "${b/c/d}" R
|
||||
expected-stdout:
|
||||
x y
|
||||
z w
|
||||
v u
|
||||
s . S
|
||||
t . T
|
||||
r . R
|
||||
q
|
||||
s . S
|
||||
t . T
|
||||
r . R
|
||||
---
|
||||
name: varexpand-null-2
|
||||
description:
|
||||
|
@ -8194,13 +8443,41 @@ expected-stdout:
|
|||
name: varexpand-null-3
|
||||
description:
|
||||
Ensure concatenating behaviour matches other shells
|
||||
although the line 2<> is probably wrong? XNULLSUB case.
|
||||
stdin:
|
||||
x=; printf "1<%s>\n" "$x$@"
|
||||
set A; printf "2<%s>\n" "${@:+}"
|
||||
showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
|
||||
x=; showargs 1 "$x"$@
|
||||
set A; showargs 2 "${@:+}"
|
||||
n() { echo "$#"; }
|
||||
unset e
|
||||
set -- a b
|
||||
n """$@"
|
||||
n "$@"
|
||||
n "$@"""
|
||||
n "$e""$@"
|
||||
n "$@"
|
||||
n "$@""$e"
|
||||
set --
|
||||
n """$@"
|
||||
n "$@"
|
||||
n "$@"""
|
||||
n "$e""$@"
|
||||
n "$@"
|
||||
n "$@""$e"
|
||||
expected-stdout:
|
||||
1<>
|
||||
2<>
|
||||
<1> <> .
|
||||
<2> <> .
|
||||
2
|
||||
2
|
||||
2
|
||||
2
|
||||
2
|
||||
2
|
||||
1
|
||||
0
|
||||
1
|
||||
1
|
||||
0
|
||||
1
|
||||
---
|
||||
name: print-funny-chars
|
||||
description:
|
||||
|
@ -10921,6 +11198,7 @@ stdin:
|
|||
(mypid=$$; try mypid)
|
||||
echo =15
|
||||
) 2>&1 | sed -e 's/^[^]]*]//' -e 's/^[^:]*: *//'
|
||||
exit ${PIPESTATUS[0]}
|
||||
expected-stdout:
|
||||
y
|
||||
=1
|
||||
|
@ -11655,3 +11933,26 @@ expected-stdout:
|
|||
expected-stderr-pattern:
|
||||
/.*/
|
||||
---
|
||||
name: xtrace-2
|
||||
description:
|
||||
Check that "set -x" is off during PS4 expansion
|
||||
stdin:
|
||||
f() {
|
||||
print -n "(f1:$-)"
|
||||
set -x
|
||||
print -n "(f2:$-)"
|
||||
}
|
||||
PS4='[(p:$-)$(f)] '
|
||||
print "(o0:$-)"
|
||||
set -x -o inherit-xtrace
|
||||
print "(o1:$-)"
|
||||
set +x
|
||||
print "(o2:$-)"
|
||||
expected-stdout:
|
||||
(o0:sh)
|
||||
(o1:shx)
|
||||
(o2:sh)
|
||||
expected-stderr:
|
||||
[(p:sh)(f1:sh)(f2:sh)] print '(o1:shx)'
|
||||
[(p:sh)(f1:sh)(f2:sh)] set +x
|
||||
---
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
# $Id$
|
||||
# $MirOS: src/bin/mksh/dot.mkshrc,v 1.89 2014/07/28 21:45:44 tg Exp $
|
||||
# $MirOS: src/bin/mksh/dot.mkshrc,v 1.89.2.1 2015/01/11 22:39:44 tg Exp $
|
||||
#-
|
||||
# Copyright (c) 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010,
|
||||
# 2011, 2012, 2013, 2014
|
||||
# 2011, 2012, 2013, 2014, 2015
|
||||
# Thorsten Glaser <tg@mirbsd.org>
|
||||
#
|
||||
# Provided that these terms and disclaimer and all copyright notices
|
||||
|
@ -67,7 +67,7 @@ else
|
|||
local dasc line i
|
||||
|
||||
cat "$@" | { set +U; if read -arN -1 line; then
|
||||
typeset -i1 line
|
||||
typeset -i1 'line[*]'
|
||||
i=0
|
||||
while (( i < ${#line[*]} )); do
|
||||
hv=${line[i++]}
|
||||
|
@ -263,9 +263,8 @@ function smores {
|
|||
|
||||
# base64 encoder and decoder, RFC compliant, NUL safe
|
||||
function Lb64decode {
|
||||
[[ -o utf8-mode ]]; local u=$?
|
||||
[[ -o utf8-mode ]]; local u=$? c s="$*" t
|
||||
set +U
|
||||
local c s="$*" t=
|
||||
[[ -n $s ]] || { s=$(cat; print x); s=${s%x}; }
|
||||
local -i i=0 j=0 n=${#s} p=0 v x
|
||||
local -i16 o
|
||||
|
@ -302,9 +301,8 @@ function Lb64decode {
|
|||
set -A Lb64encode_code -- A B C D E F G H I J K L M N O P Q R S T U V W X Y Z \
|
||||
a b c d e f g h i j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 8 9 + /
|
||||
function Lb64encode {
|
||||
[[ -o utf8-mode ]]; local u=$?
|
||||
[[ -o utf8-mode ]]; local u=$? c s t
|
||||
set +U
|
||||
local c s t
|
||||
if (( $# )); then
|
||||
read -raN-1 s <<<"$*"
|
||||
unset s[${#s[*]}-1]
|
||||
|
@ -342,9 +340,8 @@ function Lbafh_init {
|
|||
Lbafh_v=0
|
||||
}
|
||||
function Lbafh_add {
|
||||
[[ -o utf8-mode ]]; local u=$?
|
||||
[[ -o utf8-mode ]]; local u=$? s
|
||||
set +U
|
||||
local s
|
||||
if (( $# )); then
|
||||
read -raN-1 s <<<"$*"
|
||||
unset s[${#s[*]}-1]
|
||||
|
|
16
src/edit.c
16
src/edit.c
|
@ -1,6 +1,6 @@
|
|||
/* $OpenBSD: edit.c,v 1.39 2013/12/17 16:37:05 deraadt Exp $ */
|
||||
/* $OpenBSD: edit.h,v 1.9 2011/05/30 17:14:35 martynas Exp $ */
|
||||
/* $OpenBSD: emacs.c,v 1.48 2013/12/17 16:37:05 deraadt Exp $ */
|
||||
/* $OpenBSD: emacs.c,v 1.49 2015/02/16 01:44:41 tedu Exp $ */
|
||||
/* $OpenBSD: vi.c,v 1.28 2013/12/18 16:45:46 deraadt Exp $ */
|
||||
|
||||
/*-
|
||||
|
@ -28,7 +28,7 @@
|
|||
|
||||
#ifndef MKSH_NO_CMDLINE_EDITING
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.276 2014/07/13 11:34:28 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.276.2.3 2015/03/01 15:42:56 tg Exp $");
|
||||
|
||||
/*
|
||||
* in later versions we might use libtermcap for this, but since external
|
||||
|
@ -327,7 +327,7 @@ x_glob_hlp_tilde_and_rem_qchar(char *s, bool magic_flag)
|
|||
/* ok, so split into "~foo"/"bar" or "~"/"baz" */
|
||||
*cp++ = 0;
|
||||
/* try to expand the tilde */
|
||||
if (!(dp = tilde(s + 1))) {
|
||||
if (!(dp = do_tilde(s + 1))) {
|
||||
/* nope, revert damage */
|
||||
*--cp = '/';
|
||||
} else {
|
||||
|
@ -592,8 +592,6 @@ x_cf_glob(int *flagsp, const char *buf, int buflen, int pos, int *startp,
|
|||
char **words = NULL;
|
||||
bool is_command;
|
||||
|
||||
mkssert(buf != NULL);
|
||||
|
||||
len = x_locate_word(buf, buflen, pos, startp, &is_command);
|
||||
if (!((*flagsp) & XCF_COMMAND))
|
||||
is_command = false;
|
||||
|
@ -1009,7 +1007,6 @@ enum emacs_funcs {
|
|||
static const struct x_ftab x_ftab[] = {
|
||||
#define EMACSFN_ITEMS
|
||||
#include "emacsfn.h"
|
||||
{ 0, NULL, 0 }
|
||||
};
|
||||
|
||||
static struct x_defbindings const x_defbindings[] = {
|
||||
|
@ -2240,7 +2237,6 @@ x_push(int nchars)
|
|||
{
|
||||
char *cp;
|
||||
|
||||
mkssert(xcp != NULL);
|
||||
strndupx(cp, xcp, nchars, AEDIT);
|
||||
if (killstack[killsp])
|
||||
afree(killstack[killsp], AEDIT);
|
||||
|
@ -2455,8 +2451,7 @@ x_bind(const char *a1, const char *a2,
|
|||
/* List function names */
|
||||
if (list) {
|
||||
for (f = 0; f < NELEM(x_ftab); f++)
|
||||
if (x_ftab[f].xf_name &&
|
||||
!(x_ftab[f].xf_flags & XF_NOBIND))
|
||||
if (!(x_ftab[f].xf_flags & XF_NOBIND))
|
||||
shprintf("%s\n", x_ftab[f].xf_name);
|
||||
return (0);
|
||||
}
|
||||
|
@ -2517,8 +2512,7 @@ x_bind(const char *a1, const char *a2,
|
|||
#endif
|
||||
} else {
|
||||
for (f = 0; f < NELEM(x_ftab); f++)
|
||||
if (x_ftab[f].xf_name &&
|
||||
strcmp(x_ftab[f].xf_name, a2) == 0)
|
||||
if (!strcmp(x_ftab[f].xf_name, a2))
|
||||
break;
|
||||
if (f == NELEM(x_ftab) || x_ftab[f].xf_flags & XF_NOBIND) {
|
||||
bi_errorf("%s: %s %s", a2, "no such", Tfunction);
|
||||
|
|
108
src/eval.c
108
src/eval.c
|
@ -2,7 +2,7 @@
|
|||
|
||||
/*-
|
||||
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||
* 2011, 2012, 2013, 2014
|
||||
* 2011, 2012, 2013, 2014, 2015
|
||||
* Thorsten Glaser <tg@mirbsd.org>
|
||||
*
|
||||
* Provided that these terms and disclaimer and all copyright notices
|
||||
|
@ -23,7 +23,7 @@
|
|||
|
||||
#include "sh.h"
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.153 2014/10/07 15:22:16 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.158.2.4 2015/03/01 15:42:58 tg Exp $");
|
||||
|
||||
/*
|
||||
* string expansion
|
||||
|
@ -59,10 +59,11 @@ typedef struct {
|
|||
#define XSUBMID 6 /* middle of expanding ${} */
|
||||
|
||||
/* States used for field splitting */
|
||||
#define IFS_WORD 0 /* word has chars (or quotes) */
|
||||
#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_QUOTE 4 /* beg.w/quote, become IFS_WORD unless "$@" */
|
||||
|
||||
static int varsub(Expand *, const char *, const char *, int *, int *);
|
||||
static int comsub(Expand *, const char *, int);
|
||||
|
@ -70,7 +71,7 @@ static char *valsub(struct op *, Area *);
|
|||
static char *trimsub(char *, char *, int);
|
||||
static void glob(char *, XPtrV *, bool);
|
||||
static void globit(XString *, char **, char *, XPtrV *, int);
|
||||
static const char *maybe_expand_tilde(const char *, XString *, char **, int);
|
||||
static const char *maybe_expand_tilde(const char *, XString *, char **, bool);
|
||||
#ifndef MKSH_NOPWNAM
|
||||
static char *homedir(char *);
|
||||
#endif
|
||||
|
@ -237,7 +238,7 @@ expand(
|
|||
/* record number of trailing newlines in COMSUB */
|
||||
int newlines = 0;
|
||||
bool saw_eq, make_magic;
|
||||
int tilde_ok;
|
||||
unsigned int tilde_ok;
|
||||
size_t len;
|
||||
char *cp;
|
||||
|
||||
|
@ -246,7 +247,7 @@ expand(
|
|||
/* for alias, readonly, set, typeset commands */
|
||||
if ((f & DOVACHECK) && is_wdvarassign(ccp)) {
|
||||
f &= ~(DOVACHECK | DOBLANK | DOGLOB | DOTILDE);
|
||||
f |= DOASNTILDE | DOASNFIELD;
|
||||
f |= DOASNTILDE | DOSCALAR;
|
||||
}
|
||||
if (Flag(FNOGLOB))
|
||||
f &= ~DOGLOB;
|
||||
|
@ -290,7 +291,17 @@ expand(
|
|||
c = *sp++;
|
||||
break;
|
||||
case OQUOTE:
|
||||
word = IFS_WORD;
|
||||
switch (word) {
|
||||
case IFS_QUOTE:
|
||||
/* """something */
|
||||
word = IFS_WORD;
|
||||
break;
|
||||
case IFS_WORD:
|
||||
break;
|
||||
default:
|
||||
word = IFS_QUOTE;
|
||||
break;
|
||||
}
|
||||
tilde_ok = 0;
|
||||
quote = 1;
|
||||
continue;
|
||||
|
@ -383,6 +394,8 @@ expand(
|
|||
if (f & DOBLANK)
|
||||
doblank++;
|
||||
tilde_ok = 0;
|
||||
if (word == IFS_QUOTE && type != XNULLSUB)
|
||||
word = IFS_WORD;
|
||||
if (type == XBASE) {
|
||||
/* expand? */
|
||||
if (!st->next) {
|
||||
|
@ -516,7 +529,6 @@ expand(
|
|||
|
||||
/* check for special cases */
|
||||
d = str_val(st->var);
|
||||
mkssert(d != NULL);
|
||||
switch (*pat) {
|
||||
case '#':
|
||||
/* anchor at begin */
|
||||
|
@ -622,7 +634,7 @@ expand(
|
|||
case '%':
|
||||
/* ! DOBLANK,DOBRACE,DOTILDE */
|
||||
f = (f & DONTRUNCOMMAND) |
|
||||
DOPAT | DOTEMP;
|
||||
DOPAT | DOTEMP | DOSCALAR;
|
||||
st->quotew = quote = 0;
|
||||
/*
|
||||
* Prepend open pattern (so |
|
||||
|
@ -631,7 +643,7 @@ expand(
|
|||
*/
|
||||
if (!Flag(FSH)) {
|
||||
*dp++ = MAGIC;
|
||||
*dp++ = '@' | 0x80;
|
||||
*dp++ = 0x80 | '@';
|
||||
}
|
||||
break;
|
||||
case '=':
|
||||
|
@ -664,7 +676,11 @@ expand(
|
|||
f |= DOTEMP;
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
word = quote ? IFS_WORD : IFS_IWS;
|
||||
/* '-' '+' '?' */
|
||||
if (quote)
|
||||
word = IFS_WORD;
|
||||
else if (dp == Xstring(ds, dp))
|
||||
word = IFS_IWS;
|
||||
/* Enable tilde expansion */
|
||||
tilde_ok = 1;
|
||||
f |= DOTILDE;
|
||||
|
@ -704,10 +720,16 @@ expand(
|
|||
x.str = trimsub(str_val(st->var),
|
||||
dp, st->stype);
|
||||
if (x.str[0] != '\0') {
|
||||
word = IFS_WS;
|
||||
word = IFS_IWS;
|
||||
type = XSUB;
|
||||
} else
|
||||
type = quote ? XSUB : XNULLSUB;
|
||||
} else if (quote) {
|
||||
word = IFS_WORD;
|
||||
type = XSUB;
|
||||
} else {
|
||||
if (dp == Xstring(ds, dp))
|
||||
word = IFS_IWS;
|
||||
type = XNULLSUB;
|
||||
}
|
||||
if (f & DOBLANK)
|
||||
doblank++;
|
||||
st = st->prev;
|
||||
|
@ -743,7 +765,7 @@ expand(
|
|||
if (f & DOBLANK)
|
||||
doblank++;
|
||||
st = st->prev;
|
||||
word = quote || (!*x.str && (f & DOASNFIELD)) ? IFS_WORD : IFS_WS;
|
||||
word = quote || (!*x.str && (f & DOSCALAR)) ? IFS_WORD : IFS_IWS;
|
||||
continue;
|
||||
case '?': {
|
||||
char *s = Xrestpos(ds, dp, st->base);
|
||||
|
@ -759,11 +781,12 @@ expand(
|
|||
case 0x100 | 'Q':
|
||||
dp = Xrestpos(ds, dp, st->base);
|
||||
type = XSUB;
|
||||
word = quote || (!*x.str && (f & DOASNFIELD)) ? IFS_WORD : IFS_WS;
|
||||
word = quote || (!*x.str && (f & DOSCALAR)) ? IFS_WORD : IFS_IWS;
|
||||
if (f & DOBLANK)
|
||||
doblank++;
|
||||
st = st->prev;
|
||||
continue;
|
||||
/* default: '-' '+' */
|
||||
}
|
||||
st = st->prev;
|
||||
type = XBASE;
|
||||
|
@ -799,8 +822,8 @@ expand(
|
|||
type = XBASE;
|
||||
if (f & DOBLANK) {
|
||||
doblank--;
|
||||
if (dp == Xstring(ds, dp))
|
||||
word = IFS_WS;
|
||||
if (dp == Xstring(ds, dp) && word != IFS_WORD)
|
||||
word = IFS_IWS;
|
||||
}
|
||||
continue;
|
||||
|
||||
|
@ -834,15 +857,20 @@ expand(
|
|||
continue;
|
||||
}
|
||||
c = ifs0;
|
||||
if ((f & DOASNFIELD)) {
|
||||
/* assignment, do not field-split */
|
||||
if ((f & DOHEREDOC)) {
|
||||
/* pseudo-field-split reliably */
|
||||
if (c == 0)
|
||||
c = ' ';
|
||||
break;
|
||||
}
|
||||
if ((f & DOSCALAR)) {
|
||||
/* do not field-split */
|
||||
if (x.split) {
|
||||
c = ' ';
|
||||
break;
|
||||
}
|
||||
if (c == 0) {
|
||||
if (c == 0)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (c == 0) {
|
||||
if (quote && !x.split)
|
||||
|
@ -867,7 +895,7 @@ expand(
|
|||
/* $(<...) failed */
|
||||
subst_exstat = 1;
|
||||
/* fake EOF */
|
||||
c = EOF;
|
||||
c = -1;
|
||||
} else if (newlines) {
|
||||
/* spit out saved NLs */
|
||||
c = '\n';
|
||||
|
@ -877,13 +905,13 @@ expand(
|
|||
if (c == '\n')
|
||||
/* save newlines */
|
||||
newlines++;
|
||||
if (newlines && c != EOF) {
|
||||
if (newlines && c != -1) {
|
||||
shf_ungetc(c, x.u.shf);
|
||||
c = '\n';
|
||||
--newlines;
|
||||
}
|
||||
}
|
||||
if (c == EOF) {
|
||||
if (c == -1) {
|
||||
newlines = 0;
|
||||
if (x.u.shf)
|
||||
shf_close(x.u.shf);
|
||||
|
@ -911,7 +939,7 @@ expand(
|
|||
* IFS_IWS -/WS w/NWS -
|
||||
* (w means generate a word)
|
||||
*/
|
||||
if ((word == IFS_WORD) || (c &&
|
||||
if ((word == IFS_WORD) || (word == IFS_QUOTE) || (c &&
|
||||
(word == IFS_IWS || word == IFS_NWS) &&
|
||||
!ctype(c, C_IFSWS))) {
|
||||
emit_word:
|
||||
|
@ -1023,7 +1051,7 @@ expand(
|
|||
|
||||
tcp = maybe_expand_tilde(sp,
|
||||
&ds, &tdp,
|
||||
f & DOASNTILDE);
|
||||
tobool(f & DOASNTILDE));
|
||||
if (tcp) {
|
||||
if (dp != tdp)
|
||||
word = IFS_WORD;
|
||||
|
@ -1659,7 +1687,7 @@ debunk(char *dp, const char *sp, size_t dlen)
|
|||
* past the name, otherwise returns 0.
|
||||
*/
|
||||
static const char *
|
||||
maybe_expand_tilde(const char *p, XString *dsp, char **dpp, int isassign)
|
||||
maybe_expand_tilde(const char *p, XString *dsp, char **dpp, bool isassign)
|
||||
{
|
||||
XString ts;
|
||||
char *dp = *dpp;
|
||||
|
@ -1676,7 +1704,7 @@ maybe_expand_tilde(const char *p, XString *dsp, char **dpp, int isassign)
|
|||
}
|
||||
*tp = '\0';
|
||||
r = (p[0] == EOS || p[0] == CHAR || p[0] == CSUBST) ?
|
||||
tilde(Xstring(ts, tp)) : NULL;
|
||||
do_tilde(Xstring(ts, tp)) : NULL;
|
||||
Xfree(ts, tp);
|
||||
if (r) {
|
||||
while (*r) {
|
||||
|
@ -1698,7 +1726,7 @@ maybe_expand_tilde(const char *p, XString *dsp, char **dpp, int isassign)
|
|||
*/
|
||||
|
||||
char *
|
||||
tilde(char *cp)
|
||||
do_tilde(char *cp)
|
||||
{
|
||||
char *dp = null;
|
||||
|
||||
|
@ -1745,28 +1773,30 @@ homedir(char *name)
|
|||
static void
|
||||
alt_expand(XPtrV *wp, char *start, char *exp_start, char *end, int fdo)
|
||||
{
|
||||
int count = 0;
|
||||
unsigned int count = 0;
|
||||
char *brace_start, *brace_end, *comma = NULL;
|
||||
char *field_start;
|
||||
char *p;
|
||||
char *p = exp_start;
|
||||
|
||||
/* search for open brace */
|
||||
for (p = exp_start; (p = strchr(p, MAGIC)) && p[1] != '{' /*}*/; p += 2)
|
||||
;
|
||||
while ((p = strchr(p, MAGIC)) && p[1] != '{' /*}*/)
|
||||
p += 2;
|
||||
brace_start = p;
|
||||
|
||||
/* find matching close brace, if any */
|
||||
if (p) {
|
||||
comma = NULL;
|
||||
count = 1;
|
||||
for (p += 2; *p && count; p++) {
|
||||
if (ISMAGIC(*p)) {
|
||||
if (*++p == '{' /*}*/)
|
||||
count++;
|
||||
p += 2;
|
||||
while (*p && count) {
|
||||
if (ISMAGIC(*p++)) {
|
||||
if (*p == '{' /*}*/)
|
||||
++count;
|
||||
else if (*p == /*{*/ '}')
|
||||
--count;
|
||||
else if (*p == ',' && count == 1)
|
||||
comma = p;
|
||||
++p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1795,7 +1825,7 @@ alt_expand(XPtrV *wp, char *start, char *exp_start, char *end, int fdo)
|
|||
for (p = brace_start + 2; p != brace_end; p++) {
|
||||
if (ISMAGIC(*p)) {
|
||||
if (*++p == '{' /*}*/)
|
||||
count++;
|
||||
++count;
|
||||
else if ((*p == /*{*/ '}' && --count == 0) ||
|
||||
(*p == ',' && count == 1)) {
|
||||
char *news;
|
||||
|
|
213
src/exec.c
213
src/exec.c
|
@ -2,7 +2,7 @@
|
|||
|
||||
/*-
|
||||
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||
* 2011, 2012, 2013, 2014
|
||||
* 2011, 2012, 2013, 2014, 2015
|
||||
* Thorsten Glaser <tg@mirbsd.org>
|
||||
*
|
||||
* Provided that these terms and disclaimer and all copyright notices
|
||||
|
@ -23,7 +23,7 @@
|
|||
|
||||
#include "sh.h"
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.133 2014/10/03 17:32:11 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.137.2.2 2015/03/01 15:42:59 tg Exp $");
|
||||
|
||||
#ifndef MKSH_DEFAULT_EXECSHELL
|
||||
#define MKSH_DEFAULT_EXECSHELL "/bin/sh"
|
||||
|
@ -32,7 +32,7 @@ __RCSID("$MirOS: src/bin/mksh/exec.c,v 1.133 2014/10/03 17:32:11 tg Exp $");
|
|||
static int comexec(struct op *, struct tbl * volatile, const char **,
|
||||
int volatile, volatile int *);
|
||||
static void scriptexec(struct op *, const char **) MKSH_A_NORETURN;
|
||||
static int call_builtin(struct tbl *, const char **, const char *);
|
||||
static int call_builtin(struct tbl *, const char **, const char *, bool);
|
||||
static int iosetup(struct ioword *, struct tbl *);
|
||||
static int herein(struct ioword *, char **);
|
||||
static const char *do_selectargs(const char **, bool);
|
||||
|
@ -81,6 +81,8 @@ execute(struct op * volatile t,
|
|||
/* we want to run an executable, do some variance checks */
|
||||
if (t->type == TCOM) {
|
||||
/* check if this is 'var=<<EOF' */
|
||||
/*XXX this is broken, don’t use! */
|
||||
/*XXX https://bugs.launchpad.net/mksh/+bug/1380389 */
|
||||
if (
|
||||
/* we have zero arguments, i.e. no programme to run */
|
||||
t->args[0] == NULL &&
|
||||
|
@ -94,20 +96,23 @@ execute(struct op * volatile t,
|
|||
/* the variable assignment begins with a valid varname */
|
||||
(ccp = skip_wdvarname(t->vars[0], true)) != t->vars[0] &&
|
||||
/* and has no right-hand side (i.e. "varname=") */
|
||||
ccp[0] == CHAR && ccp[1] == '=' && ccp[2] == EOS &&
|
||||
ccp[0] == CHAR && ((ccp[1] == '=' && ccp[2] == EOS) ||
|
||||
/* or "varname+=" */ (ccp[1] == '+' && ccp[2] == CHAR &&
|
||||
ccp[3] == '=' && ccp[4] == EOS)) &&
|
||||
/* plus we can have a here document content */
|
||||
herein(t->ioact[0], &cp) == 0 && cp && *cp) {
|
||||
char *sp = cp, *dp;
|
||||
size_t n = ccp - t->vars[0] + 2, z;
|
||||
size_t n = ccp - t->vars[0] + (ccp[1] == '+' ? 4 : 2);
|
||||
size_t z;
|
||||
|
||||
/* drop redirection (will be garbage collected) */
|
||||
t->ioact = NULL;
|
||||
|
||||
/* set variable to its expanded value */
|
||||
z = strlen(cp) + 1;
|
||||
if (notoktomul(z, 2) || notoktoadd(z * 2, n))
|
||||
z = strlen(cp);
|
||||
if (notoktomul(z, 2) || notoktoadd(z * 2, n + 1))
|
||||
internal_errorf(Toomem, (size_t)-1);
|
||||
dp = alloc(z * 2 + n, ATEMP);
|
||||
dp = alloc(z * 2 + n + 1, APERM);
|
||||
memcpy(dp, t->vars[0], n);
|
||||
t->vars[0] = dp;
|
||||
dp += n;
|
||||
|
@ -398,7 +403,7 @@ execute(struct op * volatile t,
|
|||
|
||||
case TCASE:
|
||||
i = 0;
|
||||
ccp = evalstr(t->str, DOTILDE);
|
||||
ccp = evalstr(t->str, DOTILDE | DOSCALAR);
|
||||
for (t = t->left; t != NULL && t->type == TPAT; t = t->right) {
|
||||
for (ap = (const char **)t->vars; *ap; ap++) {
|
||||
if (i || ((s = evalstr(*ap, DOTILDE|DOPAT)) &&
|
||||
|
@ -441,7 +446,6 @@ execute(struct op * volatile t,
|
|||
|
||||
case TEXEC:
|
||||
/* an eval'd TCOM */
|
||||
s = t->args[0];
|
||||
up = makenv();
|
||||
restoresigs();
|
||||
cleanup_proc_env();
|
||||
|
@ -455,7 +459,7 @@ execute(struct op * volatile t,
|
|||
if (rv == ENOEXEC)
|
||||
scriptexec(t, (const char **)up);
|
||||
else
|
||||
errorf("%s: %s", s, cstrerror(rv));
|
||||
errorf("%s: %s", t->str, cstrerror(rv));
|
||||
}
|
||||
Break:
|
||||
exstat = rv & 0xFF;
|
||||
|
@ -500,18 +504,21 @@ comexec(struct op *t, struct tbl * volatile tp, const char **ap,
|
|||
/* Must be static (XXX but why?) */
|
||||
static struct op texec;
|
||||
int type_flags;
|
||||
bool keepasn_ok;
|
||||
bool resetspec;
|
||||
int fcflags = FC_BI|FC_FUNC|FC_PATH;
|
||||
bool bourne_function_call = false;
|
||||
struct block *l_expand, *l_assign;
|
||||
int optc;
|
||||
const char *exec_argv0 = NULL;
|
||||
bool exec_clrenv = false;
|
||||
|
||||
/*
|
||||
* snag the last argument for $_ XXX not the same as AT&T ksh,
|
||||
* which only seems to set $_ after a newline (but not in
|
||||
* functions/dot scripts, but in interactive and script) -
|
||||
* perhaps save last arg here and set it in shell()?.
|
||||
*/
|
||||
/* snag the last argument for $_ */
|
||||
if (Flag(FTALKING) && *(lastp = ap)) {
|
||||
/*
|
||||
* XXX not the same as AT&T ksh, which only seems to set $_
|
||||
* after a newline (but not in functions/dot scripts, but in
|
||||
* interactive and script) - perhaps save last arg here and
|
||||
* set it in shell()?.
|
||||
*/
|
||||
while (*++lastp)
|
||||
;
|
||||
/* setstr() can't fail here */
|
||||
|
@ -532,7 +539,7 @@ comexec(struct op *t, struct tbl * volatile tp, const char **ap,
|
|||
* FOO=bar command FOO is neither kept nor exported
|
||||
* PATH=... foobar use new PATH in foobar search
|
||||
*/
|
||||
keepasn_ok = true;
|
||||
resetspec = false;
|
||||
while (tp && tp->type == CSHELL) {
|
||||
/* undo effects of command */
|
||||
fcflags = FC_BI|FC_FUNC|FC_PATH;
|
||||
|
@ -548,10 +555,25 @@ comexec(struct op *t, struct tbl * volatile tp, const char **ap,
|
|||
} else if (tp->val.f == c_exec) {
|
||||
if (ap[1] == NULL)
|
||||
break;
|
||||
ap++;
|
||||
ksh_getopt_reset(&builtin_opt, GF_ERROR);
|
||||
while ((optc = ksh_getopt(ap, &builtin_opt, "a:c")) != -1)
|
||||
switch (optc) {
|
||||
case 'a':
|
||||
exec_argv0 = builtin_opt.optarg;
|
||||
break;
|
||||
case 'c':
|
||||
exec_clrenv = true;
|
||||
/* ensure we can actually do this */
|
||||
resetspec = true;
|
||||
break;
|
||||
default:
|
||||
rv = 2;
|
||||
goto Leave;
|
||||
}
|
||||
ap += builtin_opt.optind;
|
||||
flags |= XEXEC;
|
||||
} else if (tp->val.f == c_command) {
|
||||
int optc, saw_p = 0;
|
||||
bool saw_p = false;
|
||||
|
||||
/*
|
||||
* Ugly dealing with options in two places (here
|
||||
|
@ -559,8 +581,8 @@ comexec(struct op *t, struct tbl * volatile tp, const char **ap,
|
|||
*/
|
||||
ksh_getopt_reset(&builtin_opt, 0);
|
||||
while ((optc = ksh_getopt(ap, &builtin_opt, ":p")) == 'p')
|
||||
saw_p = 1;
|
||||
if (optc != EOF)
|
||||
saw_p = true;
|
||||
if (optc != -1)
|
||||
/* command -vV or something */
|
||||
break;
|
||||
/* don't look for functions */
|
||||
|
@ -579,7 +601,7 @@ comexec(struct op *t, struct tbl * volatile tp, const char **ap,
|
|||
* POSIX says special builtins lose their status
|
||||
* if accessed using command.
|
||||
*/
|
||||
keepasn_ok = false;
|
||||
resetspec = true;
|
||||
if (!ap[0]) {
|
||||
/* ensure command with no args exits with 0 */
|
||||
subst_exstat = 0;
|
||||
|
@ -614,20 +636,21 @@ comexec(struct op *t, struct tbl * volatile tp, const char **ap,
|
|||
if (t->u.evalflags & DOTCOMEXEC)
|
||||
flags |= XEXEC;
|
||||
l_expand = e->loc;
|
||||
if (keepasn_ok && (!ap[0] || (tp && (tp->flag & KEEPASN))))
|
||||
if (!resetspec && (!ap[0] || (tp && (tp->flag & KEEPASN))))
|
||||
type_flags = 0;
|
||||
else {
|
||||
/* create new variable/function block */
|
||||
newblock();
|
||||
/* ksh functions don't keep assignments, POSIX functions do. */
|
||||
if (keepasn_ok && tp && tp->type == CFUNC &&
|
||||
!(tp->flag & FKSH)) {
|
||||
bourne_function_call = true;
|
||||
if (!resetspec && tp && tp->type == CFUNC &&
|
||||
!(tp->flag & FKSH))
|
||||
type_flags = EXPORT;
|
||||
} else
|
||||
else
|
||||
type_flags = LOCAL|LOCAL_COPY|EXPORT;
|
||||
}
|
||||
l_assign = e->loc;
|
||||
if (exec_clrenv)
|
||||
l_assign->flags |= BF_STOPENV;
|
||||
if (Flag(FEXPORT))
|
||||
type_flags |= EXPORT;
|
||||
if (Flag(FXTRACE))
|
||||
|
@ -635,7 +658,7 @@ comexec(struct op *t, struct tbl * volatile tp, const char **ap,
|
|||
for (i = 0; t->vars[i]; i++) {
|
||||
/* do NOT lookup in the new var/fn block just created */
|
||||
e->loc = l_expand;
|
||||
cp = evalstr(t->vars[i], DOASNTILDE | DOASNFIELD);
|
||||
cp = evalstr(t->vars[i], DOASNTILDE | DOSCALAR);
|
||||
e->loc = l_assign;
|
||||
if (Flag(FXTRACE)) {
|
||||
const char *ccp;
|
||||
|
@ -651,8 +674,6 @@ comexec(struct op *t, struct tbl * volatile tp, const char **ap,
|
|||
}
|
||||
/* but assign in there as usual */
|
||||
typeset(cp, type_flags, 0, 0, 0);
|
||||
if (bourne_function_call && !(type_flags & EXPORT))
|
||||
typeset(cp, LOCAL | LOCAL_COPY | EXPORT, 0, 0, 0);
|
||||
}
|
||||
|
||||
if (Flag(FXTRACE)) {
|
||||
|
@ -684,8 +705,8 @@ comexec(struct op *t, struct tbl * volatile tp, const char **ap,
|
|||
|
||||
/* shell built-in */
|
||||
case CSHELL:
|
||||
rv = call_builtin(tp, (const char **)ap, null);
|
||||
if (!keepasn_ok && tp->val.f == c_shift) {
|
||||
rv = call_builtin(tp, (const char **)ap, null, resetspec);
|
||||
if (resetspec && tp->val.f == c_shift) {
|
||||
l_expand->argc = l_assign->argc;
|
||||
l_expand->argv = l_assign->argv;
|
||||
}
|
||||
|
@ -810,14 +831,24 @@ comexec(struct op *t, struct tbl * volatile tp, const char **ap,
|
|||
break;
|
||||
}
|
||||
|
||||
/* set $_ to programme's full path */
|
||||
/* set $_ to program's full path */
|
||||
/* setstr() can't fail here */
|
||||
setstr(typeset("_", LOCAL | EXPORT, 0, INTEGER, 0),
|
||||
tp->val.s, KSH_RETURN_ERROR);
|
||||
|
||||
if (flags&XEXEC) {
|
||||
/* to fork, we set up a TEXEC node and call execute */
|
||||
texec.type = TEXEC;
|
||||
/* for vistree/dumptree */
|
||||
texec.left = t;
|
||||
texec.str = tp->val.s;
|
||||
texec.args = ap;
|
||||
|
||||
/* in this case we do not fork, of course */
|
||||
if (flags & XEXEC) {
|
||||
if (exec_argv0)
|
||||
texec.args[0] = exec_argv0;
|
||||
j_exit();
|
||||
if (!(flags&XBGND)
|
||||
if (!(flags & XBGND)
|
||||
#ifndef MKSH_UNEMPLOYED
|
||||
|| Flag(FMONITOR)
|
||||
#endif
|
||||
|
@ -827,12 +858,6 @@ comexec(struct op *t, struct tbl * volatile tp, const char **ap,
|
|||
}
|
||||
}
|
||||
|
||||
/* to fork we set up a TEXEC node and call execute */
|
||||
texec.type = TEXEC;
|
||||
/* for tprint */
|
||||
texec.left = t;
|
||||
texec.str = tp->val.s;
|
||||
texec.args = ap;
|
||||
rv = exchild(&texec, flags, xerrok, -1);
|
||||
break;
|
||||
}
|
||||
|
@ -849,10 +874,8 @@ scriptexec(struct op *tp, const char **ap)
|
|||
{
|
||||
const char *sh;
|
||||
#ifndef MKSH_SMALL
|
||||
unsigned char *cp;
|
||||
/* 64 == MAXINTERP in MirBSD <sys/param.h> */
|
||||
char buf[64];
|
||||
int fd;
|
||||
unsigned char buf[68];
|
||||
#endif
|
||||
union mksh_ccphack args, cap;
|
||||
|
||||
|
@ -866,33 +889,35 @@ scriptexec(struct op *tp, const char **ap)
|
|||
|
||||
#ifndef MKSH_SMALL
|
||||
if ((fd = open(tp->str, O_RDONLY | O_BINARY)) >= 0) {
|
||||
/* read first MAXINTERP octets from file */
|
||||
if (read(fd, buf, sizeof(buf)) <= 0)
|
||||
/* read error -> no good */
|
||||
buf[0] = '\0';
|
||||
unsigned char *cp;
|
||||
unsigned short m;
|
||||
ssize_t n;
|
||||
|
||||
/* read first couple of octets from file */
|
||||
n = read(fd, buf, sizeof(buf) - 1);
|
||||
close(fd);
|
||||
/* read error or short read? */
|
||||
if (n < 5)
|
||||
goto nomagic;
|
||||
/* terminate buffer */
|
||||
buf[n] = '\0';
|
||||
|
||||
/* skip UTF-8 Byte Order Mark, if present */
|
||||
cp = (unsigned char *)buf;
|
||||
if ((cp[0] == 0xEF) && (cp[1] == 0xBB) && (cp[2] == 0xBF))
|
||||
cp += 3;
|
||||
/* save begin of shebang for later */
|
||||
fd = (char *)cp - buf; /* either 0 or (if BOM) 3 */
|
||||
cp = buf + (n = ((buf[0] == 0xEF) && (buf[1] == 0xBB) &&
|
||||
(buf[2] == 0xBF)) ? 3 : 0);
|
||||
|
||||
/* scan for newline (or CR) or NUL _before_ end of buffer */
|
||||
while ((size_t)((char *)cp - buf) < sizeof(buf))
|
||||
if (*cp == '\0' || *cp == '\n' || *cp == '\r') {
|
||||
*cp = '\0';
|
||||
break;
|
||||
} else
|
||||
++cp;
|
||||
/* scan for newline or NUL (end of buffer) */
|
||||
while (*cp && *cp != '\n')
|
||||
++cp;
|
||||
/* if the shebang line is longer than MAXINTERP, bail out */
|
||||
if ((size_t)((char *)cp - buf) >= sizeof(buf))
|
||||
if (!*cp)
|
||||
goto noshebang;
|
||||
/* replace newline by NUL */
|
||||
*cp = '\0';
|
||||
|
||||
/* restore begin of shebang position (buf+0 or buf+3) */
|
||||
cp = (unsigned char *)(buf + fd);
|
||||
/* bail out if read error (above) or no shebang */
|
||||
cp = buf + n;
|
||||
/* bail out if no shebang magic found */
|
||||
if ((cp[0] != '#') || (cp[1] != '!'))
|
||||
goto noshebang;
|
||||
|
||||
|
@ -918,22 +943,24 @@ scriptexec(struct op *tp, const char **ap)
|
|||
if (*cp)
|
||||
*tp->args-- = (char *)cp;
|
||||
}
|
||||
goto nomagic;
|
||||
noshebang:
|
||||
if (buf[0] == 0x7F && buf[1] == 'E' && buf[2] == 'L' &&
|
||||
buf[3] == 'F')
|
||||
m = buf[0] << 8 | buf[1];
|
||||
if (m == 0x7F45 && buf[2] == 'L' && buf[3] == 'F')
|
||||
errorf("%s: not executable: %d-bit ELF file", tp->str,
|
||||
32 * ((uint8_t)buf[4]));
|
||||
fd = buf[0] << 8 | buf[1];
|
||||
if ((fd == /* OMAGIC */ 0407) ||
|
||||
(fd == /* NMAGIC */ 0410) ||
|
||||
(fd == /* ZMAGIC */ 0413) ||
|
||||
(fd == /* QMAGIC */ 0314) ||
|
||||
(fd == /* ECOFF_I386 */ 0x4C01) ||
|
||||
(fd == /* ECOFF_M68K */ 0x0150 || fd == 0x5001) ||
|
||||
(fd == /* ECOFF_SH */ 0x0500 || fd == 0x0005) ||
|
||||
(fd == /* "MZ" */ 0x4D5A) ||
|
||||
(fd == /* gzip */ 0x1F8B))
|
||||
errorf("%s: not executable: magic %04X", tp->str, fd);
|
||||
32 * buf[4]);
|
||||
if ((m == /* OMAGIC */ 0407) ||
|
||||
(m == /* NMAGIC */ 0410) ||
|
||||
(m == /* ZMAGIC */ 0413) ||
|
||||
(m == /* QMAGIC */ 0314) ||
|
||||
(m == /* ECOFF_I386 */ 0x4C01) ||
|
||||
(m == /* ECOFF_M68K */ 0x0150 || m == 0x5001) ||
|
||||
(m == /* ECOFF_SH */ 0x0500 || m == 0x0005) ||
|
||||
(m == /* "MZ" */ 0x4D5A) ||
|
||||
(m == /* gzip */ 0x1F8B) || (m == /* .Z */ 0x1F9D))
|
||||
errorf("%s: not executable: magic %04X", tp->str, m);
|
||||
nomagic:
|
||||
;
|
||||
}
|
||||
#endif
|
||||
args.ro = tp->args;
|
||||
|
@ -952,7 +979,7 @@ shcomexec(const char **wp)
|
|||
struct tbl *tp;
|
||||
|
||||
tp = ktsearch(&builtins, *wp, hash(*wp));
|
||||
return (call_builtin(tp, wp, "shcomexec"));
|
||||
return (call_builtin(tp, wp, "shcomexec", false));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1001,8 +1028,6 @@ define(const char *name, struct op *t)
|
|||
|
||||
while (/* CONSTCOND */ 1) {
|
||||
tp = findfunc(name, nhash, true);
|
||||
/* because findfunc:create=true */
|
||||
mkssert(tp != NULL);
|
||||
|
||||
if (tp->flag & ISSET)
|
||||
was_set = true;
|
||||
|
@ -1265,22 +1290,22 @@ search_path(const char *name, const char *lpath,
|
|||
}
|
||||
|
||||
static int
|
||||
call_builtin(struct tbl *tp, const char **wp, const char *where)
|
||||
call_builtin(struct tbl *tp, const char **wp, const char *where, bool resetspec)
|
||||
{
|
||||
int rv;
|
||||
|
||||
if (!tp)
|
||||
internal_errorf("%s: %s", where, wp[0]);
|
||||
builtin_argv0 = wp[0];
|
||||
builtin_flag = tp->flag;
|
||||
builtin_spec = tobool(!resetspec && (tp->flag & SPEC_BI));
|
||||
shf_reopen(1, SHF_WR, shl_stdout);
|
||||
shl_stdout_ok = true;
|
||||
ksh_getopt_reset(&builtin_opt, GF_ERROR);
|
||||
rv = (*tp->val.f)(wp);
|
||||
shf_flush(shl_stdout);
|
||||
shl_stdout_ok = false;
|
||||
builtin_flag = 0;
|
||||
builtin_argv0 = NULL;
|
||||
builtin_spec = false;
|
||||
return (rv);
|
||||
}
|
||||
|
||||
|
@ -1467,7 +1492,7 @@ hereinval(const char *content, int sub, char **resbuf, struct shf *shf)
|
|||
if (yylex(sub) != LWORD)
|
||||
internal_errorf("%s: %s", "herein", "yylex");
|
||||
source = osource;
|
||||
ccp = evalstr(yylval.cp, 0);
|
||||
ccp = evalstr(yylval.cp, DOSCALAR | DOHEREDOC);
|
||||
}
|
||||
|
||||
if (resbuf == NULL)
|
||||
|
@ -1487,7 +1512,7 @@ herein(struct ioword *iop, char **resbuf)
|
|||
struct temp *h;
|
||||
int i;
|
||||
|
||||
/* ksh -c 'cat << EOF' can cause this... */
|
||||
/* ksh -c 'cat <<EOF' can cause this... */
|
||||
if (iop->heredoc == NULL) {
|
||||
warningf(true, "%s missing", "here document");
|
||||
/* special to iosetup(): don't print error */
|
||||
|
@ -1522,7 +1547,7 @@ herein(struct ioword *iop, char **resbuf)
|
|||
return (-2);
|
||||
}
|
||||
|
||||
if (shf_close(shf) == EOF) {
|
||||
if (shf_close(shf) == -1) {
|
||||
i = errno;
|
||||
close(fd);
|
||||
warningf(true, "can't %s temporary file %s: %s",
|
||||
|
@ -1559,7 +1584,8 @@ do_selectargs(const char **ap, bool print_menu)
|
|||
if (print_menu || !*str_val(global("REPLY")))
|
||||
pr_menu(ap);
|
||||
shellf("%s", str_val(global("PS3")));
|
||||
if (call_builtin(findcom("read", FC_BI), read_args, Tselect))
|
||||
if (call_builtin(findcom("read", FC_BI), read_args, Tselect,
|
||||
false))
|
||||
return (NULL);
|
||||
s = str_val(global("REPLY"));
|
||||
if (*s && getn(s, &i))
|
||||
|
@ -1709,6 +1735,7 @@ static const char *
|
|||
dbteste_getopnd(Test_env *te, Test_op op, bool do_eval)
|
||||
{
|
||||
const char *s = *te->pos.wp;
|
||||
int flags = DOTILDE | DOSCALAR;
|
||||
|
||||
if (!s)
|
||||
return (NULL);
|
||||
|
@ -1719,11 +1746,9 @@ dbteste_getopnd(Test_env *te, Test_op op, bool do_eval)
|
|||
return (null);
|
||||
|
||||
if (op == TO_STEQL || op == TO_STNEQ)
|
||||
s = evalstr(s, DOTILDE | DOPAT);
|
||||
else
|
||||
s = evalstr(s, DOTILDE);
|
||||
flags |= DOPAT;
|
||||
|
||||
return (s);
|
||||
return (evalstr(s, flags));
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: expr.c,v 1.23 2013/12/17 16:37:06 deraadt Exp $ */
|
||||
/* $OpenBSD: expr.c,v 1.24 2014/12/08 14:26:31 otto Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||
|
@ -23,7 +23,7 @@
|
|||
|
||||
#include "sh.h"
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/expr.c,v 1.76 2014/06/24 19:53:19 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/expr.c,v 1.76.2.1 2015/01/25 15:44:05 tg Exp $");
|
||||
|
||||
/* the order of these enums is constrained by the order of opinfo[] */
|
||||
enum token {
|
||||
|
|
55
src/funcs.c
55
src/funcs.c
|
@ -5,7 +5,7 @@
|
|||
|
||||
/*-
|
||||
* Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
|
||||
* 2010, 2011, 2012, 2013, 2014
|
||||
* 2010, 2011, 2012, 2013, 2014, 2015
|
||||
* Thorsten Glaser <tg@mirbsd.org>
|
||||
*
|
||||
* Provided that these terms and disclaimer and all copyright notices
|
||||
|
@ -38,7 +38,7 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.258 2014/09/03 19:55:51 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.259.2.2 2015/01/25 15:35:44 tg Exp $");
|
||||
|
||||
#if HAVE_KILLPG
|
||||
/*
|
||||
|
@ -550,7 +550,7 @@ c_whence(const char **wp)
|
|||
if (vflag || (tp->type != CALIAS && tp->type != CEXEC &&
|
||||
tp->type != CTALIAS))
|
||||
shf_puts(id, shl_stdout);
|
||||
if (vflag)
|
||||
if (vflag) {
|
||||
switch (tp->type) {
|
||||
case CKEYWD:
|
||||
case CALIAS:
|
||||
|
@ -559,11 +559,20 @@ c_whence(const char **wp)
|
|||
shf_puts(" is a", shl_stdout);
|
||||
break;
|
||||
}
|
||||
switch (tp->type) {
|
||||
case CKEYWD:
|
||||
case CSHELL:
|
||||
case CTALIAS:
|
||||
case CEXEC:
|
||||
shf_putc(' ', shl_stdout);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (tp->type) {
|
||||
case CKEYWD:
|
||||
if (vflag)
|
||||
shf_puts(" reserved word", shl_stdout);
|
||||
shf_puts("reserved word", shl_stdout);
|
||||
break;
|
||||
case CALIAS:
|
||||
if (vflag)
|
||||
|
@ -590,16 +599,17 @@ c_whence(const char **wp)
|
|||
}
|
||||
break;
|
||||
case CSHELL:
|
||||
if (vflag)
|
||||
shprintf("%s %s %s",
|
||||
(tp->flag & SPEC_BI) ? " special" : null,
|
||||
"shell", Tbuiltin);
|
||||
if (vflag) {
|
||||
if (tp->flag & SPEC_BI)
|
||||
shf_puts("special ", shl_stdout);
|
||||
shprintf("%s %s", "shell", Tbuiltin);
|
||||
}
|
||||
break;
|
||||
case CTALIAS:
|
||||
case CEXEC:
|
||||
if (tp->flag & ISSET) {
|
||||
if (vflag) {
|
||||
shf_puts(" is ", shl_stdout);
|
||||
shf_puts("is ", shl_stdout);
|
||||
if (tp->type == CTALIAS)
|
||||
shprintf("a tracked %s%s for ",
|
||||
(tp->flag & EXPORT) ?
|
||||
|
@ -609,12 +619,12 @@ c_whence(const char **wp)
|
|||
shf_puts(tp->val.s, shl_stdout);
|
||||
} else {
|
||||
if (vflag)
|
||||
shprintf(" %s\n", "not found");
|
||||
shf_puts("not found", shl_stdout);
|
||||
rv = 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
shprintf("%s is *GOK*", id);
|
||||
shf_puts(" is *GOK*", shl_stdout);
|
||||
break;
|
||||
}
|
||||
if (vflag || !rv)
|
||||
|
@ -1587,12 +1597,16 @@ c_shift(const char **wp)
|
|||
return (1);
|
||||
arg = wp[builtin_opt.optind];
|
||||
|
||||
if (arg) {
|
||||
evaluate(arg, &val, KSH_UNWIND_ERROR, false);
|
||||
n = val;
|
||||
} else
|
||||
if (!arg)
|
||||
n = 1;
|
||||
if (n < 0) {
|
||||
else if (!evaluate(arg, &val, KSH_RETURN_ERROR, false)) {
|
||||
/* error already printed */
|
||||
bi_errorfz();
|
||||
return (1);
|
||||
} else if (!(n = val)) {
|
||||
/* nothing to do */
|
||||
return (0);
|
||||
} else if (n < 0) {
|
||||
bi_errorf("%s: %s", arg, "bad number");
|
||||
return (1);
|
||||
}
|
||||
|
@ -1813,7 +1827,7 @@ c_read(const char **wp)
|
|||
char *cp, *allocd = NULL, *xp;
|
||||
const char *ccp;
|
||||
XString xs;
|
||||
ptrdiff_t xsave = 0;
|
||||
size_t xsave = 0;
|
||||
mksh_ttyst tios;
|
||||
bool restore_tios = false;
|
||||
#if HAVE_SELECT
|
||||
|
@ -2417,9 +2431,8 @@ c_set(const char **wp)
|
|||
return (c_typeset(args));
|
||||
}
|
||||
|
||||
argi = parse_args(wp, OF_SET, &setargs);
|
||||
if (argi < 0)
|
||||
return (1);
|
||||
if ((argi = parse_args(wp, OF_SET, &setargs)) < 0)
|
||||
return (2);
|
||||
/* set $# and $* */
|
||||
if (setargs) {
|
||||
wp += argi - 1;
|
||||
|
@ -2794,8 +2807,6 @@ c_test(const char **wp)
|
|||
|
||||
for (argc = 0; wp[argc]; argc++)
|
||||
;
|
||||
mkssert(argc > 0);
|
||||
mkssert(wp[0] != NULL);
|
||||
|
||||
if (strcmp(wp[0], "[") == 0) {
|
||||
if (strcmp(wp[--argc], "]") != 0) {
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/* $OpenBSD: history.c,v 1.39 2010/05/19 17:36:08 jasper Exp $ */
|
||||
/* $OpenBSD: history.c,v 1.40 2014/11/20 15:22:39 tedu Exp $ */
|
||||
/* $OpenBSD: trap.c,v 1.23 2010/05/19 17:36:08 jasper Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||
* 2011, 2012, 2014
|
||||
* 2011, 2012, 2014, 2015
|
||||
* Thorsten Glaser <tg@mirbsd.org>
|
||||
*
|
||||
* Provided that these terms and disclaimer and all copyright notices
|
||||
|
@ -27,7 +27,7 @@
|
|||
#include <sys/file.h>
|
||||
#endif
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.134 2014/06/09 13:25:53 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.134.2.3 2015/03/01 15:43:00 tg Exp $");
|
||||
|
||||
Trap sigtraps[NSIG + 1];
|
||||
static struct sigaction Sigact_ign;
|
||||
|
@ -303,7 +303,7 @@ c_fc(const char **wp)
|
|||
for (hp = rflag ? hlast : hfirst;
|
||||
hp >= hfirst && hp <= hlast; hp += rflag ? -1 : 1)
|
||||
shf_fprintf(shf, "%s\n", *hp);
|
||||
if (shf_close(shf) == EOF) {
|
||||
if (shf_close(shf) == -1) {
|
||||
bi_errorf("can't %s temporary file %s: %s",
|
||||
"write", tf->tffn, cstrerror(errno));
|
||||
return (1);
|
||||
|
@ -423,14 +423,14 @@ hist_get(const char *str, bool approx, bool allow_cur)
|
|||
|
||||
if (getn(str, &n)) {
|
||||
hp = histptr + (n < 0 ? n : (n - hist_source->line));
|
||||
if ((ptrdiff_t)hp < (ptrdiff_t)history) {
|
||||
if ((size_t)hp < (size_t)history) {
|
||||
if (approx)
|
||||
hp = hist_get_oldest();
|
||||
else {
|
||||
bi_errorf("%s: %s", str, Tnot_in_history);
|
||||
hp = NULL;
|
||||
}
|
||||
} else if ((ptrdiff_t)hp > (ptrdiff_t)histptr) {
|
||||
} else if ((size_t)hp > (size_t)histptr) {
|
||||
if (approx)
|
||||
hp = hist_get_newest(allow_cur);
|
||||
else {
|
||||
|
@ -634,7 +634,6 @@ histsave(int *lnp, const char *cmd, bool dowrite MKSH_A_UNUSED, bool ignoredups)
|
|||
char **hp;
|
||||
char *c, *cp;
|
||||
|
||||
mkssert(cmd != NULL);
|
||||
strdupx(c, cmd, APERM);
|
||||
if ((cp = strchr(c, '\n')) != NULL)
|
||||
*cp = '\0';
|
||||
|
|
42
src/jobs.c
42
src/jobs.c
|
@ -23,7 +23,7 @@
|
|||
|
||||
#include "sh.h"
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/jobs.c,v 1.105 2014/10/03 12:32:48 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/jobs.c,v 1.105.2.1 2015/01/25 15:44:06 tg Exp $");
|
||||
|
||||
#if HAVE_KILLPG
|
||||
#define mksh_killpg killpg
|
||||
|
@ -1047,7 +1047,7 @@ j_async(void)
|
|||
static void
|
||||
j_set_async(Job *j)
|
||||
{
|
||||
Job *jl, *oldest;
|
||||
Job *jl, *oldest;
|
||||
|
||||
if (async_job && (async_job->flags & (JF_KNOWN|JF_ZOMBIE)) == JF_ZOMBIE)
|
||||
remove_job(async_job, "async");
|
||||
|
@ -1084,7 +1084,7 @@ j_set_async(Job *j)
|
|||
static void
|
||||
j_startjob(Job *j)
|
||||
{
|
||||
Proc *p;
|
||||
Proc *p;
|
||||
|
||||
j->flags |= JF_STARTED;
|
||||
for (p = j->proc_list; p->next; p = p->next)
|
||||
|
@ -1421,8 +1421,8 @@ j_sigchld(int sig MKSH_A_UNUSED)
|
|||
static void
|
||||
check_job(Job *j)
|
||||
{
|
||||
int jstate;
|
||||
Proc *p;
|
||||
int jstate;
|
||||
Proc *p;
|
||||
|
||||
/* XXX debugging (nasty - interrupt routine using shl_out) */
|
||||
if (!(j->flags & JF_STARTED)) {
|
||||
|
@ -1524,14 +1524,14 @@ check_job(Job *j)
|
|||
static void
|
||||
j_print(Job *j, int how, struct shf *shf)
|
||||
{
|
||||
Proc *p;
|
||||
int state;
|
||||
int status;
|
||||
int coredumped;
|
||||
char jobchar = ' ';
|
||||
char buf[64];
|
||||
Proc *p;
|
||||
int state;
|
||||
int status;
|
||||
int coredumped;
|
||||
char jobchar = ' ';
|
||||
char buf[64];
|
||||
const char *filler;
|
||||
int output = 0;
|
||||
int output = 0;
|
||||
|
||||
if (how == JP_PGRP) {
|
||||
/*
|
||||
|
@ -1737,8 +1737,8 @@ static Proc *free_procs;
|
|||
static Job *
|
||||
new_job(void)
|
||||
{
|
||||
int i;
|
||||
Job *newj, *j;
|
||||
int i;
|
||||
Job *newj, *j;
|
||||
|
||||
if (free_jobs != NULL) {
|
||||
newj = free_jobs;
|
||||
|
@ -1766,7 +1766,7 @@ new_job(void)
|
|||
static Proc *
|
||||
new_proc(void)
|
||||
{
|
||||
Proc *p;
|
||||
Proc *p;
|
||||
|
||||
if (free_procs != NULL) {
|
||||
p = free_procs;
|
||||
|
@ -1786,10 +1786,9 @@ new_proc(void)
|
|||
static void
|
||||
remove_job(Job *j, const char *where)
|
||||
{
|
||||
Proc *p, *tmp;
|
||||
Job **prev, *curr;
|
||||
Proc *p, *tmp;
|
||||
Job **prev, *curr;
|
||||
|
||||
mkssert(j != NULL);
|
||||
prev = &job_list;
|
||||
curr = job_list;
|
||||
while (curr && curr != j) {
|
||||
|
@ -1830,9 +1829,8 @@ remove_job(Job *j, const char *where)
|
|||
static void
|
||||
put_job(Job *j, int where)
|
||||
{
|
||||
Job **prev, *curr;
|
||||
Job **prev, *curr;
|
||||
|
||||
mkssert(j != NULL);
|
||||
/* Remove job from list (if there) */
|
||||
prev = &job_list;
|
||||
curr = job_list;
|
||||
|
@ -1869,8 +1867,8 @@ put_job(Job *j, int where)
|
|||
static int
|
||||
kill_job(Job *j, int sig)
|
||||
{
|
||||
Proc *p;
|
||||
int rval = 0;
|
||||
Proc *p;
|
||||
int rval = 0;
|
||||
|
||||
for (p = j->proc_list; p != NULL; p = p->next)
|
||||
if (p->pid != 0)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*-
|
||||
* Copyright (c) 2009, 2010, 2011, 2013
|
||||
* Copyright (c) 2009, 2010, 2011, 2013, 2014
|
||||
* Thorsten Glaser <tg@mirbsd.org>
|
||||
*
|
||||
* Provided that these terms and disclaimer and all copyright notices
|
||||
|
@ -20,7 +20,7 @@
|
|||
|
||||
#include "sh.h"
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/lalloc.c,v 1.20 2013/06/03 22:28:33 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/lalloc.c,v 1.20.2.1 2015/01/25 15:35:47 tg Exp $");
|
||||
|
||||
/* build with CPPFLAGS+= -DUSE_REALLOC_MALLOC=0 on ancient systems */
|
||||
#if defined(USE_REALLOC_MALLOC) && (USE_REALLOC_MALLOC == 0)
|
||||
|
@ -29,7 +29,7 @@ __RCSID("$MirOS: src/bin/mksh/lalloc.c,v 1.20 2013/06/03 22:28:33 tg Exp $");
|
|||
#define remalloc(p,n) realloc_osi((p), (n))
|
||||
#endif
|
||||
|
||||
#define ALLOC_ISUNALIGNED(p) (((ptrdiff_t)(p)) % ALLOC_SIZE)
|
||||
#define ALLOC_ISUNALIGNED(p) (((size_t)(p)) % ALLOC_SIZE)
|
||||
|
||||
static ALLOC_ITEM *findptr(ALLOC_ITEM **, char *, Area *);
|
||||
|
||||
|
|
27
src/lex.c
27
src/lex.c
|
@ -23,7 +23,7 @@
|
|||
|
||||
#include "sh.h"
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.193 2014/06/29 11:28:28 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.193.2.1 2015/01/11 22:39:50 tg Exp $");
|
||||
|
||||
/*
|
||||
* states while lexing word
|
||||
|
@ -854,7 +854,7 @@ yylex(int cf)
|
|||
*dp = '\0';
|
||||
/* store the quoted string */
|
||||
*wp++ = OQUOTE;
|
||||
XcheckN(ws, wp, (dp - sp));
|
||||
XcheckN(ws, wp, (dp - sp) * 2);
|
||||
dp = sp;
|
||||
while ((c = *dp++)) {
|
||||
if (c == '\\') {
|
||||
|
@ -1027,17 +1027,24 @@ yylex(int cf)
|
|||
/* copy word to unprefixed string ident */
|
||||
sp = yylval.cp;
|
||||
dp = ident;
|
||||
if ((cf & HEREDELIM) && (sp[1] == '<'))
|
||||
while ((dp - ident) < IDENT) {
|
||||
if ((c = *sp++) == CHAR)
|
||||
*dp++ = *sp++;
|
||||
else if ((c != OQUOTE) && (c != CQUOTE))
|
||||
break;
|
||||
if ((cf & HEREDELIM) && (sp[1] == '<')) {
|
||||
herestringloop:
|
||||
switch ((c = *sp++)) {
|
||||
case CHAR:
|
||||
++sp;
|
||||
/* FALLTHROUGH */
|
||||
case OQUOTE:
|
||||
case CQUOTE:
|
||||
goto herestringloop;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
else
|
||||
/* dummy value */
|
||||
*dp++ = 'x';
|
||||
} else
|
||||
while ((dp - ident) < IDENT && (c = *sp++) == CHAR)
|
||||
*dp++ = *sp++;
|
||||
/* Make sure the ident array stays '\0' padded */
|
||||
/* make sure the ident array stays NUL padded */
|
||||
memset(dp, 0, (ident + IDENT) - dp + 1);
|
||||
if (c != EOS)
|
||||
/* word is not unquoted */
|
||||
|
|
15
src/main.c
15
src/main.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: main.c,v 1.54 2013/11/28 10:33:37 sobrado Exp $ */
|
||||
/* $OpenBSD: main.c,v 1.55 2015/02/09 09:09:30 jsg Exp $ */
|
||||
/* $OpenBSD: tty.c,v 1.10 2014/08/10 02:44:26 guenther Exp $ */
|
||||
/* $OpenBSD: io.c,v 1.25 2014/08/11 20:28:47 guenther Exp $ */
|
||||
/* $OpenBSD: table.c,v 1.15 2012/02/19 07:52:30 otto Exp $ */
|
||||
|
@ -34,7 +34,7 @@
|
|||
#include <locale.h>
|
||||
#endif
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.284 2014/10/03 17:19:27 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.285.2.2 2015/03/01 15:43:01 tg Exp $");
|
||||
|
||||
extern char **environ;
|
||||
|
||||
|
@ -892,6 +892,13 @@ unwind(int i)
|
|||
/* FALLTHROUGH */
|
||||
default:
|
||||
quitenv(NULL);
|
||||
/*
|
||||
* quitenv() may have reclaimed the memory
|
||||
* used by source which will end badly when
|
||||
* we jump to a function that expects it to
|
||||
* be valid
|
||||
*/
|
||||
source = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1014,8 +1021,6 @@ cleanup_parents_env(void)
|
|||
struct env *ep;
|
||||
int fd;
|
||||
|
||||
mkssert(e != NULL);
|
||||
|
||||
/*
|
||||
* Don't clean up temporary files - parent will probably need them.
|
||||
* Also, can't easily reclaim memory since variables, etc. could be
|
||||
|
@ -1244,7 +1249,7 @@ bi_errorf(const char *fmt, ...)
|
|||
* non-interactive shells to exit.
|
||||
* XXX odd use of KEEPASN; also may not want LERROR here
|
||||
*/
|
||||
if (builtin_flag & SPEC_BI) {
|
||||
if (builtin_spec) {
|
||||
builtin_argv0 = NULL;
|
||||
unwind(LERROR);
|
||||
}
|
||||
|
|
34
src/misc.c
34
src/misc.c
|
@ -1,9 +1,9 @@
|
|||
/* $OpenBSD: misc.c,v 1.38 2013/11/28 10:33:37 sobrado Exp $ */
|
||||
/* $OpenBSD: misc.c,v 1.39 2015/01/16 06:39:32 deraadt Exp $ */
|
||||
/* $OpenBSD: path.c,v 1.12 2005/03/30 17:16:37 deraadt Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||
* 2011, 2012, 2013, 2014
|
||||
* 2011, 2012, 2013, 2014, 2015
|
||||
* Thorsten Glaser <tg@mirbsd.org>
|
||||
*
|
||||
* Provided that these terms and disclaimer and all copyright notices
|
||||
|
@ -30,7 +30,7 @@
|
|||
#include <grp.h>
|
||||
#endif
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.219 2014/01/05 21:57:27 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.219.2.2 2015/03/01 15:43:02 tg Exp $");
|
||||
|
||||
#define KSH_CHVT_FLAG
|
||||
#ifdef MKSH_SMALL
|
||||
|
@ -281,15 +281,15 @@ change_flag(enum sh_flag f, int what, bool newset)
|
|||
#endif
|
||||
DO_SETUID(setresuid, (ksheuid, ksheuid, ksheuid));
|
||||
#else /* !HAVE_SETRESUGID */
|
||||
/* seteuid, setegid, setgid don't EAGAIN on Linux */
|
||||
#ifndef MKSH__NO_SETEUGID
|
||||
seteuid(ksheuid);
|
||||
#endif
|
||||
DO_SETUID(setuid, (ksheuid));
|
||||
/* setgid, setegid, seteuid don't EAGAIN on Linux */
|
||||
setgid(kshegid);
|
||||
#ifndef MKSH__NO_SETEUGID
|
||||
setegid(kshegid);
|
||||
#endif
|
||||
setgid(kshegid);
|
||||
DO_SETUID(setuid, (ksheuid));
|
||||
#ifndef MKSH__NO_SETEUGID
|
||||
seteuid(ksheuid);
|
||||
#endif
|
||||
#endif /* !HAVE_SETRESUGID */
|
||||
} else if ((f == FPOSIX || f == FSH) && newval) {
|
||||
/* Turning on -o posix or -o sh? */
|
||||
|
@ -304,6 +304,11 @@ change_flag(enum sh_flag f, int what, bool newset)
|
|||
void
|
||||
change_xtrace(unsigned char newval, bool dosnapshot)
|
||||
{
|
||||
static bool in_xtrace;
|
||||
|
||||
if (in_xtrace)
|
||||
return;
|
||||
|
||||
if (!dosnapshot && newval == Flag(FXTRACE))
|
||||
return;
|
||||
|
||||
|
@ -328,8 +333,13 @@ change_xtrace(unsigned char newval, bool dosnapshot)
|
|||
shl_xtrace->fd = 2;
|
||||
|
||||
changed_xtrace:
|
||||
if ((Flag(FXTRACE) = newval) == 2)
|
||||
if ((Flag(FXTRACE) = newval) == 2) {
|
||||
in_xtrace = true;
|
||||
Flag(FXTRACE) = 0;
|
||||
shf_puts(substitute(str_val(global("PS4")), 0), shl_xtrace);
|
||||
Flag(FXTRACE) = 2;
|
||||
in_xtrace = false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -485,7 +495,6 @@ parse_args(const char **argv,
|
|||
if (arrayset) {
|
||||
const char *ccp = NULL;
|
||||
|
||||
mkssert(array != NULL);
|
||||
if (*array)
|
||||
ccp = skip_varname(array, false);
|
||||
if (!ccp || !(!ccp[0] || (ccp[0] == '+' && !ccp[1]))) {
|
||||
|
@ -1384,8 +1393,7 @@ do_realpath(const char *upath)
|
|||
{
|
||||
char *xp, *ip, *tp, *ipath, *ldest = NULL;
|
||||
XString xs;
|
||||
ptrdiff_t pos;
|
||||
size_t len;
|
||||
size_t pos, len;
|
||||
int llen;
|
||||
struct stat sb;
|
||||
#ifdef MKSH__NO_PATH_MAX
|
||||
|
|
58
src/mksh.1
58
src/mksh.1
|
@ -1,9 +1,9 @@
|
|||
.\" $MirOS: src/bin/mksh/mksh.1,v 1.344 2014/10/07 15:30:12 tg Exp $
|
||||
.\" $OpenBSD: ksh.1,v 1.153 2014/08/17 07:15:41 jmc Exp $
|
||||
.\" $MirOS: src/bin/mksh/mksh.1,v 1.344.2.3 2015/03/01 15:43:03 tg Exp $
|
||||
.\" $OpenBSD: ksh.1,v 1.156 2015/01/16 15:32:32 schwarze Exp $
|
||||
.\"-
|
||||
.\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
|
||||
.\" 2010, 2011, 2012, 2013, 2014
|
||||
.\" Thorsten Glaser <tg@mirbsd.org>
|
||||
.\" 2010, 2011, 2012, 2013, 2014, 2015
|
||||
.\" Thorsten “mirabilos” Glaser <tg@mirbsd.org>
|
||||
.\"
|
||||
.\" Provided that these terms and disclaimer and all copyright notices
|
||||
.\" are retained or reproduced in an accompanying document, permission
|
||||
|
@ -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: October 7 2014 $
|
||||
.Dd $Mdocdate: March 1 2015 $
|
||||
.\"
|
||||
.\" Check which macro package we use, and do other -mdoc setup.
|
||||
.\"
|
||||
|
@ -673,11 +673,11 @@ are reserved words, not meta-characters.
|
|||
.It Xo case Ar word No in
|
||||
.Oo Op \&(
|
||||
.Ar pattern
|
||||
.Op \*(Ba Ar pat
|
||||
.Op \*(Ba Ar pattern
|
||||
.No ... Ns )
|
||||
.Ar list
|
||||
.Op ;; \*(Ba ;&\& \*(Ba ;\*(Ba\ \&
|
||||
.Oc ... esac
|
||||
.Ic terminator
|
||||
.Oc No ... esac
|
||||
.Xc
|
||||
The
|
||||
.Ic case
|
||||
|
@ -707,9 +707,11 @@ For historical reasons, open and close braces may be used instead of
|
|||
and
|
||||
.Ic esac
|
||||
e.g.\&
|
||||
.Ic case $foo { *) echo bar;; } .
|
||||
.Ic case $foo { *) echo bar ;; } .
|
||||
.Pp
|
||||
The list terminators are:
|
||||
The list
|
||||
.Ic terminator Ns s
|
||||
are:
|
||||
.Bl -tag -width 4n
|
||||
.It Ql ;;
|
||||
Terminate after the list.
|
||||
|
@ -2923,6 +2925,10 @@ trapped) will have their default effect in a function.
|
|||
.It
|
||||
The EXIT trap, if set in a function, will be executed after the function
|
||||
returns.
|
||||
.It
|
||||
Shell options
|
||||
.Pq Ic set Fl o
|
||||
have local scope, i.e. changes inside a function are reset upon its exit.
|
||||
.El
|
||||
.Ss Command execution
|
||||
After evaluation of command-line arguments, redirections, and parameter
|
||||
|
@ -3370,9 +3376,25 @@ string which the shell then parses and executes in the current environment.
|
|||
.Pp
|
||||
.It Xo
|
||||
.Ic exec
|
||||
.Op Fl a Ar argv0
|
||||
.Op Fl c
|
||||
.Op Ar command Op Ar arg ...
|
||||
.Xc
|
||||
The command is executed without forking, replacing the shell process.
|
||||
This is currently absolute, i.e.\&
|
||||
.Ic exec
|
||||
never returns, even if the
|
||||
.Ar command
|
||||
is not found.
|
||||
The
|
||||
.Fl a
|
||||
option permits setting a different
|
||||
.Li argv[0]
|
||||
value, and
|
||||
.Fl c
|
||||
clears the environment before executing the child process, except for the
|
||||
.Ev _
|
||||
variable and direct assignments.
|
||||
.Pp
|
||||
If no command is given except for I/O redirection, the I/O redirection is
|
||||
permanent and the shell is
|
||||
|
@ -6457,6 +6479,17 @@ If you require 64-bit integer arithmetics, use
|
|||
instead, but be aware that, in POSIX, it's legal for the OS to make
|
||||
.Li print $((2147483647 + 1))
|
||||
delete all files on your system, as it's Undefined Behaviour.
|
||||
.Pp
|
||||
.Nm mksh
|
||||
provides a consistent, clear interface normally.
|
||||
This may deviate from POSIX in optional or opinionated places, such
|
||||
as whether leading-digit-zero numbers should be interpreted as octal.
|
||||
.Ic set \-o posix
|
||||
will cause the shell (either
|
||||
.Nm mksh
|
||||
or
|
||||
.Nm lksh )
|
||||
to behave more like the standard expects.
|
||||
.Sh BUGS
|
||||
Suspending (using \*(haZ) pipelines like the one below will only suspend
|
||||
the currently running part of the pipeline; in this example,
|
||||
|
@ -6468,16 +6501,19 @@ $ /bin/sleep 666 && echo fubar
|
|||
.Ed
|
||||
.Pp
|
||||
This document attempts to describe
|
||||
.Nm mksh\ R50
|
||||
.Nm mksh\ R50e
|
||||
and up,
|
||||
compiled without any options impacting functionality, such as
|
||||
.Dv MKSH_SMALL ,
|
||||
when not called as
|
||||
.Pa /bin/sh
|
||||
which, on some systems only, enables
|
||||
.Ic set \-o posix
|
||||
or
|
||||
.Ic set \-o sh
|
||||
automatically (whose behaviour differs across targets),
|
||||
for an operating environment supporting all of its advanced needs.
|
||||
.Pp
|
||||
Please report bugs in
|
||||
.Nm
|
||||
to the
|
||||
|
|
22
src/sh.h
22
src/sh.h
|
@ -10,7 +10,7 @@
|
|||
|
||||
/*-
|
||||
* Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||
* 2011, 2012, 2013, 2014
|
||||
* 2011, 2012, 2013, 2014, 2015
|
||||
* Thorsten Glaser <tg@mirbsd.org>
|
||||
*
|
||||
* Provided that these terms and disclaimer and all copyright notices
|
||||
|
@ -169,9 +169,9 @@
|
|||
#endif
|
||||
|
||||
#ifdef EXTERN
|
||||
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.697 2014/10/07 15:22:17 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.701.2.4 2015/03/01 15:43:05 tg Exp $");
|
||||
#endif
|
||||
#define MKSH_VERSION "R50 2014/10/07"
|
||||
#define MKSH_VERSION "R50 2015/03/01"
|
||||
|
||||
/* arithmetic types: C implementation */
|
||||
#if !HAVE_CAN_INTTYPES
|
||||
|
@ -312,9 +312,13 @@ struct rusage {
|
|||
#undef PATH_MAX
|
||||
#else
|
||||
#ifndef PATH_MAX
|
||||
#ifdef MAXPATHLEN
|
||||
#define PATH_MAX MAXPATHLEN
|
||||
#else
|
||||
#define PATH_MAX 1024
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#ifndef SIZE_MAX
|
||||
#ifdef SIZE_T_MAX
|
||||
#define SIZE_MAX SIZE_T_MAX
|
||||
|
@ -533,7 +537,7 @@ char *ucstrstr(char *, const char *);
|
|||
#define mkssert(e) do { } while (/* CONSTCOND */ 0)
|
||||
#endif
|
||||
|
||||
#if (!defined(MKSH_BUILDMAKEFILE4BSD) && !defined(MKSH_BUILDSH)) || (MKSH_BUILD_R != 504)
|
||||
#if (!defined(MKSH_BUILDMAKEFILE4BSD) && !defined(MKSH_BUILDSH)) || (MKSH_BUILD_R != 505)
|
||||
#error Must run Build.sh to compile this.
|
||||
extern void thiswillneverbedefinedIhope(void);
|
||||
int
|
||||
|
@ -992,8 +996,8 @@ EXTERN sigset_t sm_default, sm_sigchld;
|
|||
|
||||
/* name of called builtin function (used by error functions) */
|
||||
EXTERN const char *builtin_argv0;
|
||||
/* flags of called builtin (SPEC_BI, etc.) */
|
||||
EXTERN uint32_t builtin_flag;
|
||||
/* is called builtin SPEC_BI? */
|
||||
EXTERN bool builtin_spec;
|
||||
|
||||
/* current working directory */
|
||||
EXTERN char *current_wd;
|
||||
|
@ -1233,6 +1237,7 @@ struct block {
|
|||
|
||||
/* Values for struct block.flags */
|
||||
#define BF_DOGETOPTS BIT(0) /* save/restore getopts state */
|
||||
#define BF_STOPENV BIT(1) /* do not export further */
|
||||
|
||||
/*
|
||||
* Used by ktwalk() and ktnext() routines.
|
||||
|
@ -1396,7 +1401,8 @@ struct ioword {
|
|||
#define DOVACHECK BIT(9) /* var assign check (for typeset, set, etc) */
|
||||
#define DOMARKDIRS BIT(10) /* force markdirs behaviour */
|
||||
#define DOTCOMEXEC BIT(11) /* not an eval flag, used by sh -c hack */
|
||||
#define DOASNFIELD BIT(12) /* is assignment, change field handling */
|
||||
#define DOSCALAR BIT(12) /* change field handling to non-list context */
|
||||
#define DOHEREDOC BIT(13) /* change scalar handling to heredoc body */
|
||||
|
||||
#define X_EXTRA 20 /* this many extra bytes in X string */
|
||||
|
||||
|
@ -1645,7 +1651,7 @@ char *evalonestr(const char *cp, int);
|
|||
char *debunk(char *, const char *, size_t);
|
||||
void expand(const char *, XPtrV *, int);
|
||||
int glob_str(char *, XPtrV *, bool);
|
||||
char *tilde(char *);
|
||||
char *do_tilde(char *);
|
||||
/* exec.c */
|
||||
int execute(struct op * volatile, volatile int, volatile int * volatile);
|
||||
int shcomexec(const char **);
|
||||
|
|
113
src/shf.c
113
src/shf.c
|
@ -2,7 +2,7 @@
|
|||
|
||||
/*-
|
||||
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011,
|
||||
* 2012, 2013
|
||||
* 2012, 2013, 2015
|
||||
* Thorsten Glaser <tg@mirbsd.org>
|
||||
*
|
||||
* Provided that these terms and disclaimer and all copyright notices
|
||||
|
@ -25,7 +25,7 @@
|
|||
|
||||
#include "sh.h"
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/shf.c,v 1.62 2013/10/09 11:59:30 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/shf.c,v 1.62.2.2 2015/03/01 15:43:07 tg Exp $");
|
||||
|
||||
/* flags to shf_emptybuf() */
|
||||
#define EB_READSW 0x01 /* about to switch to reading */
|
||||
|
@ -232,7 +232,7 @@ shf_close(struct shf *shf)
|
|||
if (shf->fd >= 0) {
|
||||
ret = shf_flush(shf);
|
||||
if (close(shf->fd) < 0)
|
||||
ret = EOF;
|
||||
ret = -1;
|
||||
}
|
||||
if (shf->flags & SHF_ALLOCS)
|
||||
afree(shf, shf->areap);
|
||||
|
@ -251,7 +251,7 @@ shf_fdclose(struct shf *shf)
|
|||
if (shf->fd >= 0) {
|
||||
ret = shf_flush(shf);
|
||||
if (close(shf->fd) < 0)
|
||||
ret = EOF;
|
||||
ret = -1;
|
||||
shf->rnleft = 0;
|
||||
shf->rp = shf->buf;
|
||||
shf->wnleft = 0;
|
||||
|
@ -283,20 +283,20 @@ shf_sclose(struct shf *shf)
|
|||
|
||||
/*
|
||||
* Un-read what has been read but not examined, or write what has been
|
||||
* buffered. Returns 0 for success, EOF for (write) error.
|
||||
* buffered. Returns 0 for success, -1 for (write) error.
|
||||
*/
|
||||
int
|
||||
shf_flush(struct shf *shf)
|
||||
{
|
||||
if (shf->flags & SHF_STRING)
|
||||
return ((shf->flags & SHF_WR) ? EOF : 0);
|
||||
return ((shf->flags & SHF_WR) ? -1 : 0);
|
||||
|
||||
if (shf->fd < 0)
|
||||
internal_errorf("%s: %s", "shf_flush", "no fd");
|
||||
|
||||
if (shf->flags & SHF_ERROR) {
|
||||
errno = shf->errnosv;
|
||||
return (EOF);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (shf->flags & SHF_READING) {
|
||||
|
@ -315,7 +315,7 @@ shf_flush(struct shf *shf)
|
|||
|
||||
/*
|
||||
* Write out any buffered data. If currently reading, flushes the read
|
||||
* buffer. Returns 0 for success, EOF for (write) error.
|
||||
* buffer. Returns 0 for success, -1 for (write) error.
|
||||
*/
|
||||
static int
|
||||
shf_emptybuf(struct shf *shf, int flags)
|
||||
|
@ -327,7 +327,7 @@ shf_emptybuf(struct shf *shf, int flags)
|
|||
|
||||
if (shf->flags & SHF_ERROR) {
|
||||
errno = shf->errnosv;
|
||||
return (EOF);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (shf->flags & SHF_READING) {
|
||||
|
@ -347,7 +347,7 @@ shf_emptybuf(struct shf *shf, int flags)
|
|||
*/
|
||||
if (!(flags & EB_GROW) || !(shf->flags & SHF_DYNAMIC) ||
|
||||
!(shf->flags & SHF_ALLOCB))
|
||||
return (EOF);
|
||||
return (-1);
|
||||
/* allocate more space for buffer */
|
||||
nbuf = aresize2(shf->buf, 2, shf->wbsize, shf->areap);
|
||||
shf->rp = nbuf + (shf->rp - shf->buf);
|
||||
|
@ -379,7 +379,7 @@ shf_emptybuf(struct shf *shf, int flags)
|
|||
ntowrite);
|
||||
shf->wp = shf->buf + ntowrite;
|
||||
}
|
||||
return (EOF);
|
||||
return (-1);
|
||||
}
|
||||
buf += n;
|
||||
ntowrite -= n;
|
||||
|
@ -399,7 +399,7 @@ shf_emptybuf(struct shf *shf, int flags)
|
|||
return (ret);
|
||||
}
|
||||
|
||||
/* Fill up a read buffer. Returns EOF for a read error, 0 otherwise. */
|
||||
/* Fill up a read buffer. Returns -1 for a read error, 0 otherwise. */
|
||||
static int
|
||||
shf_fillbuf(struct shf *shf)
|
||||
{
|
||||
|
@ -414,11 +414,11 @@ shf_fillbuf(struct shf *shf)
|
|||
if (shf->flags & (SHF_EOF | SHF_ERROR)) {
|
||||
if (shf->flags & SHF_ERROR)
|
||||
errno = shf->errnosv;
|
||||
return (EOF);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if ((shf->flags & SHF_WRITING) && shf_emptybuf(shf, EB_READSW) == EOF)
|
||||
return (EOF);
|
||||
if ((shf->flags & SHF_WRITING) && shf_emptybuf(shf, EB_READSW) == -1)
|
||||
return (-1);
|
||||
|
||||
shf->flags |= SHF_READING;
|
||||
|
||||
|
@ -434,7 +434,7 @@ shf_fillbuf(struct shf *shf)
|
|||
shf->errnosv = errno;
|
||||
shf->rnleft = 0;
|
||||
shf->rp = shf->buf;
|
||||
return (EOF);
|
||||
return (-1);
|
||||
}
|
||||
if ((shf->rnleft = n) == 0)
|
||||
shf->flags |= SHF_EOF;
|
||||
|
@ -443,7 +443,7 @@ shf_fillbuf(struct shf *shf)
|
|||
|
||||
/*
|
||||
* Read a buffer from shf. Returns the number of bytes read into buf, if
|
||||
* no bytes were read, returns 0 if end of file was seen, EOF if a read
|
||||
* no bytes were read, returns 0 if end of file was seen, -1 if a read
|
||||
* error occurred.
|
||||
*/
|
||||
ssize_t
|
||||
|
@ -459,7 +459,7 @@ shf_read(char *buf, ssize_t bsize, struct shf *shf)
|
|||
|
||||
while (bsize > 0) {
|
||||
if (shf->rnleft == 0 &&
|
||||
(shf_fillbuf(shf) == EOF || shf->rnleft == 0))
|
||||
(shf_fillbuf(shf) == -1 || shf->rnleft == 0))
|
||||
break;
|
||||
ncopy = shf->rnleft;
|
||||
if (ncopy > bsize)
|
||||
|
@ -471,12 +471,12 @@ shf_read(char *buf, ssize_t bsize, struct shf *shf)
|
|||
shf->rnleft -= ncopy;
|
||||
}
|
||||
/* Note: fread(3S) returns 0 for errors - this doesn't */
|
||||
return (orig_bsize == bsize ? (shf_error(shf) ? EOF : 0) :
|
||||
return (orig_bsize == bsize ? (shf_error(shf) ? -1 : 0) :
|
||||
orig_bsize - bsize);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read up to a newline or EOF. The newline is put in buf; buf is always
|
||||
* Read up to a newline or -1. The newline is put in buf; buf is always
|
||||
* NUL terminated. Returns NULL on read error or if nothing was read
|
||||
* before end of file, returns a pointer to the NUL byte in buf
|
||||
* otherwise.
|
||||
|
@ -498,7 +498,7 @@ shf_getse(char *buf, ssize_t bsize, struct shf *shf)
|
|||
--bsize;
|
||||
do {
|
||||
if (shf->rnleft == 0) {
|
||||
if (shf_fillbuf(shf) == EOF)
|
||||
if (shf_fillbuf(shf) == -1)
|
||||
return (NULL);
|
||||
if (shf->rnleft == 0) {
|
||||
*buf = '\0';
|
||||
|
@ -520,22 +520,22 @@ shf_getse(char *buf, ssize_t bsize, struct shf *shf)
|
|||
return (buf);
|
||||
}
|
||||
|
||||
/* Returns the char read. Returns EOF for error and end of file. */
|
||||
/* Returns the char read. Returns -1 for error and end of file. */
|
||||
int
|
||||
shf_getchar(struct shf *shf)
|
||||
{
|
||||
if (!(shf->flags & SHF_RD))
|
||||
internal_errorf("%s: flags 0x%X", "shf_getchar", shf->flags);
|
||||
|
||||
if (shf->rnleft == 0 && (shf_fillbuf(shf) == EOF || shf->rnleft == 0))
|
||||
return (EOF);
|
||||
if (shf->rnleft == 0 && (shf_fillbuf(shf) == -1 || shf->rnleft == 0))
|
||||
return (-1);
|
||||
--shf->rnleft;
|
||||
return (*shf->rp++);
|
||||
}
|
||||
|
||||
/*
|
||||
* Put a character back in the input stream. Returns the character if
|
||||
* successful, EOF if there is no room.
|
||||
* successful, -1 if there is no room.
|
||||
*/
|
||||
int
|
||||
shf_ungetc(int c, struct shf *shf)
|
||||
|
@ -543,12 +543,12 @@ shf_ungetc(int c, struct shf *shf)
|
|||
if (!(shf->flags & SHF_RD))
|
||||
internal_errorf("%s: flags 0x%X", "shf_ungetc", shf->flags);
|
||||
|
||||
if ((shf->flags & SHF_ERROR) || c == EOF ||
|
||||
if ((shf->flags & SHF_ERROR) || c == -1 ||
|
||||
(shf->rp == shf->buf && shf->rnleft))
|
||||
return (EOF);
|
||||
return (-1);
|
||||
|
||||
if ((shf->flags & SHF_WRITING) && shf_emptybuf(shf, EB_READSW) == EOF)
|
||||
return (EOF);
|
||||
if ((shf->flags & SHF_WRITING) && shf_emptybuf(shf, EB_READSW) == -1)
|
||||
return (-1);
|
||||
|
||||
if (shf->rp == shf->buf)
|
||||
shf->rp = shf->buf + shf->rbsize;
|
||||
|
@ -558,7 +558,7 @@ shf_ungetc(int c, struct shf *shf)
|
|||
* we don't want to modify a string.
|
||||
*/
|
||||
if ((int)(shf->rp[-1]) != c)
|
||||
return (EOF);
|
||||
return (-1);
|
||||
shf->flags &= ~SHF_EOF;
|
||||
shf->rp--;
|
||||
shf->rnleft++;
|
||||
|
@ -571,7 +571,7 @@ shf_ungetc(int c, struct shf *shf)
|
|||
}
|
||||
|
||||
/*
|
||||
* Write a character. Returns the character if successful, EOF if the
|
||||
* Write a character. Returns the character if successful, -1 if the
|
||||
* char could not be written.
|
||||
*/
|
||||
int
|
||||
|
@ -580,8 +580,8 @@ shf_putchar(int c, struct shf *shf)
|
|||
if (!(shf->flags & SHF_WR))
|
||||
internal_errorf("%s: flags 0x%X", "shf_putchar", shf->flags);
|
||||
|
||||
if (c == EOF)
|
||||
return (EOF);
|
||||
if (c == -1)
|
||||
return (-1);
|
||||
|
||||
if (shf->flags & SHF_UNBUF) {
|
||||
unsigned char cc = (unsigned char)c;
|
||||
|
@ -591,7 +591,7 @@ shf_putchar(int c, struct shf *shf)
|
|||
internal_errorf("%s: %s", "shf_putchar", "no fd");
|
||||
if (shf->flags & SHF_ERROR) {
|
||||
errno = shf->errnosv;
|
||||
return (EOF);
|
||||
return (-1);
|
||||
}
|
||||
while ((n = write(shf->fd, &cc, 1)) != 1)
|
||||
if (n < 0) {
|
||||
|
@ -600,12 +600,12 @@ shf_putchar(int c, struct shf *shf)
|
|||
continue;
|
||||
shf->flags |= SHF_ERROR;
|
||||
shf->errnosv = errno;
|
||||
return (EOF);
|
||||
return (-1);
|
||||
}
|
||||
} else {
|
||||
/* Flush deals with strings and sticky errors */
|
||||
if (shf->wnleft == 0 && shf_emptybuf(shf, EB_GROW) == EOF)
|
||||
return (EOF);
|
||||
if (shf->wnleft == 0 && shf_emptybuf(shf, EB_GROW) == -1)
|
||||
return (-1);
|
||||
shf->wnleft--;
|
||||
*shf->wp++ = c;
|
||||
}
|
||||
|
@ -614,19 +614,19 @@ shf_putchar(int c, struct shf *shf)
|
|||
}
|
||||
|
||||
/*
|
||||
* Write a string. Returns the length of the string if successful, EOF
|
||||
* Write a string. Returns the length of the string if successful, -1
|
||||
* if the string could not be written.
|
||||
*/
|
||||
ssize_t
|
||||
shf_puts(const char *s, struct shf *shf)
|
||||
{
|
||||
if (!s)
|
||||
return (EOF);
|
||||
return (-1);
|
||||
|
||||
return (shf_write(s, strlen(s), shf));
|
||||
}
|
||||
|
||||
/* Write a buffer. Returns nbytes if successful, EOF if there is an error. */
|
||||
/* Write a buffer. Returns nbytes if successful, -1 if there is an error. */
|
||||
ssize_t
|
||||
shf_write(const char *buf, ssize_t nbytes, struct shf *shf)
|
||||
{
|
||||
|
@ -653,13 +653,13 @@ shf_write(const char *buf, ssize_t nbytes, struct shf *shf)
|
|||
if (shf->flags & SHF_STRING) {
|
||||
/* resize buffer until there's enough space left */
|
||||
while (nbytes > shf->wnleft)
|
||||
if (shf_emptybuf(shf, EB_GROW) == EOF)
|
||||
return (EOF);
|
||||
if (shf_emptybuf(shf, EB_GROW) == -1)
|
||||
return (-1);
|
||||
/* then write everything into the buffer */
|
||||
} else {
|
||||
/* flush deals with sticky errors */
|
||||
if (shf_emptybuf(shf, EB_GROW) == EOF)
|
||||
return (EOF);
|
||||
if (shf_emptybuf(shf, EB_GROW) == -1)
|
||||
return (-1);
|
||||
/* write chunks larger than window size directly */
|
||||
if (nbytes > shf->wbsize) {
|
||||
ncopy = nbytes;
|
||||
|
@ -679,7 +679,7 @@ shf_write(const char *buf, ssize_t nbytes, struct shf *shf)
|
|||
* Note: fwrite(3) returns 0
|
||||
* for errors - this doesn't
|
||||
*/
|
||||
return (EOF);
|
||||
return (-1);
|
||||
}
|
||||
buf += n;
|
||||
ncopy -= n;
|
||||
|
@ -767,12 +767,7 @@ shf_vfprintf(struct shf *shf, const char *fmt, va_list args)
|
|||
ssize_t field, precision, len;
|
||||
unsigned long lnum;
|
||||
/* %#o produces the longest output */
|
||||
char numbuf[(8 * sizeof(long) + 2) / 3 + 1
|
||||
#ifdef DEBUG
|
||||
/* a NUL for LLVM/Clang scan-build */
|
||||
+ 1
|
||||
#endif
|
||||
];
|
||||
char numbuf[(8 * sizeof(long) + 2) / 3 + 1];
|
||||
/* this stuff for dealing with the buffer */
|
||||
ssize_t nwritten = 0;
|
||||
|
||||
|
@ -910,16 +905,6 @@ shf_vfprintf(struct shf *shf, const char *fmt, va_list args)
|
|||
integral:
|
||||
flags |= FL_NUMBER;
|
||||
cp = numbuf + sizeof(numbuf);
|
||||
#ifdef DEBUG
|
||||
/*
|
||||
* this is necessary so Clang 3.2 realises
|
||||
* utf_skipcols/shf_putc in the output loop
|
||||
* terminate; these values are always ASCII
|
||||
* so an out-of-bounds access cannot happen
|
||||
* but Clang doesn't know that
|
||||
*/
|
||||
*--cp = '\0';
|
||||
#endif
|
||||
|
||||
switch (c) {
|
||||
case 'd':
|
||||
|
@ -971,10 +956,6 @@ shf_vfprintf(struct shf *shf, const char *fmt, va_list args)
|
|||
}
|
||||
}
|
||||
len = numbuf + sizeof(numbuf) - (s = cp);
|
||||
#ifdef DEBUG
|
||||
/* see above comment for Clang 3.2 */
|
||||
--len;
|
||||
#endif
|
||||
if (flags & FL_DOT) {
|
||||
if (precision > len) {
|
||||
field = precision;
|
||||
|
@ -1068,7 +1049,7 @@ shf_vfprintf(struct shf *shf, const char *fmt, va_list args)
|
|||
}
|
||||
}
|
||||
|
||||
return (shf_error(shf) ? EOF : nwritten);
|
||||
return (shf_error(shf) ? -1 : nwritten);
|
||||
}
|
||||
|
||||
#if defined(MKSH_SMALL) && !defined(MKSH_SMALL_BUT_FAST)
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
#include "sh.h"
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.94 2014/01/05 21:57:29 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.94.2.1 2015/01/25 15:35:54 tg Exp $");
|
||||
|
||||
struct nesting_state {
|
||||
int start_token; /* token than began nesting (eg, FOR) */
|
||||
|
@ -196,10 +196,11 @@ synio(int cf)
|
|||
musthave(LWORD, ishere ? HEREDELIM : 0);
|
||||
if (ishere) {
|
||||
iop->delim = yylval.cp;
|
||||
if (*ident != 0)
|
||||
if (*ident != 0) {
|
||||
/* unquoted */
|
||||
gotnulldelim:
|
||||
iop->flag |= IOEVAL;
|
||||
}
|
||||
if (herep > &heres[HERES - 1])
|
||||
yyerror("too many %ss\n", "<<");
|
||||
*herep++ = iop;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
/*-
|
||||
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||
* 2011, 2012, 2013, 2014
|
||||
* 2011, 2012, 2013, 2014, 2015
|
||||
* Thorsten Glaser <tg@mirbsd.org>
|
||||
*
|
||||
* Provided that these terms and disclaimer and all copyright notices
|
||||
|
@ -28,7 +28,7 @@
|
|||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/var.c,v 1.183 2014/10/04 11:47:19 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/var.c,v 1.183.2.2 2015/03/01 15:43:07 tg Exp $");
|
||||
|
||||
/*-
|
||||
* Variables
|
||||
|
@ -308,7 +308,6 @@ local(const char *n, bool copy)
|
|||
* dereference namerefs; must come first
|
||||
*/
|
||||
n = array_index_calc(n, &array, &val);
|
||||
mkssert(n != NULL);
|
||||
h = hash(n);
|
||||
if (!ksh_isalphx(*n)) {
|
||||
vp = &vtemp;
|
||||
|
@ -679,8 +678,6 @@ exportprep(struct tbl *vp, const char *val)
|
|||
char *op = (vp->flag&ALLOC) ? vp->val.s : NULL;
|
||||
size_t namelen, vallen;
|
||||
|
||||
mkssert(val != NULL);
|
||||
|
||||
namelen = strlen(vp->name);
|
||||
vallen = strlen(val) + 1;
|
||||
|
||||
|
@ -1114,6 +1111,8 @@ makenv(void)
|
|||
}
|
||||
XPput(denv, vp->val.s);
|
||||
}
|
||||
if (l->flags & BF_STOPENV)
|
||||
break;
|
||||
}
|
||||
XPput(denv, NULL);
|
||||
return ((char **)XPclose(denv));
|
||||
|
|
Loading…
Reference in a new issue