mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-02-13 19:52:20 +00:00
Remove SHOPT_BASH; keep &> redir operator, '-o posix' option
On 16 June there was a call for volunteers to fix the bash compatibility mode; it has never successfully compiled in 93u+. Since no one showed up, it is now removed due to lack of interest. A couple of things are kept, which are now globally enabled: 1. The &>file redirection shorthand (for >file 2>&1). As a matter of fact, ksh93 already supported this natively, but only while running rc/profile/login scripts, and it issued a warning. This makse it globally available and removes the warning, bringing ksh93 in line with mksh, bash and zsh. 2. The '-o posix' standard compliance option. It is now enabled on startup if ksh is invoked as 'sh' or if the POSIXLY_CORRECT variable exists in the environment. To begin with, it disables the aforementioned &> redirection shorthand. Further compliance tweaks will be added in subsequent commits. The differences will be fairly minimal as ksh93 is mostly compliant already. In all changed files, code was removed that was compiled (more precisely, failed to compile/link) if the SHOPT_BASH preprocessor identifier was defined. Below are other changes worth mentioning: src/cmd/ksh93/sh/bash.c, src/cmd/ksh93/data/bash_pre_rc.sh: - Removed. src/cmd/ksh93/data/lexstates.c, src/cmd/ksh93/include/shlex.h, src/cmd/ksh93/sh/lex.c: - Globally enable &> redirection operator if SH_POSIX not active. - Remove warning that was issued when &> was used in rc scripts. src/cmd/ksh93/data/options.c, src/cmd/ksh93/include/defs.h, src/cmd/ksh93/sh/args.c: - Keep SH_POSIX option (-o posix). - Replace SH_TYPE_BASH shell type by SH_TYPE_POSIX. src/cmd/ksh93/sh/init.c: - sh_type(): Return SH_TYPE_POSIX shell type if ksh was invoked as sh (or rsh, restricted sh). - sh_init(): Enable posix option if the SH_TYPE_POSIX shell type was detected, or if the CONFORMANCE ast config variable was set to "standard" (which libast sets on init if POSIXLY_CORRECT exists in the environment). src/cmd/ksh93/tests/options.sh, src/cmd/ksh93/tests/io.sh: - Replace regression tests for &> and move to io.sh. Since &> is now for general use, no longer test in an rc script, and don't check that a warning is issued. Closes: #9 Progresses: #20
This commit is contained in:
parent
84331a96fc
commit
921bbcaeb7
25 changed files with 95 additions and 1148 deletions
12
NEWS
12
NEWS
|
@ -3,6 +3,18 @@ For full details, see the git log at: https://github.com/ksh93/ksh
|
||||||
|
|
||||||
Any uppercase BUG_* names are modernish shell bug IDs.
|
Any uppercase BUG_* names are modernish shell bug IDs.
|
||||||
|
|
||||||
|
2020-09-01:
|
||||||
|
|
||||||
|
- The bash-style '&>file' redirection shorthand (for '>file 2>&1') is now
|
||||||
|
always recognised and not only when running rc/profile init scripts. It no
|
||||||
|
longer issues a warning. This brings ksh93 in line with mksh, bash and zsh.
|
||||||
|
|
||||||
|
- A long-form shell option '-o posix' has been added, which implements a
|
||||||
|
mode for better compatibility with the POSIX standard. It is automatically
|
||||||
|
turned on if ksh is invoked under the name 'sh'.
|
||||||
|
For now, it:
|
||||||
|
* disables the &> redirection shorthand
|
||||||
|
|
||||||
2020-08-19:
|
2020-08-19:
|
||||||
|
|
||||||
- Sped up the 'read' command on most systems by 15-25%. Fixed a hanging bug
|
- Sped up the 'read' command on most systems by 15-25%. Fixed a hanging bug
|
||||||
|
|
|
@ -43,10 +43,6 @@ Directory layout:
|
||||||
fixes and new features since the original ksh93 release. The file
|
fixes and new features since the original ksh93 release. The file
|
||||||
COMPATIBILITY is a list of all known incompatibilities with ksh88.
|
COMPATIBILITY is a list of all known incompatibilities with ksh88.
|
||||||
|
|
||||||
The data/bash_pre_rc.sh is a startup script used when emulating
|
|
||||||
bash if the shell is compiled with SHOPT_BASH and the shell
|
|
||||||
is invoked as bash. The bash emulation is not complete.
|
|
||||||
|
|
||||||
Include directory:
|
Include directory:
|
||||||
1. argnod.h contains the type definitions for command
|
1. argnod.h contains the type definitions for command
|
||||||
nodes, io nodes, argument nodes, and for positional
|
nodes, io nodes, argument nodes, and for positional
|
||||||
|
@ -111,8 +107,7 @@ sh directory:
|
||||||
library and the interface to shell arithmetic.
|
library and the interface to shell arithmetic.
|
||||||
3. array.c contains the code for indexed and associative
|
3. array.c contains the code for indexed and associative
|
||||||
arrays.
|
arrays.
|
||||||
4. bash.c contains code used when compiling with SHOPT_BASH
|
4. (removed)
|
||||||
to add bash specific features such as shopt.
|
|
||||||
5. defs.c contains the data definitions for global symbols.
|
5. defs.c contains the data definitions for global symbols.
|
||||||
6. deparse.c contains code to generate shell script from
|
6. deparse.c contains code to generate shell script from
|
||||||
a parse tree.
|
a parse tree.
|
||||||
|
|
|
@ -20,7 +20,6 @@ SHOPT_ACCT == /* accounting */
|
||||||
SHOPT_ACCTFILE == /* per user accounting info */
|
SHOPT_ACCTFILE == /* per user accounting info */
|
||||||
SHOPT_AUDIT == 1 /* enable auditing per SHOPT_AUDITFILE */
|
SHOPT_AUDIT == 1 /* enable auditing per SHOPT_AUDITFILE */
|
||||||
SHOPT_AUDITFILE == "/etc/ksh_audit" /* auditing file */
|
SHOPT_AUDITFILE == "/etc/ksh_audit" /* auditing file */
|
||||||
SHOPT_BASH == /* bash compatibility code */
|
|
||||||
SHOPT_BGX == 1 /* one SIGCHLD trap per completed job */
|
SHOPT_BGX == 1 /* one SIGCHLD trap per completed job */
|
||||||
SHOPT_BRACEPAT == 1 /* C-shell {...,...} expansions (, required) */
|
SHOPT_BRACEPAT == 1 /* C-shell {...,...} expansions (, required) */
|
||||||
SHOPT_CMDLIB_HDR == /* -lcmd builtin list (<cmdlist.h>) */
|
SHOPT_CMDLIB_HDR == /* -lcmd builtin list (<cmdlist.h>) */
|
||||||
|
@ -98,11 +97,6 @@ if CC.HOSTTYPE == "win32*"
|
||||||
SHOPT_CRNL == 1 /* <cr><nl> is equivalent to <nl> */
|
SHOPT_CRNL == 1 /* <cr><nl> is equivalent to <nl> */
|
||||||
end
|
end
|
||||||
|
|
||||||
if SHOPT_BASH
|
|
||||||
BASH_HOSTTYPE == "$(CC.HOSTTYPE:S:/\.//)"
|
|
||||||
BASH_MACHTYPE == "$(BASH_HOSTTYPE)-unknown-$(CC.HOSTTYPE:B)"
|
|
||||||
end
|
|
||||||
|
|
||||||
/* use the following libraries only if they exist */
|
/* use the following libraries only if they exist */
|
||||||
LIBS_opt := +ljobs +li
|
LIBS_opt := +ljobs +li
|
||||||
|
|
||||||
|
@ -136,10 +130,6 @@ end
|
||||||
if SHOPT_VSH
|
if SHOPT_VSH
|
||||||
FILES_opt += vi.c
|
FILES_opt += vi.c
|
||||||
end
|
end
|
||||||
if SHOPT_BASH
|
|
||||||
FILES_opt += bash.c bash_pre_rc.c
|
|
||||||
SHOPT_HISTEXPAND == 1
|
|
||||||
end
|
|
||||||
if SHOPT_HISTEXPAND
|
if SHOPT_HISTEXPAND
|
||||||
FILES_opt += hexpand.c
|
FILES_opt += hexpand.c
|
||||||
end
|
end
|
||||||
|
@ -150,7 +140,7 @@ if SHOPT_X
|
||||||
LDFLAGS += -u _XtAppInitialize -L/usr/add-on/X11/lib
|
LDFLAGS += -u _XtAppInitialize -L/usr/add-on/X11/lib
|
||||||
end
|
end
|
||||||
|
|
||||||
:ALL: $(SH) $(SHCOMP) $(SHOPT_SUID_EXEC:+suid_exec) $(SHOPT_BASH:+bash$(RELEASE))
|
:ALL: $(SH) $(SHCOMP) $(SHOPT_SUID_EXEC:+suid_exec)
|
||||||
|
|
||||||
$(SH) :: sh.1 pmain.c $(LIBS_req)
|
$(SH) :: sh.1 pmain.c $(LIBS_req)
|
||||||
|
|
||||||
|
@ -191,19 +181,8 @@ $(FUNDIR) :INSTALLDIR: mode=+x dirs popd pushd
|
||||||
|
|
||||||
shcomp.o : _BLD_DLL= $(CC.HOSTTYPE:N=cygwin.*:??_BLD_shell=?)
|
shcomp.o : _BLD_DLL= $(CC.HOSTTYPE:N=cygwin.*:??_BLD_shell=?)
|
||||||
|
|
||||||
if SHOPT_BASH
|
|
||||||
|
|
||||||
bash$(RELEASE) :LINK: $(SH)
|
|
||||||
|
|
||||||
bash_pre_rc.c : bash_pre_rc.sh
|
|
||||||
echo "const char bash_pre_rc[] = " > $(<)
|
|
||||||
sed -e 's/\\/\\\\/g' -e 's/"/\\"/g' -e 's/'"'"'/\\'"'"'/g' -e 's/^[[:space:]]*\(.*\)$/\"\1\\n\"/' $(*) >> $(<)
|
|
||||||
echo ";" >> $(<)
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
:: math.tab syscall.s mamexec mamstate.c $(DOCFILES) \
|
:: math.tab syscall.s mamexec mamstate.c $(DOCFILES) \
|
||||||
bash.c bash_pre_rc.sh hexpand.c mkservice.c \
|
hexpand.c mkservice.c \
|
||||||
shopen.mk shopen.c
|
shopen.mk shopen.c
|
||||||
|
|
||||||
:: shtests \
|
:: shtests \
|
||||||
|
|
|
@ -645,7 +645,7 @@ prev ${PACKAGE_ast_INCLUDE}/ast.h implicit
|
||||||
done sh/main.c
|
done sh/main.c
|
||||||
meta main.o %.c>%.o sh/main.c main
|
meta main.o %.c>%.o sh/main.c main
|
||||||
prev sh/main.c
|
prev sh/main.c
|
||||||
exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${CCFLAGS.FORCE}?} ${DEBUG+-DDEBUG=${DEBUG}} ${SHOPT_TIMEOUT+-DSHOPT_TIMEOUT=${SHOPT_TIMEOUT}} ${SHOPT_ACCT+-DSHOPT_ACCT=${SHOPT_ACCT}} ${SH_DICT+-DSH_DICT=${SH_DICT}} ${SHOPT_SYSRC+-DSHOPT_SYSRC=${SHOPT_SYSRC}} ${SHOPT_BASH+-DSHOPT_BASH=${SHOPT_BASH}} ${SHOPT_REMOTE+-DSHOPT_REMOTE=${SHOPT_REMOTE}} ${SHOPT_OLDTERMIO+-DSHOPT_OLDTERMIO=${SHOPT_OLDTERMIO}} ${SHOPT_SPAWN+-DSHOPT_SPAWN=${SHOPT_SPAWN}} ${SH_CMDLIB_DIR+-DSH_CMDLIB_DIR=${SH_CMDLIB_DIR}} ${SHOPT_P_SUID+-DSHOPT_P_SUID=${SHOPT_P_SUID}} ${SHOPT_REGRESS+-DSHOPT_REGRESS=${SHOPT_REGRESS}} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -DSHOPT_BRACEPAT -D_API_ast=20100309 -D_PACKAGE_ast -DSHOPT_ESH -D_BLD_shell -DSHOPT_KIA -DSHOPT_MULTIBYTE -DSHOPT_PFSH -DSHOPT_BGX -DKSHELL -DSHOPT_SUID_EXEC -DSHOPT_STATS -DSHOPT_NAMESPACE -DSHOPT_HISTEXPAND -DERROR_CONTEXT_T=Error_context_t -DSHOPT_FIXEDARRAY -DSHOPT_DYNAMIC -c sh/main.c
|
exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${CCFLAGS.FORCE}?} ${DEBUG+-DDEBUG=${DEBUG}} ${SHOPT_TIMEOUT+-DSHOPT_TIMEOUT=${SHOPT_TIMEOUT}} ${SHOPT_ACCT+-DSHOPT_ACCT=${SHOPT_ACCT}} ${SH_DICT+-DSH_DICT=${SH_DICT}} ${SHOPT_SYSRC+-DSHOPT_SYSRC=${SHOPT_SYSRC}} ${SHOPT_REMOTE+-DSHOPT_REMOTE=${SHOPT_REMOTE}} ${SHOPT_OLDTERMIO+-DSHOPT_OLDTERMIO=${SHOPT_OLDTERMIO}} ${SHOPT_SPAWN+-DSHOPT_SPAWN=${SHOPT_SPAWN}} ${SH_CMDLIB_DIR+-DSH_CMDLIB_DIR=${SH_CMDLIB_DIR}} ${SHOPT_P_SUID+-DSHOPT_P_SUID=${SHOPT_P_SUID}} ${SHOPT_REGRESS+-DSHOPT_REGRESS=${SHOPT_REGRESS}} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -DSHOPT_BRACEPAT -D_API_ast=20100309 -D_PACKAGE_ast -DSHOPT_ESH -D_BLD_shell -DSHOPT_KIA -DSHOPT_MULTIBYTE -DSHOPT_PFSH -DSHOPT_BGX -DKSHELL -DSHOPT_SUID_EXEC -DSHOPT_STATS -DSHOPT_NAMESPACE -DSHOPT_HISTEXPAND -DERROR_CONTEXT_T=Error_context_t -DSHOPT_FIXEDARRAY -DSHOPT_DYNAMIC -c sh/main.c
|
||||||
done main.o generated
|
done main.o generated
|
||||||
make nvdisc.o
|
make nvdisc.o
|
||||||
make sh/nvdisc.c
|
make sh/nvdisc.c
|
||||||
|
@ -1101,7 +1101,7 @@ prev include/defs.h implicit
|
||||||
done sh/trestore.c
|
done sh/trestore.c
|
||||||
meta trestore.o %.c>%.o sh/trestore.c trestore
|
meta trestore.o %.c>%.o sh/trestore.c trestore
|
||||||
prev sh/trestore.c
|
prev sh/trestore.c
|
||||||
exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${CCFLAGS.FORCE}?} ${SHOPT_BASH+-DSHOPT_BASH=${SHOPT_BASH}} ${SHOPT_SYSRC+-DSHOPT_SYSRC=${SHOPT_SYSRC}} ${SHOPT_ACCT+-DSHOPT_ACCT=${SHOPT_ACCT}} ${SHOPT_SPAWN+-DSHOPT_SPAWN=${SHOPT_SPAWN}} ${SH_CMDLIB_DIR+-DSH_CMDLIB_DIR=${SH_CMDLIB_DIR}} ${SH_DICT+-DSH_DICT=${SH_DICT}} ${SHOPT_P_SUID+-DSHOPT_P_SUID=${SHOPT_P_SUID}} ${SHOPT_REGRESS+-DSHOPT_REGRESS=${SHOPT_REGRESS}} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_BLD_shell -DKSHELL -D_API_ast=20100309 -D_PACKAGE_ast -DSHOPT_SUID_EXEC -DSHOPT_BRACEPAT -DSHOPT_STATS -DSHOPT_NAMESPACE -DSHOPT_PFSH -DSHOPT_HISTEXPAND -DERROR_CONTEXT_T=Error_context_t -DSHOPT_FIXEDARRAY -DSHOPT_ESH -DSHOPT_MULTIBYTE -c sh/trestore.c
|
exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${CCFLAGS.FORCE}?} ${SHOPT_SYSRC+-DSHOPT_SYSRC=${SHOPT_SYSRC}} ${SHOPT_ACCT+-DSHOPT_ACCT=${SHOPT_ACCT}} ${SHOPT_SPAWN+-DSHOPT_SPAWN=${SHOPT_SPAWN}} ${SH_CMDLIB_DIR+-DSH_CMDLIB_DIR=${SH_CMDLIB_DIR}} ${SH_DICT+-DSH_DICT=${SH_DICT}} ${SHOPT_P_SUID+-DSHOPT_P_SUID=${SHOPT_P_SUID}} ${SHOPT_REGRESS+-DSHOPT_REGRESS=${SHOPT_REGRESS}} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_BLD_shell -DKSHELL -D_API_ast=20100309 -D_PACKAGE_ast -DSHOPT_SUID_EXEC -DSHOPT_BRACEPAT -DSHOPT_STATS -DSHOPT_NAMESPACE -DSHOPT_PFSH -DSHOPT_HISTEXPAND -DERROR_CONTEXT_T=Error_context_t -DSHOPT_FIXEDARRAY -DSHOPT_ESH -DSHOPT_MULTIBYTE -c sh/trestore.c
|
||||||
done trestore.o generated
|
done trestore.o generated
|
||||||
make waitevent.o
|
make waitevent.o
|
||||||
make sh/waitevent.c
|
make sh/waitevent.c
|
||||||
|
@ -1189,7 +1189,7 @@ prev ${PACKAGE_ast_INCLUDE}/ast_standards.h implicit
|
||||||
done data/strdata.c
|
done data/strdata.c
|
||||||
meta strdata.o %.c>%.o data/strdata.c strdata
|
meta strdata.o %.c>%.o data/strdata.c strdata
|
||||||
prev data/strdata.c
|
prev data/strdata.c
|
||||||
exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${CCFLAGS.FORCE}?} ${SHOPT_BASH+-DSHOPT_BASH=${SHOPT_BASH}} ${SH_CMDLIB_DIR+-DSH_CMDLIB_DIR=${SH_CMDLIB_DIR}} ${SH_DICT+-DSH_DICT=${SH_DICT}} ${SHOPT_P_SUID+-DSHOPT_P_SUID=${SHOPT_P_SUID}} ${SHOPT_REGRESS+-DSHOPT_REGRESS=${SHOPT_REGRESS}} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -DSHOPT_STATS -DSHOPT_NAMESPACE -DSHOPT_PFSH -DSHOPT_HISTEXPAND -D_BLD_shell -D_API_ast=20100309 -D_PACKAGE_ast -DERROR_CONTEXT_T=Error_context_t -DSHOPT_FIXEDARRAY -DSHOPT_ESH -DSHOPT_MULTIBYTE -c data/strdata.c
|
exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${CCFLAGS.FORCE}?} ${SH_CMDLIB_DIR+-DSH_CMDLIB_DIR=${SH_CMDLIB_DIR}} ${SH_DICT+-DSH_DICT=${SH_DICT}} ${SHOPT_P_SUID+-DSHOPT_P_SUID=${SHOPT_P_SUID}} ${SHOPT_REGRESS+-DSHOPT_REGRESS=${SHOPT_REGRESS}} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -DSHOPT_STATS -DSHOPT_NAMESPACE -DSHOPT_PFSH -DSHOPT_HISTEXPAND -D_BLD_shell -D_API_ast=20100309 -D_PACKAGE_ast -DERROR_CONTEXT_T=Error_context_t -DSHOPT_FIXEDARRAY -DSHOPT_ESH -DSHOPT_MULTIBYTE -c data/strdata.c
|
||||||
done strdata.o generated
|
done strdata.o generated
|
||||||
make testops.o
|
make testops.o
|
||||||
make data/testops.c
|
make data/testops.c
|
||||||
|
|
|
@ -1,255 +0,0 @@
|
||||||
########################################################################
|
|
||||||
# #
|
|
||||||
# This software is part of the ast package #
|
|
||||||
# Copyright (c) 1982-2011 AT&T Intellectual Property #
|
|
||||||
# and is licensed under the #
|
|
||||||
# Eclipse Public License, Version 1.0 #
|
|
||||||
# by AT&T Intellectual Property #
|
|
||||||
# #
|
|
||||||
# A copy of the License is available at #
|
|
||||||
# http://www.eclipse.org/org/documents/epl-v10.html #
|
|
||||||
# (with md5 checksum b35adb5213ca9657e911e9befb180842) #
|
|
||||||
# #
|
|
||||||
# Information and Software Systems Research #
|
|
||||||
# AT&T Research #
|
|
||||||
# Florham Park NJ #
|
|
||||||
# #
|
|
||||||
# David Korn <dgk@research.att.com> #
|
|
||||||
# #
|
|
||||||
########################################################################
|
|
||||||
#
|
|
||||||
# bash compatibility startup script
|
|
||||||
#
|
|
||||||
# Author:
|
|
||||||
# Karsten Fleischer
|
|
||||||
# Omnium Software Engineering
|
|
||||||
# An der Luisenburg 7
|
|
||||||
# D-51379 Leverkusen
|
|
||||||
# Germany
|
|
||||||
#
|
|
||||||
# <K.Fleischer@omnium.de>
|
|
||||||
#
|
|
||||||
|
|
||||||
alias declare=typeset
|
|
||||||
|
|
||||||
nameref FUNCNAME=.sh.fun
|
|
||||||
integer SHLVL
|
|
||||||
export SHLVL
|
|
||||||
SHLVL+=1
|
|
||||||
|
|
||||||
if [[ ! $EUID ]]
|
|
||||||
then EUID=$(id -u)
|
|
||||||
readonly EUID
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ ! $UID ]]
|
|
||||||
then UID=$(id -u)
|
|
||||||
readonly UID
|
|
||||||
fi
|
|
||||||
|
|
||||||
readonly SHELLOPTS
|
|
||||||
if ! shopt -qo restricted; then
|
|
||||||
IFS=:
|
|
||||||
for i in $SHELLOPTS
|
|
||||||
do
|
|
||||||
[[ -n "$i" ]] && set -o $i
|
|
||||||
done
|
|
||||||
unset IFS
|
|
||||||
fi
|
|
||||||
function SHELLOPTS.get
|
|
||||||
{
|
|
||||||
.sh.value=$(shopt -so)
|
|
||||||
.sh.value=${.sh.value//+([[:space:]])on*([[:space:]])/:}
|
|
||||||
.sh.value=${.sh.value%:}
|
|
||||||
}
|
|
||||||
|
|
||||||
set -A GROUPS $(id -G)
|
|
||||||
function GROUPS.set
|
|
||||||
{
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
function GROUPS.unset
|
|
||||||
{
|
|
||||||
unset -f GROUPS.set
|
|
||||||
unset -f GROUPS.unset
|
|
||||||
}
|
|
||||||
|
|
||||||
typeset -A DIRSTACK
|
|
||||||
function DIRSTACK.get
|
|
||||||
{
|
|
||||||
set -A .sh.value $(dirs)
|
|
||||||
}
|
|
||||||
function DIRSTACK.set
|
|
||||||
{
|
|
||||||
integer index
|
|
||||||
index=_push_max-.sh.subscript
|
|
||||||
(( index == _push_max || index < _push_top )) && return
|
|
||||||
_push_stack[index]=${.sh.value}
|
|
||||||
}
|
|
||||||
function DIRSTACK.unset
|
|
||||||
{
|
|
||||||
unset -f DIRSTACK.get
|
|
||||||
unset -f DIRSTACK.set
|
|
||||||
unset -f DIRSTACK.unset
|
|
||||||
}
|
|
||||||
|
|
||||||
function PS1.set
|
|
||||||
{
|
|
||||||
typeset prefix remaining=${.sh.value} var= n= k=
|
|
||||||
while [[ $remaining ]]
|
|
||||||
do prefix=${remaining%%'\'*}
|
|
||||||
remaining=${remaining#$prefix}
|
|
||||||
var+="$prefix"
|
|
||||||
case ${remaining:1:1} in
|
|
||||||
t) var+="\$(printf '%(%H:%M:%S)T')";;
|
|
||||||
d) var+="\$(printf '%(%a %b:%e)T')";;
|
|
||||||
n) var+=$'\n';;
|
|
||||||
s) var+=ksh;;
|
|
||||||
w) var+="\$(pwd)";;
|
|
||||||
W) var+="\$(basename \"\$(pwd)\")";;
|
|
||||||
u) var+=$USER;;
|
|
||||||
h) var+=$(hostname -s);;
|
|
||||||
'#') var+=!;;
|
|
||||||
!) var+=!;;
|
|
||||||
@) var+="\$(printf '%(%I:%M%p)T')";;
|
|
||||||
'$') if (( $(id -u) == 0 ))
|
|
||||||
then var+='#'
|
|
||||||
else var+='$'
|
|
||||||
fi;;
|
|
||||||
'\') var+='\\';;
|
|
||||||
'['|']') ;;
|
|
||||||
[0-7]) case ${remaining:1:3} in
|
|
||||||
[0-7][0-7][0-7])
|
|
||||||
k=4;;
|
|
||||||
[0-7][0-7])
|
|
||||||
k=3;;
|
|
||||||
*) k=2;;
|
|
||||||
esac
|
|
||||||
eval n="\$'"${remaining:0:k}"'"
|
|
||||||
var+=$n
|
|
||||||
remaining=${remaining:k}
|
|
||||||
continue
|
|
||||||
;;
|
|
||||||
"") ;;
|
|
||||||
*) var+='\'${remaining:0:2};;
|
|
||||||
esac
|
|
||||||
remaining=${remaining:2}
|
|
||||||
done
|
|
||||||
.sh.value=$var
|
|
||||||
}
|
|
||||||
function logout
|
|
||||||
{
|
|
||||||
if shopt -q login_shell; then
|
|
||||||
exit
|
|
||||||
else
|
|
||||||
print ${BASH##*/}: $0: not login shell: use 'exit' >&2
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
PS1="bash$ "
|
|
||||||
|
|
||||||
function source
|
|
||||||
{
|
|
||||||
if ! shopt -qpo posix; then
|
|
||||||
unset OPATH
|
|
||||||
typeset OPATH=$PATH
|
|
||||||
typeset PATH=$PATH
|
|
||||||
if shopt -q sourcepath; then
|
|
||||||
PATH=$OPATH:.
|
|
||||||
else
|
|
||||||
PATH=.
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
. "$@"
|
|
||||||
}
|
|
||||||
unalias .
|
|
||||||
alias .=source
|
|
||||||
|
|
||||||
alias enable=builtin
|
|
||||||
|
|
||||||
function help
|
|
||||||
{
|
|
||||||
typeset b cmd usage try_cmd man
|
|
||||||
function has_help_option
|
|
||||||
{
|
|
||||||
[[ $1 == @(''|/*|:|echo|false|true|login|test|'[') ]] && return 1
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
typeset -A short_use=(
|
|
||||||
[echo]='Usage: echo [ options ] [arg]...'
|
|
||||||
[:]='Usage: : ...'
|
|
||||||
[true]='Usage: true ...'
|
|
||||||
[false]='Usage: false ...'
|
|
||||||
[login]='Usage: login [-p] [name]'
|
|
||||||
['[']='Usage: [ EXPRESSION ] | [ OPTION'
|
|
||||||
[test]='Usage: test EXPRESSION | test'
|
|
||||||
)
|
|
||||||
b=$(builtin)
|
|
||||||
if (( $# == 0))
|
|
||||||
then print 'The following is the current list of built-in commands:'
|
|
||||||
print -r $'Type help *name* for more information about name\n'
|
|
||||||
for cmd in $b
|
|
||||||
do if has_help_option $cmd
|
|
||||||
then usage=$($cmd --short 2>&1)
|
|
||||||
print -r -- "${usage:7}"
|
|
||||||
else print -r -- ${short_use[$cmd]:7}
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
b=${b/'['/}
|
|
||||||
man=--man
|
|
||||||
[[ $1 == -s ]] && man=--short && shift
|
|
||||||
for try_cmd
|
|
||||||
do if has_help_option $try_cmd
|
|
||||||
then if [[ $try_cmd == @(${b//$'\n'/'|'}) ]]
|
|
||||||
then $try_cmd $man
|
|
||||||
else man $try_cmd
|
|
||||||
fi
|
|
||||||
elif [[ $man == '--short' ]]
|
|
||||||
then print -r -- ${short_use[$try_cmd]}
|
|
||||||
else man $try_cmd
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
function cd
|
|
||||||
{
|
|
||||||
|
|
||||||
local msg
|
|
||||||
local args
|
|
||||||
local i
|
|
||||||
local a
|
|
||||||
local ret
|
|
||||||
|
|
||||||
if ! shopt -q cdable_vars; then
|
|
||||||
command cd "$@"
|
|
||||||
else
|
|
||||||
msg=$(command cd "$@" 2>&1)
|
|
||||||
ret=$?
|
|
||||||
if [[ $ret != 0 ]]; then
|
|
||||||
for i
|
|
||||||
do
|
|
||||||
case $i in
|
|
||||||
-*) args="$args $i" ;;
|
|
||||||
*/*) args="$args $i" ;;
|
|
||||||
*) eval a="$"$i
|
|
||||||
if [[ -n $a ]]; then args="$args $a"
|
|
||||||
else args="$args $i"
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
command cd $args
|
|
||||||
else
|
|
||||||
print -- $msg
|
|
||||||
return $ret
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
typeset BASH=$0
|
|
||||||
! shopt -qo posix && HISTFILE=~/.bash_history
|
|
||||||
HOSTNAME=$(hostname)
|
|
||||||
nameref BASH_SUBSHELL=.sh.subshell
|
|
|
@ -54,7 +54,6 @@
|
||||||
/*
|
/*
|
||||||
* IMPORTANT: The order of these struct members must be synchronous
|
* IMPORTANT: The order of these struct members must be synchronous
|
||||||
* with the offsets on the macros defined in include/builtins.h!
|
* with the offsets on the macros defined in include/builtins.h!
|
||||||
* The order up through "local" is significant.
|
|
||||||
*/
|
*/
|
||||||
const struct shtable3 shtab_builtins[] =
|
const struct shtable3 shtab_builtins[] =
|
||||||
{
|
{
|
||||||
|
@ -81,9 +80,6 @@ const struct shtable3 shtab_builtins[] =
|
||||||
".", NV_BLTIN|BLT_ENV|BLT_SPC, bltin(dot_cmd),
|
".", NV_BLTIN|BLT_ENV|BLT_SPC, bltin(dot_cmd),
|
||||||
"source", NV_BLTIN|BLT_ENV, bltin(dot_cmd),
|
"source", NV_BLTIN|BLT_ENV, bltin(dot_cmd),
|
||||||
"return", NV_BLTIN|BLT_ENV|BLT_SPC, bltin(return),
|
"return", NV_BLTIN|BLT_ENV|BLT_SPC, bltin(return),
|
||||||
#if SHOPT_BASH
|
|
||||||
"local", NV_BLTIN|BLT_ENV|BLT_SPC|BLT_DCL,bltin(typeset),
|
|
||||||
#endif
|
|
||||||
/*
|
/*
|
||||||
* Builtins without offset macros in include/builtins.h follow.
|
* Builtins without offset macros in include/builtins.h follow.
|
||||||
*/
|
*/
|
||||||
|
@ -220,13 +216,6 @@ const char sh_set[] =
|
||||||
"[+gmacs?Enables/disables \bgmacs\b editing mode. \bgmacs\b "
|
"[+gmacs?Enables/disables \bgmacs\b editing mode. \bgmacs\b "
|
||||||
"editing mode is the same as \bemacs\b editing mode "
|
"editing mode is the same as \bemacs\b editing mode "
|
||||||
"except for the handling of \b^T\b.]"
|
"except for the handling of \b^T\b.]"
|
||||||
#if SHOPT_BASH
|
|
||||||
"[+hashall?Equivalent to \b-h\b and \b-o trackall\b. Available "
|
|
||||||
"in bash compatibility mode only.]"
|
|
||||||
"[+history?Enable command history. Available in bash "
|
|
||||||
"compatibility mode only. On by default in interactive "
|
|
||||||
"shells.]"
|
|
||||||
#endif
|
|
||||||
#if SHOPT_HISTEXPAND
|
#if SHOPT_HISTEXPAND
|
||||||
"[+histexpand?Equivalent to \b-H\b.]"
|
"[+histexpand?Equivalent to \b-H\b.]"
|
||||||
#endif
|
#endif
|
||||||
|
@ -247,20 +236,12 @@ const char sh_set[] =
|
||||||
"compatibility.]"
|
"compatibility.]"
|
||||||
"[+notify?Equivalent to \b-b\b.]"
|
"[+notify?Equivalent to \b-b\b.]"
|
||||||
"[+nounset?Equivalent to \b-u\b.]"
|
"[+nounset?Equivalent to \b-u\b.]"
|
||||||
#if SHOPT_BASH
|
|
||||||
"[+onecmd?Equivalent to \b-t\b. Available in bash compatibility "
|
|
||||||
"mode only.]"
|
|
||||||
"[+physical?Equivalent to \b-P\b. Available in bash "
|
|
||||||
"compatibility mode only.]"
|
|
||||||
"[+posix?Turn on POSIX compatibility. Available in bash "
|
|
||||||
"compatibility mode only. Bash in POSIX mode is not the "
|
|
||||||
"same as ksh.]"
|
|
||||||
#endif
|
|
||||||
"[+pipefail?A pipeline will not complete until all components "
|
"[+pipefail?A pipeline will not complete until all components "
|
||||||
"of the pipeline have completed, and the exit status "
|
"of the pipeline have completed, and the exit status "
|
||||||
"of the pipeline will be the value of the last "
|
"of the pipeline will be the value of the last "
|
||||||
"command to exit with non-zero exit status, or will "
|
"command to exit with non-zero exit status, or will "
|
||||||
"be zero if all commands return zero exit status.]"
|
"be zero if all commands return zero exit status.]"
|
||||||
|
"[+posix?Enable POSIX standard compatibility mode.]"
|
||||||
"[+privileged?Equivalent to \b-p\b.]"
|
"[+privileged?Equivalent to \b-p\b.]"
|
||||||
"[+rc?Do not run the \b.kshrc\b file for interactive shells.]"
|
"[+rc?Do not run the \b.kshrc\b file for interactive shells.]"
|
||||||
"[+showme?Simple commands preceded by a \b;\b will be traced "
|
"[+showme?Simple commands preceded by a \b;\b will be traced "
|
||||||
|
@ -289,9 +270,6 @@ const char sh_set[] =
|
||||||
"[x?Execution trace. The shell will display each command after all "
|
"[x?Execution trace. The shell will display each command after all "
|
||||||
"expansion and before execution preceded by the expanded value "
|
"expansion and before execution preceded by the expanded value "
|
||||||
"of the \bPS4\b parameter.]"
|
"of the \bPS4\b parameter.]"
|
||||||
#if SHOPT_BASH
|
|
||||||
"\fbash1\f"
|
|
||||||
#endif
|
|
||||||
#if SHOPT_BRACEPAT
|
#if SHOPT_BRACEPAT
|
||||||
"[B?Enable {...} group expansion. On by default.]"
|
"[B?Enable {...} group expansion. On by default.]"
|
||||||
#endif
|
#endif
|
||||||
|
@ -1569,9 +1547,6 @@ USAGE_LICENSE
|
||||||
"[I:regress]:[intercept?Enable the regression test \aintercept\a. Must be "
|
"[I:regress]:[intercept?Enable the regression test \aintercept\a. Must be "
|
||||||
"the first command line option(s).]"
|
"the first command line option(s).]"
|
||||||
#endif
|
#endif
|
||||||
#if SHOPT_BASH
|
|
||||||
"\fbash2\f"
|
|
||||||
#endif
|
|
||||||
"\fabc\f"
|
"\fabc\f"
|
||||||
"?"
|
"?"
|
||||||
"[T?Enable implementation specific test code defined by mask.]#[mask]"
|
"[T?Enable implementation specific test code defined by mask.]#[mask]"
|
||||||
|
|
|
@ -402,7 +402,6 @@ const char e_lexobsolete3[] = "line %d: '=' obsolete, use '=='";
|
||||||
const char e_lexobsolete4[] = "line %d: %s within [[...]] obsolete, use ((...))";
|
const char e_lexobsolete4[] = "line %d: %s within [[...]] obsolete, use ((...))";
|
||||||
const char e_lexobsolete5[] = "line %d: set %s obsolete";
|
const char e_lexobsolete5[] = "line %d: set %s obsolete";
|
||||||
const char e_lexobsolete6[] = "line %d: `{' instead of `in' is obsolete";
|
const char e_lexobsolete6[] = "line %d: `{' instead of `in' is obsolete";
|
||||||
const char e_lexnonstandard[] = "line %d: `&>file' is nonstandard -- interpreted as `>file 2>&1' for profile input only";
|
|
||||||
const char e_lexusebrace[] = "line %d: use braces to avoid ambiguities with $id[...]";
|
const char e_lexusebrace[] = "line %d: use braces to avoid ambiguities with $id[...]";
|
||||||
const char e_lexusequote[] = "line %d: %c within ${} should be quoted";
|
const char e_lexusequote[] = "line %d: %c within ${} should be quoted";
|
||||||
const char e_lexescape[] = "line %d: escape %c to avoid ambiguities";
|
const char e_lexescape[] = "line %d: escape %c to avoid ambiguities";
|
||||||
|
|
|
@ -187,15 +187,6 @@ const char e_suidprofile[] = "/etc/suid_profile";
|
||||||
#if SHOPT_SYSRC
|
#if SHOPT_SYSRC
|
||||||
const char e_sysrc[] = "/etc/ksh.kshrc";
|
const char e_sysrc[] = "/etc/ksh.kshrc";
|
||||||
#endif
|
#endif
|
||||||
#if SHOPT_BASH
|
|
||||||
#if SHOPT_SYSRC
|
|
||||||
const char e_bash_sysrc[] = "/etc/bash.bashrc";
|
|
||||||
#endif
|
|
||||||
const char e_bash_rc[] = "$HOME/.bashrc";
|
|
||||||
const char e_bash_login[] = "$HOME/.bash_login";
|
|
||||||
const char e_bash_logout[] = "$HOME/.bash_logout";
|
|
||||||
const char e_bash_profile[] = "$HOME/.bash_profile";
|
|
||||||
#endif
|
|
||||||
const char e_crondir[] = "/usr/spool/cron/atjobs";
|
const char e_crondir[] = "/usr/spool/cron/atjobs";
|
||||||
const char e_prohibited[] = "login setuid/setgid shells prohibited";
|
const char e_prohibited[] = "login setuid/setgid shells prohibited";
|
||||||
#ifdef BUILD_DTKSH
|
#ifdef BUILD_DTKSH
|
||||||
|
|
|
@ -23,14 +23,6 @@
|
||||||
#include "name.h"
|
#include "name.h"
|
||||||
#include "shtable.h"
|
#include "shtable.h"
|
||||||
|
|
||||||
#if SHOPT_BASH
|
|
||||||
# define bashopt(a,b) a, b|SH_BASHOPT,
|
|
||||||
# define bashextra(a,b) a, b|SH_BASHEXTRA,
|
|
||||||
#else
|
|
||||||
# define bashopt(a,b)
|
|
||||||
# define bashextra(a,b)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is the list of invocation and set options
|
* This is the list of invocation and set options
|
||||||
* This list must be in in ascii sorted order
|
* This list must be in in ascii sorted order
|
||||||
|
@ -39,83 +31,42 @@
|
||||||
const Shtable_t shtab_options[] =
|
const Shtable_t shtab_options[] =
|
||||||
{
|
{
|
||||||
"allexport", SH_ALLEXPORT,
|
"allexport", SH_ALLEXPORT,
|
||||||
#if SHOPT_BASH
|
|
||||||
"bash", (SH_BASH|SH_COMMANDLINE),
|
|
||||||
#endif
|
|
||||||
"bgnice", SH_BGNICE,
|
"bgnice", SH_BGNICE,
|
||||||
"braceexpand", SH_BRACEEXPAND,
|
"braceexpand", SH_BRACEEXPAND,
|
||||||
bashopt("cdable_vars", SH_CDABLE_VARS)
|
|
||||||
bashopt("cdspell", SH_CDSPELL)
|
|
||||||
bashopt("checkhash", SH_CHECKHASH)
|
|
||||||
bashopt("checkwinsize", SH_CHECKWINSIZE)
|
|
||||||
"noclobber", SH_NOCLOBBER,
|
"noclobber", SH_NOCLOBBER,
|
||||||
bashopt("dotglob", SH_DOTGLOB)
|
|
||||||
"emacs", SH_EMACS,
|
"emacs", SH_EMACS,
|
||||||
"errexit", SH_ERREXIT,
|
"errexit", SH_ERREXIT,
|
||||||
"noexec", SH_NOEXEC,
|
"noexec", SH_NOEXEC,
|
||||||
bashopt("execfail", SH_EXECFAIL)
|
|
||||||
bashopt("expand_aliases", SH_EXPAND_ALIASES)
|
|
||||||
bashopt("extglob", SH_EXTGLOB)
|
|
||||||
"noglob", SH_NOGLOB,
|
"noglob", SH_NOGLOB,
|
||||||
"globstar", SH_GLOBSTARS,
|
"globstar", SH_GLOBSTARS,
|
||||||
"gmacs", SH_GMACS,
|
"gmacs", SH_GMACS,
|
||||||
bashextra("hashall", SH_TRACKALL)
|
|
||||||
bashopt("histappend", SH_HISTAPPEND)
|
|
||||||
#if SHOPT_HISTEXPAND
|
#if SHOPT_HISTEXPAND
|
||||||
"histexpand", SH_HISTEXPAND,
|
"histexpand", SH_HISTEXPAND,
|
||||||
#else
|
|
||||||
bashextra("histexpand", SH_HISTEXPAND)
|
|
||||||
#endif
|
#endif
|
||||||
bashextra("history", SH_HISTORY2)
|
|
||||||
bashopt("histreedit", SH_HISTREEDIT)
|
|
||||||
bashopt("histverify", SH_HISTVERIFY)
|
|
||||||
bashopt("hostcomplete", SH_HOSTCOMPLETE)
|
|
||||||
bashopt("huponexit", SH_HUPONEXIT)
|
|
||||||
"ignoreeof", SH_IGNOREEOF,
|
"ignoreeof", SH_IGNOREEOF,
|
||||||
"interactive", SH_INTERACTIVE|SH_COMMANDLINE,
|
"interactive", SH_INTERACTIVE|SH_COMMANDLINE,
|
||||||
bashextra("interactive_comments", SH_INTERACTIVE_COMM)
|
|
||||||
"keyword", SH_KEYWORD,
|
"keyword", SH_KEYWORD,
|
||||||
"letoctal", SH_LETOCTAL,
|
"letoctal", SH_LETOCTAL,
|
||||||
bashopt("lithist", SH_LITHIST)
|
|
||||||
"nolog", SH_NOLOG,
|
"nolog", SH_NOLOG,
|
||||||
"login_shell", SH_LOGIN_SHELL|SH_COMMANDLINE,
|
"login_shell", SH_LOGIN_SHELL|SH_COMMANDLINE,
|
||||||
bashopt("mailwarn", SH_MAILWARN)
|
|
||||||
"markdirs", SH_MARKDIRS,
|
"markdirs", SH_MARKDIRS,
|
||||||
"monitor", SH_MONITOR,
|
"monitor", SH_MONITOR,
|
||||||
"multiline", SH_MULTILINE,
|
"multiline", SH_MULTILINE,
|
||||||
bashopt("no_empty_cmd_completion", SH_NOEMPTYCMDCOMPL)
|
|
||||||
bashopt("nocaseglob", SH_NOCASEGLOB)
|
|
||||||
"notify", SH_NOTIFY,
|
"notify", SH_NOTIFY,
|
||||||
bashopt("nullglob", SH_NULLGLOB)
|
|
||||||
bashextra("onecmd", SH_TFLAG)
|
|
||||||
"pipefail", SH_PIPEFAIL,
|
"pipefail", SH_PIPEFAIL,
|
||||||
bashextra("physical", SH_PHYSICAL)
|
"posix", SH_POSIX,
|
||||||
bashextra("posix", SH_POSIX)
|
|
||||||
"privileged", SH_PRIVILEGED,
|
"privileged", SH_PRIVILEGED,
|
||||||
#if SHOPT_BASH
|
#if SHOPT_PFSH
|
||||||
"profile", SH_LOGIN_SHELL|SH_COMMANDLINE,
|
|
||||||
# if SHOPT_PFSH
|
|
||||||
"pfsh", SH_PFSH|SH_COMMANDLINE,
|
|
||||||
# endif
|
|
||||||
#else
|
|
||||||
# if SHOPT_PFSH
|
|
||||||
"profile", SH_PFSH|SH_COMMANDLINE,
|
"profile", SH_PFSH|SH_COMMANDLINE,
|
||||||
# endif
|
|
||||||
#endif
|
#endif
|
||||||
bashopt("progcomp", SH_PROGCOMP)
|
|
||||||
bashopt("promptvars", SH_PROMPTVARS)
|
|
||||||
"rc", SH_RC|SH_COMMANDLINE,
|
"rc", SH_RC|SH_COMMANDLINE,
|
||||||
"restricted", SH_RESTRICTED,
|
"restricted", SH_RESTRICTED,
|
||||||
bashopt("restricted_shell", SH_RESTRICTED2|SH_COMMANDLINE)
|
|
||||||
bashopt("shift_verbose", SH_SHIFT_VERBOSE)
|
|
||||||
"showme", SH_SHOWME,
|
"showme", SH_SHOWME,
|
||||||
bashopt("sourcepath", SH_SOURCEPATH)
|
|
||||||
"trackall", SH_TRACKALL,
|
"trackall", SH_TRACKALL,
|
||||||
"nounset", SH_NOUNSET,
|
"nounset", SH_NOUNSET,
|
||||||
"verbose", SH_VERBOSE,
|
"verbose", SH_VERBOSE,
|
||||||
"vi", SH_VI,
|
"vi", SH_VI,
|
||||||
"viraw", SH_VIRAW,
|
"viraw", SH_VIRAW,
|
||||||
bashopt("xpg_echo", SH_XPG_ECHO)
|
|
||||||
"xtrace", SH_XTRACE,
|
"xtrace", SH_XTRACE,
|
||||||
"", 0
|
"", 0
|
||||||
};
|
};
|
||||||
|
|
|
@ -58,11 +58,6 @@
|
||||||
#define SYSDOT (shgd->bltin_cmds+20) /* . */
|
#define SYSDOT (shgd->bltin_cmds+20) /* . */
|
||||||
#define SYSSOURCE (shgd->bltin_cmds+21) /* source */
|
#define SYSSOURCE (shgd->bltin_cmds+21) /* source */
|
||||||
#define SYSRETURN (shgd->bltin_cmds+22) /* return */
|
#define SYSRETURN (shgd->bltin_cmds+22) /* return */
|
||||||
#if SHOPT_BASH
|
|
||||||
# define SYSLOCAL (shgd->bltin_cmds+23) /* local */
|
|
||||||
#else
|
|
||||||
# define SYSLOCAL 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* entry point for shell special builtins */
|
/* entry point for shell special builtins */
|
||||||
|
|
||||||
|
|
|
@ -311,7 +311,6 @@ struct shared
|
||||||
#define SH_COMPLETE 19 /* set for command completion */
|
#define SH_COMPLETE 19 /* set for command completion */
|
||||||
#define SH_INTESTCMD 20 /* set while test/[ command is being run */
|
#define SH_INTESTCMD 20 /* set while test/[ command is being run */
|
||||||
|
|
||||||
#define SH_BASH 41
|
|
||||||
#define SH_BRACEEXPAND 42
|
#define SH_BRACEEXPAND 42
|
||||||
#define SH_POSIX 46
|
#define SH_POSIX 46
|
||||||
#define SH_MULTILINE 47
|
#define SH_MULTILINE 47
|
||||||
|
@ -319,9 +318,7 @@ struct shared
|
||||||
#define SH_NOPROFILE 78
|
#define SH_NOPROFILE 78
|
||||||
#define SH_NOUSRPROFILE 79
|
#define SH_NOUSRPROFILE 79
|
||||||
#define SH_LOGIN_SHELL 67
|
#define SH_LOGIN_SHELL 67
|
||||||
#define SH_COMMANDLINE 0x100
|
#define SH_COMMANDLINE 0x100 /* flag for invocation-only options ('set -o' cannot change them) */
|
||||||
#define SH_BASHEXTRA 0x200
|
|
||||||
#define SH_BASHOPT 0x400
|
|
||||||
|
|
||||||
#define SH_ID "ksh" /* ksh id */
|
#define SH_ID "ksh" /* ksh id */
|
||||||
#define SH_STD "sh" /* standard sh id */
|
#define SH_STD "sh" /* standard sh id */
|
||||||
|
@ -330,44 +327,11 @@ struct shared
|
||||||
|
|
||||||
#define SH_TYPE_SH 001
|
#define SH_TYPE_SH 001
|
||||||
#define SH_TYPE_KSH 002
|
#define SH_TYPE_KSH 002
|
||||||
#define SH_TYPE_BASH 004
|
#define SH_TYPE_POSIX 004
|
||||||
#define SH_TYPE_LOGIN 010
|
#define SH_TYPE_LOGIN 010
|
||||||
#define SH_TYPE_PROFILE 020
|
#define SH_TYPE_PROFILE 020
|
||||||
#define SH_TYPE_RESTRICTED 040
|
#define SH_TYPE_RESTRICTED 040
|
||||||
|
|
||||||
#if SHOPT_BASH
|
|
||||||
# ifndef SHOPT_HISTEXPAND
|
|
||||||
# define SHOPT_HISTEXPAND 1
|
|
||||||
# endif
|
|
||||||
/*
|
|
||||||
* define for all the bash options
|
|
||||||
*/
|
|
||||||
# define SH_CDABLE_VARS 51
|
|
||||||
# define SH_CDSPELL 52
|
|
||||||
# define SH_CHECKHASH 53
|
|
||||||
# define SH_CHECKWINSIZE 54
|
|
||||||
# define SH_CMDHIST 55
|
|
||||||
# define SH_DOTGLOB 56
|
|
||||||
# define SH_EXECFAIL 57
|
|
||||||
# define SH_EXPAND_ALIASES 58
|
|
||||||
# define SH_EXTGLOB 59
|
|
||||||
# define SH_HOSTCOMPLETE 63
|
|
||||||
# define SH_HUPONEXIT 64
|
|
||||||
# define SH_INTERACTIVE_COMM 65
|
|
||||||
# define SH_LITHIST 66
|
|
||||||
# define SH_MAILWARN 68
|
|
||||||
# define SH_NOEMPTYCMDCOMPL 69
|
|
||||||
# define SH_NOCASEGLOB 70
|
|
||||||
# define SH_NULLGLOB 71
|
|
||||||
# define SH_PHYSICAL 45
|
|
||||||
# define SH_PROGCOMP 72
|
|
||||||
# define SH_PROMPTVARS 73
|
|
||||||
# define SH_RESTRICTED2 74
|
|
||||||
# define SH_SHIFT_VERBOSE 75
|
|
||||||
# define SH_SOURCEPATH 76
|
|
||||||
# define SH_XPG_ECHO 77
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if SHOPT_HISTEXPAND
|
#if SHOPT_HISTEXPAND
|
||||||
# define SH_HISTAPPEND 60
|
# define SH_HISTAPPEND 60
|
||||||
# define SH_HISTEXPAND 43
|
# define SH_HISTEXPAND 43
|
||||||
|
@ -483,7 +447,6 @@ extern const char e_dict[];
|
||||||
#define PRINT_VERBOSE 0x01 /* option on|off list */
|
#define PRINT_VERBOSE 0x01 /* option on|off list */
|
||||||
#define PRINT_ALL 0x02 /* list unset options too */
|
#define PRINT_ALL 0x02 /* list unset options too */
|
||||||
#define PRINT_NO_HEADER 0x04 /* omit listing header */
|
#define PRINT_NO_HEADER 0x04 /* omit listing header */
|
||||||
#define PRINT_SHOPT 0x08 /* shopt -s|-u */
|
|
||||||
#define PRINT_TABLE 0x10 /* table of all options */
|
#define PRINT_TABLE 0x10 /* table of all options */
|
||||||
|
|
||||||
#ifdef SHOPT_STATS
|
#ifdef SHOPT_STATS
|
||||||
|
|
|
@ -114,15 +114,6 @@ extern const char e_sysprofile[];
|
||||||
#if SHOPT_SYSRC
|
#if SHOPT_SYSRC
|
||||||
extern const char e_sysrc[];
|
extern const char e_sysrc[];
|
||||||
#endif
|
#endif
|
||||||
#if SHOPT_BASH
|
|
||||||
#if SHOPT_SYSRC
|
|
||||||
extern const char e_bash_sysrc[];
|
|
||||||
#endif
|
|
||||||
extern const char e_bash_rc[];
|
|
||||||
extern const char e_bash_login[];
|
|
||||||
extern const char e_bash_logout[];
|
|
||||||
extern const char e_bash_profile[];
|
|
||||||
#endif
|
|
||||||
extern const char e_stdprompt[];
|
extern const char e_stdprompt[];
|
||||||
extern const char e_supprompt[];
|
extern const char e_supprompt[];
|
||||||
extern const char e_ambiguous[];
|
extern const char e_ambiguous[];
|
||||||
|
|
|
@ -41,7 +41,6 @@ typedef struct _shlex_
|
||||||
int lastline; /* last line number */
|
int lastline; /* last line number */
|
||||||
int lasttok; /* previous token number */
|
int lasttok; /* previous token number */
|
||||||
int digits; /* numerical value with word token */
|
int digits; /* numerical value with word token */
|
||||||
int nonstandard; /* nonstandard construct in profile */
|
|
||||||
char aliasok; /* on when alias is legal */
|
char aliasok; /* on when alias is legal */
|
||||||
char assignok; /* on when name=value is legal */
|
char assignok; /* on when name=value is legal */
|
||||||
char inexec; /* on when processing exec */
|
char inexec; /* on when processing exec */
|
||||||
|
|
|
@ -17,4 +17,4 @@
|
||||||
* David Korn <dgk@research.att.com> *
|
* David Korn <dgk@research.att.com> *
|
||||||
* *
|
* *
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
#define SH_RELEASE "93u+m 2020-08-19"
|
#define SH_RELEASE "93u+m 2020-09-01"
|
||||||
|
|
|
@ -3409,7 +3409,7 @@ successfully rename it to
|
||||||
otherwise, delete the temporary file.
|
otherwise, delete the temporary file.
|
||||||
.BI >; word
|
.BI >; word
|
||||||
cannot be used with the
|
cannot be used with the
|
||||||
.IR exec (2).
|
.IR exec
|
||||||
built-in.
|
built-in.
|
||||||
.TP
|
.TP
|
||||||
.BI >> word
|
.BI >> word
|
||||||
|
@ -3433,7 +3433,7 @@ except that if the command completes successfully,
|
||||||
is truncated to the offset at command completion.
|
is truncated to the offset at command completion.
|
||||||
.BI <>; word
|
.BI <>; word
|
||||||
cannot be used with the
|
cannot be used with the
|
||||||
.IR exec (2).
|
.IR exec
|
||||||
built-in.
|
built-in.
|
||||||
.TP
|
.TP
|
||||||
\f3<<\fP\*(OK\f3\-\fP\*(CK\f2word\fP
|
\f3<<\fP\*(OK\f3\-\fP\*(CK\f2word\fP
|
||||||
|
@ -3492,20 +3492,26 @@ The standard input is duplicated from file descriptor
|
||||||
.I digit
|
.I digit
|
||||||
(see
|
(see
|
||||||
.IR dup (2)).
|
.IR dup (2)).
|
||||||
Similarly for the standard output using
|
.TP
|
||||||
\f3>&\^\f2digit\fR.
|
.BI >& digit
|
||||||
|
The standard output is duplicated from file descriptor
|
||||||
|
.IR digit .
|
||||||
.TP
|
.TP
|
||||||
.BI <& digit \-
|
.BI <& digit \-
|
||||||
The file descriptor given by
|
The file descriptor given by
|
||||||
.I digit
|
.I digit
|
||||||
is moved to standard input.
|
is moved to standard input.
|
||||||
Similarly for the standard output using
|
.TP
|
||||||
\f3>&\^\f2digit\f3\-\fR.
|
.BI >& digit \-
|
||||||
|
The file descriptor given by
|
||||||
|
.I digit
|
||||||
|
is moved to standard output.
|
||||||
.TP
|
.TP
|
||||||
.B <&\-
|
.B <&\-
|
||||||
The standard input is closed.
|
The standard input is closed.
|
||||||
Similarly for the standard output using
|
.TP
|
||||||
.BR >&\- .
|
.B >&\-
|
||||||
|
The standard output is closed.
|
||||||
.TP
|
.TP
|
||||||
.B <&p
|
.B <&p
|
||||||
The input from the co-process is moved to standard input.
|
The input from the co-process is moved to standard input.
|
||||||
|
@ -3593,6 +3599,11 @@ for reading and store
|
||||||
the file descriptor number in variable
|
the file descriptor number in variable
|
||||||
.BR n .
|
.BR n .
|
||||||
.PP
|
.PP
|
||||||
|
A special shorthand redirection operator \fB&>\fR\fIword\fR is available; it
|
||||||
|
is equivalent to \fB>\fR\fIword\fR\fB 2>&1\fR. It cannot be preceded by any
|
||||||
|
digit or variable name. This shorthand is disabled if the \fIposix\fR shell
|
||||||
|
option is active.
|
||||||
|
.PP
|
||||||
The order in which redirections are specified is significant.
|
The order in which redirections are specified is significant.
|
||||||
The shell evaluates each redirection in terms of the
|
The shell evaluates each redirection in terms of the
|
||||||
.RI ( "file descriptor" ", " file )
|
.RI ( "file descriptor" ", " file )
|
||||||
|
@ -7020,6 +7031,11 @@ of the pipeline have completed, and the return value
|
||||||
will be the value of the last non-zero command
|
will be the value of the last non-zero command
|
||||||
to fail or zero if no command has failed.
|
to fail or zero if no command has failed.
|
||||||
.TP 8
|
.TP 8
|
||||||
|
.B posix
|
||||||
|
Enable POSIX standard compatibility mode. This option
|
||||||
|
is on by default if ksh is invoked as \fBsh\fR. It
|
||||||
|
disables the \fB&>\fR redirection shorthand.
|
||||||
|
.TP 8
|
||||||
.B privileged
|
.B privileged
|
||||||
Same as
|
Same as
|
||||||
.BR \-p .
|
.BR \-p .
|
||||||
|
|
|
@ -42,11 +42,6 @@
|
||||||
#else
|
#else
|
||||||
# define PFSHOPT
|
# define PFSHOPT
|
||||||
#endif
|
#endif
|
||||||
#if SHOPT_BASH
|
|
||||||
# define BASHOPT "\374"
|
|
||||||
#else
|
|
||||||
# define BASHOPT
|
|
||||||
#endif
|
|
||||||
#if SHOPT_HISTEXPAND
|
#if SHOPT_HISTEXPAND
|
||||||
# define HFLAG "H"
|
# define HFLAG "H"
|
||||||
#else
|
#else
|
||||||
|
@ -59,15 +54,13 @@
|
||||||
static char *null;
|
static char *null;
|
||||||
|
|
||||||
/* The following order is determined by sh_optset */
|
/* The following order is determined by sh_optset */
|
||||||
static const char optksh[] = PFSHOPT BASHOPT "DircabefhkmnpstuvxBCGEl" HFLAG;
|
static const char optksh[] = PFSHOPT "\374" "DircabefhkmnpstuvxBCGEl" HFLAG;
|
||||||
static const int flagval[] =
|
static const int flagval[] =
|
||||||
{
|
{
|
||||||
#if SHOPT_PFSH
|
#if SHOPT_PFSH
|
||||||
SH_PFSH,
|
SH_PFSH,
|
||||||
#endif
|
#endif
|
||||||
#if SHOPT_BASH
|
|
||||||
SH_POSIX,
|
SH_POSIX,
|
||||||
#endif
|
|
||||||
SH_DICTIONARY, SH_INTERACTIVE, SH_RESTRICTED, SH_CFLAG,
|
SH_DICTIONARY, SH_INTERACTIVE, SH_RESTRICTED, SH_CFLAG,
|
||||||
SH_ALLEXPORT, SH_NOTIFY, SH_ERREXIT, SH_NOGLOB, SH_TRACKALL,
|
SH_ALLEXPORT, SH_NOTIFY, SH_ERREXIT, SH_NOGLOB, SH_TRACKALL,
|
||||||
SH_KEYWORD, SH_MONITOR, SH_NOEXEC, SH_PRIVILEGED, SH_SFLAG, SH_TFLAG,
|
SH_KEYWORD, SH_MONITOR, SH_NOEXEC, SH_PRIVILEGED, SH_SFLAG, SH_TFLAG,
|
||||||
|
@ -108,22 +101,6 @@ void *sh_argopen(Shell_t *shp)
|
||||||
|
|
||||||
static int infof(Opt_t* op, Sfio_t* sp, const char* s, Optdisc_t* dp)
|
static int infof(Opt_t* op, Sfio_t* sp, const char* s, Optdisc_t* dp)
|
||||||
{
|
{
|
||||||
#if SHOPT_BASH
|
|
||||||
extern const char sh_bash1[], sh_bash2[];
|
|
||||||
if(strcmp(s,"bash1")==0)
|
|
||||||
{
|
|
||||||
if(sh_isoption(SH_BASH))
|
|
||||||
sfputr(sp,sh_bash1,-1);
|
|
||||||
}
|
|
||||||
else if(strcmp(s,"bash2")==0)
|
|
||||||
{
|
|
||||||
if(sh_isoption(SH_BASH))
|
|
||||||
sfputr(sp,sh_bash2,-1);
|
|
||||||
}
|
|
||||||
else if(*s==':' && sh_isoption(SH_BASH))
|
|
||||||
sfputr(sp,s,-1);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
if(*s!=':')
|
if(*s!=':')
|
||||||
sfputr(sp,sh_set,-1);
|
sfputr(sp,sh_set,-1);
|
||||||
return(1);
|
return(1);
|
||||||
|
@ -168,31 +145,17 @@ int sh_argopts(int argc,register char *argv[], void *context)
|
||||||
if(f)
|
if(f)
|
||||||
nv_unset(np);
|
nv_unset(np);
|
||||||
continue;
|
continue;
|
||||||
#if SHOPT_BASH
|
|
||||||
case 'O': /* shopt options, only in bash mode */
|
|
||||||
if(!sh_isoption(SH_BASH))
|
|
||||||
errormsg(SH_DICT,ERROR_exit(1), e_option, opt_info.name);
|
|
||||||
#endif
|
|
||||||
case 'o': /* set options */
|
case 'o': /* set options */
|
||||||
byname:
|
byname:
|
||||||
if(!opt_info.arg||!*opt_info.arg||*opt_info.arg=='-')
|
if(!opt_info.arg||!*opt_info.arg||*opt_info.arg=='-')
|
||||||
{
|
{
|
||||||
action = PRINT;
|
action = PRINT;
|
||||||
/* print style: -O => shopt options
|
|
||||||
* bash => print unset options also, no heading
|
|
||||||
*/
|
|
||||||
verbose = (f?PRINT_VERBOSE:PRINT_NO_HEADER)|
|
verbose = (f?PRINT_VERBOSE:PRINT_NO_HEADER)|
|
||||||
(n=='O'?PRINT_SHOPT:0)|
|
|
||||||
(sh_isoption(SH_BASH)?PRINT_ALL|PRINT_NO_HEADER:0)|
|
|
||||||
((opt_info.arg&&(!*opt_info.arg||*opt_info.arg=='-'))?(PRINT_TABLE|PRINT_NO_HEADER):0);
|
((opt_info.arg&&(!*opt_info.arg||*opt_info.arg=='-'))?(PRINT_TABLE|PRINT_NO_HEADER):0);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
o = sh_lookopt(opt_info.arg,&f);
|
o = sh_lookopt(opt_info.arg,&f);
|
||||||
if(o<=0
|
if(o<=0 || (setflag && (o&SH_COMMANDLINE)))
|
||||||
|| (!sh_isoption(SH_BASH) && (o&SH_BASHEXTRA))
|
|
||||||
|| ((!sh_isoption(SH_BASH) || n=='o') && (o&SH_BASHOPT))
|
|
||||||
|
|
||||||
|| (setflag && (o&SH_COMMANDLINE)))
|
|
||||||
{
|
{
|
||||||
errormsg(SH_DICT,2, e_option, opt_info.arg);
|
errormsg(SH_DICT,2, e_option, opt_info.arg);
|
||||||
error_info.errors++;
|
error_info.errors++;
|
||||||
|
@ -201,33 +164,6 @@ int sh_argopts(int argc,register char *argv[], void *context)
|
||||||
if(sh_isoption(SH_RESTRICTED) && !f && o==SH_RESTRICTED)
|
if(sh_isoption(SH_RESTRICTED) && !f && o==SH_RESTRICTED)
|
||||||
errormsg(SH_DICT,ERROR_exit(1), e_restricted, opt_info.arg);
|
errormsg(SH_DICT,ERROR_exit(1), e_restricted, opt_info.arg);
|
||||||
break;
|
break;
|
||||||
#if SHOPT_BASH
|
|
||||||
case -1: /* --rcfile */
|
|
||||||
ap->sh->gd->rcfile = opt_info.arg;
|
|
||||||
continue;
|
|
||||||
case -2: /* --noediting */
|
|
||||||
if (!f)
|
|
||||||
{
|
|
||||||
off_option(&newflags,SH_VI);
|
|
||||||
off_option(&newflags,SH_EMACS);
|
|
||||||
off_option(&newflags,SH_GMACS);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
case -3: /* --profile */
|
|
||||||
n = 'l';
|
|
||||||
goto skip;
|
|
||||||
case -4: /* --posix */
|
|
||||||
/* mask lower 8 bits to find char in optksh string */
|
|
||||||
n&=0xff;
|
|
||||||
goto skip;
|
|
||||||
case -5: /* --version */
|
|
||||||
sfputr(sfstdout, "ksh bash emulation, version ",-1);
|
|
||||||
np = nv_open("BASH_VERSION",ap->sh->var_tree,0);
|
|
||||||
sfputr(sfstdout, nv_getval(np),-1);
|
|
||||||
np = nv_open("MACHTYPE",ap->sh->var_tree,0);
|
|
||||||
sfprintf(sfstdout, " (%s)\n", nv_getval(np));
|
|
||||||
sh_exit(0);
|
|
||||||
#endif
|
|
||||||
case -6: /* --default */
|
case -6: /* --default */
|
||||||
{
|
{
|
||||||
register const Shtable_t *tp;
|
register const Shtable_t *tp;
|
||||||
|
@ -408,35 +344,6 @@ void sh_applyopts(Shell_t* shp,Shopt_t newflags)
|
||||||
(shp->gd->userid==shp->gd->euserid && shp->gd->groupid==shp->gd->egroupid))
|
(shp->gd->userid==shp->gd->euserid && shp->gd->groupid==shp->gd->egroupid))
|
||||||
off_option(&newflags,SH_PRIVILEGED);
|
off_option(&newflags,SH_PRIVILEGED);
|
||||||
}
|
}
|
||||||
#if SHOPT_BASH
|
|
||||||
on_option(&newflags,SH_CMDHIST);
|
|
||||||
on_option(&newflags,SH_CHECKHASH);
|
|
||||||
on_option(&newflags,SH_EXECFAIL);
|
|
||||||
on_option(&newflags,SH_EXPAND_ALIASES);
|
|
||||||
on_option(&newflags,SH_HISTAPPEND);
|
|
||||||
on_option(&newflags,SH_INTERACTIVE_COMM);
|
|
||||||
on_option(&newflags,SH_LITHIST);
|
|
||||||
on_option(&newflags,SH_NOEMPTYCMDCOMPL);
|
|
||||||
|
|
||||||
if(!is_option(&newflags,SH_XPG_ECHO) && sh_isoption(SH_XPG_ECHO))
|
|
||||||
astconf("UNIVERSE", 0, "ucb");
|
|
||||||
if(is_option(&newflags,SH_XPG_ECHO) && !sh_isoption(SH_XPG_ECHO))
|
|
||||||
astconf("UNIVERSE", 0, "att");
|
|
||||||
if(!is_option(&newflags,SH_PHYSICAL) && sh_isoption(SH_PHYSICAL))
|
|
||||||
astconf("PATH_RESOLVE", 0, "metaphysical");
|
|
||||||
if(is_option(&newflags,SH_PHYSICAL) && !sh_isoption(SH_PHYSICAL))
|
|
||||||
astconf("PATH_RESOLVE", 0, "physical");
|
|
||||||
if(is_option(&newflags,SH_HISTORY2) && !sh_isoption(SH_HISTORY2))
|
|
||||||
{
|
|
||||||
sh_onstate(SH_HISTORY);
|
|
||||||
sh_onoption(SH_HISTORY);
|
|
||||||
}
|
|
||||||
if(!is_option(&newflags,SH_HISTORY2) && sh_isoption(SH_HISTORY2))
|
|
||||||
{
|
|
||||||
sh_offstate(SH_HISTORY);
|
|
||||||
sh_offoption(SH_HISTORY);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
shp->options = newflags;
|
shp->options = newflags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -647,23 +554,11 @@ void sh_printopts(Shopt_t oflags,register int mode, Shopt_t *mask)
|
||||||
on_option(&oflags,SH_VIRAW);
|
on_option(&oflags,SH_VIRAW);
|
||||||
#endif
|
#endif
|
||||||
if(!(mode&(PRINT_ALL|PRINT_VERBOSE))) /* only print set options */
|
if(!(mode&(PRINT_ALL|PRINT_VERBOSE))) /* only print set options */
|
||||||
{
|
sfwrite(sfstdout,"set --default",13);
|
||||||
if(mode&PRINT_SHOPT)
|
|
||||||
sfwrite(sfstdout,"shopt -s",3);
|
|
||||||
else
|
|
||||||
sfwrite(sfstdout,"set --default",13);
|
|
||||||
}
|
|
||||||
for(tp=shtab_options; value=tp->sh_number; tp++)
|
for(tp=shtab_options; value=tp->sh_number; tp++)
|
||||||
{
|
{
|
||||||
if(mask && !is_option(mask,value&0xff))
|
if(mask && !is_option(mask,value&0xff))
|
||||||
continue;
|
continue;
|
||||||
if(sh_isoption(SH_BASH))
|
|
||||||
{
|
|
||||||
if (!(mode&PRINT_SHOPT) != !(value&SH_BASHOPT))
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if (value&(SH_BASHEXTRA|SH_BASHOPT))
|
|
||||||
continue;
|
|
||||||
on = !!is_option(&oflags,value);
|
on = !!is_option(&oflags,value);
|
||||||
name = tp->sh_name;
|
name = tp->sh_name;
|
||||||
if(name[0] == 'n' && name[1] == 'o' && name[2] != 't')
|
if(name[0] == 'n' && name[1] == 'o' && name[2] != 't')
|
||||||
|
@ -678,18 +573,9 @@ void sh_printopts(Shopt_t oflags,register int mode, Shopt_t *mask)
|
||||||
sfputr(sfstdout,on ? sh_translate(e_on) : sh_translate(e_off),'\n');
|
sfputr(sfstdout,on ? sh_translate(e_on) : sh_translate(e_off),'\n');
|
||||||
}
|
}
|
||||||
else if(mode&PRINT_ALL) /* print unset options also */
|
else if(mode&PRINT_ALL) /* print unset options also */
|
||||||
{
|
sfprintf(sfstdout, "set %co %s\n", on?'-':'+', name);
|
||||||
if(mode&PRINT_SHOPT)
|
|
||||||
sfprintf(sfstdout, "shopt -%c %s\n",
|
|
||||||
on?'s':'u',
|
|
||||||
name);
|
|
||||||
else
|
|
||||||
sfprintf(sfstdout, "set %co %s\n",
|
|
||||||
on?'-':'+',
|
|
||||||
name);
|
|
||||||
}
|
|
||||||
else if(!(value&SH_COMMANDLINE) && is_option(&oflags,value&0xff))
|
else if(!(value&SH_COMMANDLINE) && is_option(&oflags,value&0xff))
|
||||||
sfprintf(sfstdout," %s%s%s",(mode&PRINT_SHOPT)?"":"--",on?"":"no",name);
|
sfprintf(sfstdout, " %s%s%s","--", on?"":"no", name);
|
||||||
}
|
}
|
||||||
if(!(mode&(PRINT_VERBOSE|PRINT_ALL)))
|
if(!(mode&(PRINT_VERBOSE|PRINT_ALL)))
|
||||||
sfputc(sfstdout,'\n');
|
sfputc(sfstdout,'\n');
|
||||||
|
|
|
@ -1,423 +0,0 @@
|
||||||
/***********************************************************************
|
|
||||||
* *
|
|
||||||
* This software is part of the ast package *
|
|
||||||
* Copyright (c) 1982-2011 AT&T Intellectual Property *
|
|
||||||
* and is licensed under the *
|
|
||||||
* Eclipse Public License, Version 1.0 *
|
|
||||||
* by AT&T Intellectual Property *
|
|
||||||
* *
|
|
||||||
* A copy of the License is available at *
|
|
||||||
* http://www.eclipse.org/org/documents/epl-v10.html *
|
|
||||||
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
|
|
||||||
* *
|
|
||||||
* Information and Software Systems Research *
|
|
||||||
* AT&T Research *
|
|
||||||
* Florham Park NJ *
|
|
||||||
* *
|
|
||||||
* David Korn <dgk@research.att.com> *
|
|
||||||
* *
|
|
||||||
***********************************************************************/
|
|
||||||
/*
|
|
||||||
* bash specific extensions
|
|
||||||
* originally provided by Karsten Fleischer
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "defs.h"
|
|
||||||
#include "path.h"
|
|
||||||
#include "io.h"
|
|
||||||
#include "builtins.h"
|
|
||||||
#include "name.h"
|
|
||||||
|
|
||||||
#ifndef BASH_MAJOR
|
|
||||||
# define BASH_MAJOR "1"
|
|
||||||
# define BASH_MINOR "0"
|
|
||||||
# define BASH_PATCH "0"
|
|
||||||
# define BASH_BUILD "0"
|
|
||||||
# define BASH_RELEASE "experimental"
|
|
||||||
#endif
|
|
||||||
#define BASH_VERSION BASH_MAJOR "." BASH_MINOR "." BASH_PATCH "(" BASH_BUILD ")-" BASH_RELEASE
|
|
||||||
|
|
||||||
|
|
||||||
extern const char bash_pre_rc[];
|
|
||||||
|
|
||||||
static char *login_files[4];
|
|
||||||
|
|
||||||
const char sh_bash1[] =
|
|
||||||
"[B?Enable brace group expansion. This option is only available in bash "
|
|
||||||
"compatibility mode. In ksh mode, brace group expansion is always on.]"
|
|
||||||
"[P?Do not follow symbolic links, use physical directory structure "
|
|
||||||
"instead. Only available in bash compatibility mode.]";
|
|
||||||
const char sh_bash2[] =
|
|
||||||
"[O]:?[shopt_option?\ashopt_option\a is one of the shell options accepted by "
|
|
||||||
"the \bshopt\b builtin. If \ashopt_option\a is present, \b-O\b sets "
|
|
||||||
"the value of that option; \b+O\b unsets it. If \ashopt_option\a is "
|
|
||||||
"not supplied, the names and values of the shell options accepted by "
|
|
||||||
"\bshopt\b are printed on the standard output. If the invocation "
|
|
||||||
"option is \b+O\b, the output is displayed in a format that may be "
|
|
||||||
"reused as input. Only available if invoked as \bbash\b.]"
|
|
||||||
"[01:init-file|rcfile]:[file?Execute commands from \afile\a instead of the "
|
|
||||||
"standard personal initialization file ~/.bashrc if the shell is "
|
|
||||||
"interactive. Only available if invoked as \bbash\b.]"
|
|
||||||
"[02:editing?For option compatibility with \bbash\b only. Ignored.]"
|
|
||||||
"[03:profile?Read either the system-wide startup file or any of the "
|
|
||||||
"personal initialization files. On by default for interactive "
|
|
||||||
"shells. Only available if invoked as \bbash\b.]"
|
|
||||||
"[04:posix?If invoked as \bbash\b, turn on POSIX compatibility. \bBash\b in "
|
|
||||||
"POSIX mode is not the same as \bksh\b.]"
|
|
||||||
"[05:version?Print version number and exit.]";
|
|
||||||
|
|
||||||
const char sh_optshopt[] =
|
|
||||||
"+[-1c?\n@(#)$Id: shopt (AT&T Research) 2003-02-13 $\n]"
|
|
||||||
"[-author?Karsten Fleischer <K.Fleischer@omnium.de>]"
|
|
||||||
USAGE_LICENSE
|
|
||||||
"[+NAME?shopt - set/unset variables controlling optional shell behavior]"
|
|
||||||
"[+DESCRIPTION?\bshopt\b sets or unsets variables controlling optional shell "
|
|
||||||
"behavior. With no options, or with the \b-p\b option, a list of all "
|
|
||||||
"settable options is displayed, with an indication of whether or not "
|
|
||||||
"each is set.]"
|
|
||||||
"[p?Causes output to be displayed in a form that may be reused as input.]"
|
|
||||||
"[s?Set each \aoptname\a.]"
|
|
||||||
"[u?Unset each \aoptname\a.]"
|
|
||||||
"[q?Suppress output (quiet mode). The return status indicates whether the "
|
|
||||||
"\aoptname\a is set or unset. If multiple \aoptname\a arguments are "
|
|
||||||
"given with \b-q\b, the return status is zero if all \aoptname\as are "
|
|
||||||
"enabled; non-zero otherwise.]"
|
|
||||||
"[o?Restricts the values of \aoptname\a to be those defined for the \b-o\b "
|
|
||||||
"option to the set builtin.]"
|
|
||||||
"[+?If either \b-s\b or \b-u\b is used with no \aoptname\a arguments, the "
|
|
||||||
"display is limited to those options which are set or unset.]"
|
|
||||||
"[+?\bshopt\b supports all bash options. Some settings do not have any effect "
|
|
||||||
"or are are always on and cannot be changed.]"
|
|
||||||
"[+?The value of \aoptname\a must be one of the following:]{"
|
|
||||||
"[+cdable_vars?If set, arguments to the \bcd\b command are "
|
|
||||||
"assumed to be names of variables whose values are to "
|
|
||||||
"be used if the usual \bcd\b proceeding fails.]"
|
|
||||||
"[+cdspell?Currently ignored.]"
|
|
||||||
"[+checkhash?Always on.]"
|
|
||||||
"[+checkwinsize?Currently ignored.]"
|
|
||||||
"[+cmdhist?Always on.]"
|
|
||||||
"[+dotglob?If set, include filenames beginning with a \b.\b "
|
|
||||||
"in the results of pathname expansion.]"
|
|
||||||
"[+execfail?Always on.]"
|
|
||||||
"[+expand_aliases?Always on.]"
|
|
||||||
"[+extglob?Enable extended pattern matching features.]"
|
|
||||||
"[+histappend?Always on.]"
|
|
||||||
"[+histreedit?If set and an edit mode is selected, the user "
|
|
||||||
"is given the opportunity to re-edit a failed history "
|
|
||||||
"substitution.]"
|
|
||||||
"[+histverify?If set and an edit mode is selected, the result "
|
|
||||||
"of a history substitution will not be executed "
|
|
||||||
"immediately but be placed in the edit buffer for "
|
|
||||||
"further modifications.]"
|
|
||||||
"[+hostcomplete?Currently ignored.]"
|
|
||||||
"[+huponexit?Currently ignored.]"
|
|
||||||
"[+interactive_comments?Always on.]"
|
|
||||||
"[+lithist?Always on.]"
|
|
||||||
"[+login_shell?This option is set if the shell is started as "
|
|
||||||
"a login shell. The value cannot be changed.]"
|
|
||||||
"[+mailwarn?Currently ignored.]"
|
|
||||||
"[+no_empty_cmd_completion?Always on.]"
|
|
||||||
"[+nocaseglob?Match filenames in a case-insensitive fashion "
|
|
||||||
"when performing filename expansion.]"
|
|
||||||
"[+nullglob?Allows filename patterns which match no files to "
|
|
||||||
"expand to a null string, rather than themselves.]"
|
|
||||||
"[+progcomp?Currently ignored.]"
|
|
||||||
"[+promptvars?Currently ignored.]"
|
|
||||||
"[+restricted_shell?This option is set if the shell is started "
|
|
||||||
"as a restricted shell. The value cannot be changed. "
|
|
||||||
"It is not reset during execution of startup files, "
|
|
||||||
"allowing the startup files to determine whether the "
|
|
||||||
"shell is restricted.]"
|
|
||||||
"[+shift_verbose?Currently ignored.]"
|
|
||||||
"[+sourcepath?If set, the \b.\b builtin uses the value of PATH "
|
|
||||||
"to find the directory containing the file supplied "
|
|
||||||
"as an argument.]"
|
|
||||||
"[+xpg_echo?If set, the \becho\b and \bprint\b builtins "
|
|
||||||
"expand backslash-escape sequences.]"
|
|
||||||
"}"
|
|
||||||
"\n"
|
|
||||||
"\n[optname ...]\n"
|
|
||||||
"\n"
|
|
||||||
"[+EXIT STATUS?]{"
|
|
||||||
"[+?The return status when listing options is zero if all \aoptnames\a "
|
|
||||||
"are enabled, non-zero otherwise. When setting or unsetting options, "
|
|
||||||
"the return status is zero unless an \aoptname\a is not a valid shell "
|
|
||||||
"option.]"
|
|
||||||
"}"
|
|
||||||
|
|
||||||
"[+SEE ALSO?\bset\b(1)]"
|
|
||||||
;
|
|
||||||
|
|
||||||
/* GLOBIGNORE discipline. Turn on SH_DOTGLOB on set, turn off on unset. */
|
|
||||||
|
|
||||||
static void put_globignore(register Namval_t* np, const char *val, int flags, Namfun_t *fp)
|
|
||||||
{
|
|
||||||
if(val)
|
|
||||||
sh_onoption(SH_DOTGLOB);
|
|
||||||
else
|
|
||||||
sh_offoption(SH_DOTGLOB);
|
|
||||||
|
|
||||||
nv_putv(np,val,flags,fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
const Namdisc_t SH_GLOBIGNORE_disc = { sizeof(Namfun_t), put_globignore };
|
|
||||||
|
|
||||||
/* FUNCNAME discipline */
|
|
||||||
|
|
||||||
struct funcname
|
|
||||||
{
|
|
||||||
Namfun_t hdr;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void put_funcname(register Namval_t* np,const char *val,int flags,Namfun_t *fp)
|
|
||||||
{
|
|
||||||
/* bash silently returns with an error when FUNCNAME is set,
|
|
||||||
unsetting FUNCNAME is allowed */
|
|
||||||
if(val && !(flags&NV_RDONLY))
|
|
||||||
error_info.exit(1);
|
|
||||||
|
|
||||||
nv_putv(np,val,flags,fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
const Namdisc_t SH_FUNCNAME_disc = { sizeof(struct funcname), put_funcname };
|
|
||||||
|
|
||||||
#define SET_SET 1
|
|
||||||
#define SET_UNSET 2
|
|
||||||
#define SET_NOARGS 4
|
|
||||||
|
|
||||||
/* shopt builtin */
|
|
||||||
|
|
||||||
int b_shopt(int argc,register char *argv[],void *extra)
|
|
||||||
{
|
|
||||||
Shell_t *shp = (Shell_t*)extra;
|
|
||||||
int n, f, ret=0;
|
|
||||||
Shopt_t newflags=shp->options, opt;
|
|
||||||
int verbose=PRINT_SHOPT|PRINT_ALL|PRINT_NO_HEADER|PRINT_VERBOSE;
|
|
||||||
int setflag=0, quietflag=0, oflag=0;
|
|
||||||
memset(&opt,0,sizeof(opt));
|
|
||||||
#if SHOPT_RAWONLY
|
|
||||||
on_option(&newflags,SH_VIRAW);
|
|
||||||
#endif
|
|
||||||
while((n = optget(argv,sh_optshopt)))
|
|
||||||
{
|
|
||||||
switch(n)
|
|
||||||
{
|
|
||||||
case 'p':
|
|
||||||
verbose&=~PRINT_VERBOSE;
|
|
||||||
break;
|
|
||||||
case 's':
|
|
||||||
case 'u':
|
|
||||||
setflag|=n=='s'?SET_SET:SET_UNSET;
|
|
||||||
if(setflag==(SET_SET|SET_UNSET))
|
|
||||||
{
|
|
||||||
errormsg(SH_DICT,ERROR_ERROR,"cannot set and unset options simultaneously");
|
|
||||||
error_info.errors++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'q':
|
|
||||||
quietflag=1;
|
|
||||||
break;
|
|
||||||
case 'o':
|
|
||||||
oflag=1;
|
|
||||||
verbose&=~PRINT_SHOPT;
|
|
||||||
break;
|
|
||||||
case ':':
|
|
||||||
errormsg(SH_DICT,2, "%s", opt_info.arg);
|
|
||||||
continue;
|
|
||||||
case '?':
|
|
||||||
errormsg(SH_DICT,ERROR_usage(0), "%s", opt_info.arg);
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(error_info.errors)
|
|
||||||
errormsg(SH_DICT,ERROR_usage(2),"%s",optusage(NIL(char*)));
|
|
||||||
argc -= opt_info.index;
|
|
||||||
if(argc==0)
|
|
||||||
{
|
|
||||||
/* no args, -s => mask=current options, -u mask=~(current options)
|
|
||||||
else mask=all bits */
|
|
||||||
if(setflag&SET_SET)
|
|
||||||
opt=newflags;
|
|
||||||
else if(setflag&SET_UNSET)
|
|
||||||
for(n=0;n<4;n++)
|
|
||||||
opt.v[n]=~newflags.v[n];
|
|
||||||
else
|
|
||||||
memset(&opt,0xff,sizeof(opt));
|
|
||||||
setflag=SET_NOARGS;
|
|
||||||
}
|
|
||||||
while(argc>0)
|
|
||||||
{
|
|
||||||
f=1;
|
|
||||||
n=sh_lookopt(argv[opt_info.index],&f);
|
|
||||||
if(n<=0||(setflag
|
|
||||||
&& (is_option(&opt,SH_INTERACTIVE)
|
|
||||||
|| is_option(&opt,SH_RESTRICTED)
|
|
||||||
|| is_option(&opt,SH_RESTRICTED2)
|
|
||||||
|| is_option(&opt,SH_BASH)
|
|
||||||
|| is_option(&opt,SH_LOGIN_SHELL)))
|
|
||||||
||(oflag&&(n&SH_BASHOPT)))
|
|
||||||
{
|
|
||||||
errormsg(SH_DICT,ERROR_ERROR, e_option, argv[opt_info.index]);
|
|
||||||
error_info.errors++;
|
|
||||||
ret=1;
|
|
||||||
}
|
|
||||||
else if(f)
|
|
||||||
on_option(&opt,n&0xff);
|
|
||||||
else
|
|
||||||
off_option(&opt,n&0xff);
|
|
||||||
opt_info.index++;
|
|
||||||
argc--;
|
|
||||||
}
|
|
||||||
if(setflag&(SET_SET|SET_UNSET))
|
|
||||||
{
|
|
||||||
if(setflag&SET_SET)
|
|
||||||
{
|
|
||||||
if(sh_isoption(SH_INTERACTIVE))
|
|
||||||
off_option(&opt,SH_NOEXEC);
|
|
||||||
if(is_option(&opt,SH_VI)||is_option(&opt,SH_EMACS)||is_option(&opt,SH_GMACS))
|
|
||||||
{
|
|
||||||
off_option(&newflags,SH_VI);
|
|
||||||
off_option(&newflags,SH_EMACS);
|
|
||||||
off_option(&newflags,SH_GMACS);
|
|
||||||
}
|
|
||||||
for(n=0;n<4;n++)
|
|
||||||
newflags.v[n] |= opt.v[n];
|
|
||||||
}
|
|
||||||
else if(setflag&SET_UNSET)
|
|
||||||
for(n=0;n<4;n++)
|
|
||||||
newflags.v[n] &= ~opt.v[n];
|
|
||||||
sh_applyopts(shp,newflags);
|
|
||||||
shp->options = newflags;
|
|
||||||
if(is_option(&newflags,SH_XTRACE))
|
|
||||||
sh_trace(shp,argv,1);
|
|
||||||
}
|
|
||||||
else if(!(setflag&SET_NOARGS)) /* no -s,-u but args, ret=0 if opt&mask==mask */
|
|
||||||
{
|
|
||||||
for(n=0;n<4;n++)
|
|
||||||
ret+=((newflags.v[n]&opt.v[n])!=opt.v[n]);
|
|
||||||
}
|
|
||||||
if(!quietflag&&!(setflag&(SET_SET|SET_UNSET)))
|
|
||||||
sh_printopts(newflags,verbose,&opt);
|
|
||||||
return(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* mode = 0: init, called two times
|
|
||||||
before parsing shell args with SH_PREINIT state turned on
|
|
||||||
second time after sh_init() is through and with SH_PREINIT state turned off
|
|
||||||
mode > 1: re-init
|
|
||||||
mode < 0: shutdown
|
|
||||||
*/
|
|
||||||
|
|
||||||
void bash_init(Shell_t *shp,int mode)
|
|
||||||
{
|
|
||||||
Sfio_t *iop;
|
|
||||||
Namval_t *np;
|
|
||||||
int n=0,xtrace,verbose;
|
|
||||||
if(mode>0)
|
|
||||||
goto reinit;
|
|
||||||
if(mode < 0)
|
|
||||||
{
|
|
||||||
/* termination code */
|
|
||||||
if(sh_isoption(SH_LOGIN_SHELL) && !sh_isoption(SH_POSIX))
|
|
||||||
sh_source(shp, NiL, sh_mactry(shp,(char*)e_bash_logout));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(sh_isstate(SH_PREINIT))
|
|
||||||
{ /* pre-init stage */
|
|
||||||
if(sh_isoption(SH_RESTRICTED))
|
|
||||||
sh_onoption(SH_RESTRICTED2);
|
|
||||||
sh_onoption(SH_HISTORY2);
|
|
||||||
sh_onoption(SH_INTERACTIVE_COMM);
|
|
||||||
sh_onoption(SH_SOURCEPATH);
|
|
||||||
sh_onoption(SH_HISTAPPEND);
|
|
||||||
sh_onoption(SH_CMDHIST);
|
|
||||||
sh_onoption(SH_LITHIST);
|
|
||||||
sh_onoption(SH_NOEMPTYCMDCOMPL);
|
|
||||||
if(shp->login_sh==2)
|
|
||||||
sh_onoption(SH_LOGIN_SHELL);
|
|
||||||
if(strcmp(astconf("CONFORMANCE",0,0),"standard")==0)
|
|
||||||
sh_onoption(SH_POSIX);
|
|
||||||
if(strcmp(astconf("UNIVERSE",0,0),"att")==0)
|
|
||||||
sh_onoption(SH_XPG_ECHO);
|
|
||||||
else
|
|
||||||
sh_offoption(SH_XPG_ECHO);
|
|
||||||
if(strcmp(astconf("PATH_RESOLVE",0,0),"physical")==0)
|
|
||||||
sh_onoption(SH_PHYSICAL);
|
|
||||||
else
|
|
||||||
sh_offoption(SH_PHYSICAL);
|
|
||||||
|
|
||||||
/* add builtins */
|
|
||||||
sh_addbuiltin("shopt", b_shopt, &sh);
|
|
||||||
|
|
||||||
/* set up some variables needed for --version
|
|
||||||
* needs to go here because --version option is parsed before the init script.
|
|
||||||
*/
|
|
||||||
if(np=nv_open("HOSTTYPE",shp->var_tree,0))
|
|
||||||
nv_putval(np, BASH_HOSTTYPE, NV_NOFREE);
|
|
||||||
if(np=nv_open("MACHTYPE",shp->var_tree,0))
|
|
||||||
nv_putval(np, BASH_MACHTYPE, NV_NOFREE);
|
|
||||||
if(np=nv_open("BASH_VERSION",shp->var_tree,0))
|
|
||||||
nv_putval(np, BASH_VERSION, NV_NOFREE);
|
|
||||||
if(np=nv_open("BASH_VERSINFO",shp->var_tree,0))
|
|
||||||
{
|
|
||||||
char *argv[7];
|
|
||||||
argv[0] = BASH_MAJOR;
|
|
||||||
argv[1] = BASH_MINOR;
|
|
||||||
argv[2] = BASH_PATCH;
|
|
||||||
argv[3] = BASH_BUILD;
|
|
||||||
argv[4] = BASH_RELEASE;
|
|
||||||
argv[5] = BASH_MACHTYPE;
|
|
||||||
argv[6] = 0;
|
|
||||||
nv_setvec(np, 0, 6, argv);
|
|
||||||
nv_onattr(np,NV_RDONLY);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* rest of init stage */
|
|
||||||
|
|
||||||
/* restrict BASH_ENV */
|
|
||||||
if(np=nv_open("BASH_ENV",shp->var_tree,0))
|
|
||||||
{
|
|
||||||
const Namdisc_t *dp = nv_discfun(NV_DCRESTRICT);
|
|
||||||
Namfun_t *fp = calloc(dp->dsize,1);
|
|
||||||
fp->disc = dp;
|
|
||||||
nv_disc(np, fp, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* open GLOBIGNORE node */
|
|
||||||
if(np=nv_open("GLOBIGNORE",shp->var_tree,0))
|
|
||||||
{
|
|
||||||
const Namdisc_t *dp = &SH_GLOBIGNORE_disc;
|
|
||||||
Namfun_t *fp = calloc(dp->dsize,1);
|
|
||||||
fp->disc = dp;
|
|
||||||
nv_disc(np, fp, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* set startup files */
|
|
||||||
n=0;
|
|
||||||
if(sh_isoption(SH_LOGIN_SHELL))
|
|
||||||
{
|
|
||||||
if(!sh_isoption(SH_POSIX))
|
|
||||||
{
|
|
||||||
login_files[n++] = (char*)e_bash_profile;
|
|
||||||
login_files[n++] = (char*)e_bash_login;
|
|
||||||
}
|
|
||||||
login_files[n++] = (char*)e_profile;
|
|
||||||
}
|
|
||||||
shp->login_files = login_files;
|
|
||||||
reinit:
|
|
||||||
xtrace = sh_isoption(SH_XTRACE);
|
|
||||||
sh_offoption(SH_XTRACE);
|
|
||||||
verbose = sh_isoption(SH_VERBOSE);
|
|
||||||
sh_offoption(SH_VERBOSE);
|
|
||||||
if(np = nv_open("SHELLOPTS", shp->var_tree, NV_NOADD))
|
|
||||||
nv_offattr(np,NV_RDONLY);
|
|
||||||
iop = sfopen(NULL, bash_pre_rc, "s");
|
|
||||||
sh_eval(iop,0);
|
|
||||||
if(xtrace)
|
|
||||||
sh_offoption(SH_XTRACE);
|
|
||||||
if(verbose)
|
|
||||||
sh_offoption(SH_VERBOSE);
|
|
||||||
}
|
|
|
@ -96,10 +96,6 @@ int path_expand(Shell_t *shp,const char *pattern, struct argnod **arghead)
|
||||||
register struct argnod *ap;
|
register struct argnod *ap;
|
||||||
register glob_t *gp= &gdata;
|
register glob_t *gp= &gdata;
|
||||||
register int flags,extra=0;
|
register int flags,extra=0;
|
||||||
#if SHOPT_BASH
|
|
||||||
register int off;
|
|
||||||
register char *sp, *cp, *cp2;
|
|
||||||
#endif
|
|
||||||
sh_stats(STAT_GLOBS);
|
sh_stats(STAT_GLOBS);
|
||||||
memset(gp,0,sizeof(gdata));
|
memset(gp,0,sizeof(gdata));
|
||||||
flags = GLOB_GROUP|GLOB_AUGMENTED|GLOB_NOCHECK|GLOB_NOSORT|GLOB_STACK|GLOB_LIST|GLOB_DISC;
|
flags = GLOB_GROUP|GLOB_AUGMENTED|GLOB_NOCHECK|GLOB_NOSORT|GLOB_STACK|GLOB_LIST|GLOB_DISC;
|
||||||
|
@ -107,16 +103,6 @@ int path_expand(Shell_t *shp,const char *pattern, struct argnod **arghead)
|
||||||
flags |= GLOB_MARK;
|
flags |= GLOB_MARK;
|
||||||
if(sh_isoption(SH_GLOBSTARS))
|
if(sh_isoption(SH_GLOBSTARS))
|
||||||
flags |= GLOB_STARSTAR;
|
flags |= GLOB_STARSTAR;
|
||||||
#if SHOPT_BASH
|
|
||||||
#if 0
|
|
||||||
if(sh_isoption(SH_BASH) && !sh_isoption(SH_EXTGLOB))
|
|
||||||
flags &= ~GLOB_AUGMENTED;
|
|
||||||
#endif
|
|
||||||
if(sh_isoption(SH_NULLGLOB))
|
|
||||||
flags &= ~GLOB_NOCHECK;
|
|
||||||
if(sh_isoption(SH_NOCASEGLOB))
|
|
||||||
flags |= GLOB_ICASE;
|
|
||||||
#endif
|
|
||||||
if(sh_isstate(SH_COMPLETE))
|
if(sh_isstate(SH_COMPLETE))
|
||||||
{
|
{
|
||||||
#if KSHELL
|
#if KSHELL
|
||||||
|
@ -129,62 +115,6 @@ int path_expand(Shell_t *shp,const char *pattern, struct argnod **arghead)
|
||||||
flags |= GLOB_COMPLETE;
|
flags |= GLOB_COMPLETE;
|
||||||
flags &= ~GLOB_NOCHECK;
|
flags &= ~GLOB_NOCHECK;
|
||||||
}
|
}
|
||||||
#if SHOPT_BASH
|
|
||||||
if(off = staktell())
|
|
||||||
sp = stakfreeze(0);
|
|
||||||
if(sh_isoption(SH_BASH))
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* For bash, FIGNORE is a colon separated list of suffixes to
|
|
||||||
* ignore when doing filename/command completion.
|
|
||||||
* GLOBIGNORE is similar to ksh FIGNORE, but colon separated
|
|
||||||
* instead of being an augmented shell pattern.
|
|
||||||
* Generate shell patterns out of those here.
|
|
||||||
*/
|
|
||||||
if(sh_isstate(SH_FCOMPLETE))
|
|
||||||
cp=nv_getval(sh_scoped(shp,FIGNORENOD));
|
|
||||||
else
|
|
||||||
{
|
|
||||||
static Namval_t *GLOBIGNORENOD;
|
|
||||||
if(!GLOBIGNORENOD)
|
|
||||||
GLOBIGNORENOD = nv_open("GLOBIGNORE",shp->var_tree,0);
|
|
||||||
cp=nv_getval(sh_scoped(shp,GLOBIGNORENOD));
|
|
||||||
}
|
|
||||||
if(cp)
|
|
||||||
{
|
|
||||||
flags |= GLOB_AUGMENTED;
|
|
||||||
stakputs("@(");
|
|
||||||
if(!sh_isstate(SH_FCOMPLETE))
|
|
||||||
{
|
|
||||||
stakputs(cp);
|
|
||||||
for(cp=stakptr(off); *cp; cp++)
|
|
||||||
if(*cp == ':')
|
|
||||||
*cp='|';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cp2 = strtok(cp, ":");
|
|
||||||
if(!cp2)
|
|
||||||
cp2=cp;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
stakputc('*');
|
|
||||||
stakputs(cp2);
|
|
||||||
if(cp2 = strtok(NULL, ":"))
|
|
||||||
{
|
|
||||||
*(cp2-1)=':';
|
|
||||||
stakputc('|');
|
|
||||||
}
|
|
||||||
} while(cp2);
|
|
||||||
}
|
|
||||||
stakputc(')');
|
|
||||||
gp->gl_fignore = stakfreeze(1);
|
|
||||||
}
|
|
||||||
else if(!sh_isstate(SH_FCOMPLETE) && sh_isoption(SH_DOTGLOB))
|
|
||||||
gp->gl_fignore = "";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
gp->gl_fignore = nv_getval(sh_scoped(shp,FIGNORENOD));
|
gp->gl_fignore = nv_getval(sh_scoped(shp,FIGNORENOD));
|
||||||
if(suflen)
|
if(suflen)
|
||||||
gp->gl_suffix = sufstr;
|
gp->gl_suffix = sufstr;
|
||||||
|
@ -193,12 +123,6 @@ int path_expand(Shell_t *shp,const char *pattern, struct argnod **arghead)
|
||||||
if(memcmp(pattern,"~(N",3)==0)
|
if(memcmp(pattern,"~(N",3)==0)
|
||||||
flags &= ~GLOB_NOCHECK;
|
flags &= ~GLOB_NOCHECK;
|
||||||
glob(pattern, flags, 0, gp);
|
glob(pattern, flags, 0, gp);
|
||||||
#if SHOPT_BASH
|
|
||||||
if(off)
|
|
||||||
stakset(sp,off);
|
|
||||||
else
|
|
||||||
stakseek(0);
|
|
||||||
#endif
|
|
||||||
sh_sigcheck(shp);
|
sh_sigcheck(shp);
|
||||||
for(ap= (struct argnod*)gp->gl_list; ap; ap = ap->argnxt.ap)
|
for(ap= (struct argnod*)gp->gl_list; ap; ap = ap->argnxt.ap)
|
||||||
{
|
{
|
||||||
|
|
|
@ -87,10 +87,6 @@ char e_version[] = "\n@(#)$Id: Version "
|
||||||
#define ATTRS 1
|
#define ATTRS 1
|
||||||
"A"
|
"A"
|
||||||
#endif
|
#endif
|
||||||
#if SHOPT_BASH
|
|
||||||
#define ATTRS 1
|
|
||||||
"B"
|
|
||||||
#endif
|
|
||||||
#if SHOPT_BGX
|
#if SHOPT_BGX
|
||||||
#define ATTRS 1
|
#define ATTRS 1
|
||||||
"J"
|
"J"
|
||||||
|
@ -116,10 +112,6 @@ char e_version[] = "\n@(#)$Id: Version "
|
||||||
#endif
|
#endif
|
||||||
SH_RELEASE " $\0\n";
|
SH_RELEASE " $\0\n";
|
||||||
|
|
||||||
#if SHOPT_BASH
|
|
||||||
extern void bash_init(Shell_t*,int);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define RANDMASK 0x7fff
|
#define RANDMASK 0x7fff
|
||||||
|
|
||||||
#ifndef ARG_MAX
|
#ifndef ARG_MAX
|
||||||
|
@ -1103,7 +1095,7 @@ int sh_type(register const char *path)
|
||||||
}
|
}
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
if (!(t & (SH_TYPE_KSH|SH_TYPE_BASH)))
|
if (!(t & SH_TYPE_KSH))
|
||||||
{
|
{
|
||||||
if (*s == 'k')
|
if (*s == 'k')
|
||||||
{
|
{
|
||||||
|
@ -1111,14 +1103,6 @@ int sh_type(register const char *path)
|
||||||
t |= SH_TYPE_KSH;
|
t |= SH_TYPE_KSH;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#if SHOPT_BASH
|
|
||||||
if (*s == 'b' && *(s+1) == 'a')
|
|
||||||
{
|
|
||||||
s += 2;
|
|
||||||
t |= SH_TYPE_BASH;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
if (!(t & (SH_TYPE_PROFILE|SH_TYPE_RESTRICTED)))
|
if (!(t & (SH_TYPE_PROFILE|SH_TYPE_RESTRICTED)))
|
||||||
{
|
{
|
||||||
|
@ -1143,6 +1127,8 @@ int sh_type(register const char *path)
|
||||||
{
|
{
|
||||||
s++;
|
s++;
|
||||||
t |= SH_TYPE_SH;
|
t |= SH_TYPE_SH;
|
||||||
|
if (!(t & SH_TYPE_KSH))
|
||||||
|
t |= SH_TYPE_POSIX;
|
||||||
if ((t & SH_TYPE_KSH) && *s == '9' && *(s+1) == '3')
|
if ((t & SH_TYPE_KSH) && *s == '9' && *(s+1) == '3')
|
||||||
s += 2;
|
s += 2;
|
||||||
#if _WINIX
|
#if _WINIX
|
||||||
|
@ -1152,7 +1138,7 @@ int sh_type(register const char *path)
|
||||||
if (!isalnum(*s))
|
if (!isalnum(*s))
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
return t & ~(SH_TYPE_BASH|SH_TYPE_KSH|SH_TYPE_PROFILE|SH_TYPE_RESTRICTED);
|
return t & ~(SH_TYPE_KSH|SH_TYPE_PROFILE|SH_TYPE_RESTRICTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1315,6 +1301,8 @@ Shell_t *sh_init(register int argc,register char *argv[], Shinit_f userinit)
|
||||||
type = sh_type(*argv);
|
type = sh_type(*argv);
|
||||||
if(type&SH_TYPE_LOGIN)
|
if(type&SH_TYPE_LOGIN)
|
||||||
shp->login_sh = 2;
|
shp->login_sh = 2;
|
||||||
|
if(type&SH_TYPE_POSIX || strcmp(astconf("CONFORMANCE",0,0),"standard")==0)
|
||||||
|
sh_onoption(SH_POSIX);
|
||||||
}
|
}
|
||||||
env_init(shp);
|
env_init(shp);
|
||||||
if(!ENVNOD->nvalue.cp)
|
if(!ENVNOD->nvalue.cp)
|
||||||
|
@ -1378,17 +1366,6 @@ Shell_t *sh_init(register int argc,register char *argv[], Shinit_f userinit)
|
||||||
/* check for profile shell */
|
/* check for profile shell */
|
||||||
else if(type&SH_TYPE_PROFILE)
|
else if(type&SH_TYPE_PROFILE)
|
||||||
sh_onoption(SH_PFSH);
|
sh_onoption(SH_PFSH);
|
||||||
#endif
|
|
||||||
#if SHOPT_BASH
|
|
||||||
/* check for invocation as bash */
|
|
||||||
if(type&SH_TYPE_BASH)
|
|
||||||
{
|
|
||||||
shp>userinit = userinit = bash_init;
|
|
||||||
sh_onoption(SH_BASH);
|
|
||||||
sh_onstate(SH_PREINIT);
|
|
||||||
(*userinit)(shp, 0);
|
|
||||||
sh_offstate(SH_PREINIT);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
/* look for options */
|
/* look for options */
|
||||||
/* shp->st.dolc is $# */
|
/* shp->st.dolc is $# */
|
||||||
|
|
|
@ -576,13 +576,9 @@ int sh_lex(Lex_t* lp)
|
||||||
return(lp->token=c);
|
return(lp->token=c);
|
||||||
else if(c=='&')
|
else if(c=='&')
|
||||||
{
|
{
|
||||||
if(!sh_isoption(SH_POSIX) && n=='>' && (sh_isoption(SH_BASH) || sh_isstate(SH_PROFILE)))
|
if(n=='>' && !sh_isoption(SH_POSIX))
|
||||||
{
|
{
|
||||||
if(!sh_isoption(SH_BASH) && !lp->nonstandard)
|
/* bash-style "&>file" shorthand for ">file 2>&1" */
|
||||||
{
|
|
||||||
lp->nonstandard = 1;
|
|
||||||
errormsg(SH_DICT,ERROR_warn(0),e_lexnonstandard,shp->inlineno);
|
|
||||||
}
|
|
||||||
lp->digits = -1;
|
lp->digits = -1;
|
||||||
c = '>';
|
c = '>';
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,7 +163,6 @@ int sh_main(int ac, char *av[], Shinit_f userinit)
|
||||||
if((beenhere++)==0)
|
if((beenhere++)==0)
|
||||||
{
|
{
|
||||||
sh_onstate(SH_PROFILE);
|
sh_onstate(SH_PROFILE);
|
||||||
((Lex_t*)shp->lex_context)->nonstandard = 0;
|
|
||||||
if(shp->gd->ppid==1)
|
if(shp->gd->ppid==1)
|
||||||
shp->login_sh++;
|
shp->login_sh++;
|
||||||
if(shp->login_sh >= 2)
|
if(shp->login_sh >= 2)
|
||||||
|
@ -177,12 +176,14 @@ int sh_main(int ac, char *av[], Shinit_f userinit)
|
||||||
sh_onoption(SH_BGNICE);
|
sh_onoption(SH_BGNICE);
|
||||||
sh_onoption(SH_RC);
|
sh_onoption(SH_RC);
|
||||||
}
|
}
|
||||||
if(!sh_isoption(SH_RC) && (sh_isoption(SH_BASH) && !sh_isoption(SH_POSIX)
|
|
||||||
#if SHOPT_REMOTE
|
#if SHOPT_REMOTE
|
||||||
|| !fstat(0, &statb) && REMOTE(statb.st_mode)
|
/*
|
||||||
#endif
|
* Building ksh with SHOPT_REMOTE=1 causes ksh to set --rc if stdin is
|
||||||
))
|
* a socket (presumably part of a remote shell invocation.)
|
||||||
|
*/
|
||||||
|
if(!sh_isoption(SH_RC) && !fstat(0, &statb) && REMOTE(statb.st_mode))
|
||||||
sh_onoption(SH_RC);
|
sh_onoption(SH_RC);
|
||||||
|
#endif
|
||||||
for(i=0; i<elementsof(shp->offoptions.v); i++)
|
for(i=0; i<elementsof(shp->offoptions.v); i++)
|
||||||
shp->options.v[i] &= ~shp->offoptions.v[i];
|
shp->options.v[i] &= ~shp->offoptions.v[i];
|
||||||
if(sh_isoption(SH_INTERACTIVE))
|
if(sh_isoption(SH_INTERACTIVE))
|
||||||
|
@ -212,28 +213,16 @@ int sh_main(int ac, char *av[], Shinit_f userinit)
|
||||||
{
|
{
|
||||||
if(!sh_isoption(SH_NOUSRPROFILE) && !sh_isoption(SH_PRIVILEGED) && sh_isoption(SH_RC))
|
if(!sh_isoption(SH_NOUSRPROFILE) && !sh_isoption(SH_PRIVILEGED) && sh_isoption(SH_RC))
|
||||||
{
|
{
|
||||||
#if SHOPT_BASH
|
if(name = sh_mactry(shp,nv_getval(ENVNOD)))
|
||||||
if(sh_isoption(SH_BASH) && !sh_isoption(SH_POSIX))
|
name = *name ? strdup(name) : (char*)0;
|
||||||
{
|
|
||||||
#if SHOPT_SYSRC
|
#if SHOPT_SYSRC
|
||||||
sh_source(shp, iop, e_bash_sysrc);
|
if(!strmatch(name, "?(.)/./*"))
|
||||||
#endif
|
sh_source(shp, iop, e_sysrc);
|
||||||
sh_source(shp, iop, shp->gd->rcfile ? shp->gd->rcfile : sh_mactry(shp,(char*)e_bash_rc));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
#endif
|
||||||
|
if(name)
|
||||||
{
|
{
|
||||||
if(name = sh_mactry(shp,nv_getval(ENVNOD)))
|
sh_source(shp, iop, name);
|
||||||
name = *name ? strdup(name) : (char*)0;
|
free(name);
|
||||||
#if SHOPT_SYSRC
|
|
||||||
if(!strmatch(name, "?(.)/./*"))
|
|
||||||
sh_source(shp, iop, e_sysrc);
|
|
||||||
#endif
|
|
||||||
if(name)
|
|
||||||
{
|
|
||||||
sh_source(shp, iop, name);
|
|
||||||
free(name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(sh_isoption(SH_INTERACTIVE) && sh_isoption(SH_PRIVILEGED))
|
else if(sh_isoption(SH_INTERACTIVE) && sh_isoption(SH_PRIVILEGED))
|
||||||
|
|
|
@ -549,7 +549,7 @@ void nv_setlist(register struct argnod *arg,register int flags, Namval_t *typ)
|
||||||
{
|
{
|
||||||
if(!(arg->argflag&ARG_APPEND))
|
if(!(arg->argflag&ARG_APPEND))
|
||||||
_nv_unset(np,NV_EXPORT);
|
_nv_unset(np,NV_EXPORT);
|
||||||
if(!sh_isoption(SH_BASH) && !(array&NV_IARRAY) && !nv_isarray(np))
|
if(!(array&NV_IARRAY) && !nv_isarray(np))
|
||||||
nv_setarray(np,nv_associative);
|
nv_setarray(np,nv_associative);
|
||||||
}
|
}
|
||||||
skip:
|
skip:
|
||||||
|
|
|
@ -1086,19 +1086,6 @@ int sh_exec(register const Shnode_t *t, int flags)
|
||||||
}
|
}
|
||||||
if(np)
|
if(np)
|
||||||
flgs |= NV_UNJUST;
|
flgs |= NV_UNJUST;
|
||||||
#if SHOPT_BASH
|
|
||||||
if(np==SYSLOCAL)
|
|
||||||
{
|
|
||||||
if(!nv_getval(SH_FUNNAMENOD))
|
|
||||||
errormsg(SH_DICT,ERROR_exit(1),"%s: can only be used in a function",com0);
|
|
||||||
if(!shp->st.var_local)
|
|
||||||
{
|
|
||||||
sh_scope(shp,(struct argnod*)0,0);
|
|
||||||
shp->st.var_local = shp->var_tree;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif /* SHOPT_BASH */
|
|
||||||
if(np && np->nvalue.bfp==SYSTYPESET->nvalue.bfp)
|
if(np && np->nvalue.bfp==SYSTYPESET->nvalue.bfp)
|
||||||
{
|
{
|
||||||
/* command calls b_typeset(); treat as a typeset variant */
|
/* command calls b_typeset(); treat as a typeset variant */
|
||||||
|
@ -1134,7 +1121,7 @@ int sh_exec(register const Shnode_t *t, int flags)
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif /* SHOPT_TYPEDEF */
|
#endif /* SHOPT_TYPEDEF */
|
||||||
if((shp->fn_depth && !shp->prefix) || np==SYSLOCAL)
|
if((shp->fn_depth && !shp->prefix))
|
||||||
flgs |= NV_NOSCOPE;
|
flgs |= NV_NOSCOPE;
|
||||||
}
|
}
|
||||||
else if(np==SYSEXPORT)
|
else if(np==SYSEXPORT)
|
||||||
|
|
|
@ -597,5 +597,24 @@ then trap 'sleep_pid=0; kill "$ksh_pid"; err_exit "'\''read'\'' hangs on EOF wit
|
||||||
else err_exit "mkfifo failed; cannot test reading from FIFO"
|
else err_exit "mkfifo failed; cannot test reading from FIFO"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# ======
|
||||||
|
# "&>file" redirection operator, shorthand for ">file 2>&1" (new as of 93u+m; inherited from old SHOPT_BASH)
|
||||||
|
if [[ -o ?posix ]]
|
||||||
|
then set -o posix
|
||||||
|
# This should print in a background job, then create an empty file, as '>aha1.txt' is a separate command.
|
||||||
|
eval ' print -u1 bad1 &>aha1.txt
|
||||||
|
print -u2 bad2 &>aha2.txt
|
||||||
|
' >/dev/null 2>&1
|
||||||
|
[[ -s aha1.txt ]] && err_exit "&> not deactivated in POSIX mode (stdout; got '$(cat aha1.txt)')"
|
||||||
|
[[ -s aha2.txt ]] && err_exit "&> not deactivated in POSIX mode (stderr; got '$(cat aha2.txt)')"
|
||||||
|
set +o posix
|
||||||
|
# This should write the text to the file.
|
||||||
|
eval ' print -u1 ok1 &>aha1.txt
|
||||||
|
print -u2 ok2 &>aha2.txt
|
||||||
|
' >/dev/null 2>&1
|
||||||
|
[[ $(< aha1.txt) == ok1 ]] || err_exit '&> does not redirect stdout'
|
||||||
|
[[ $(< aha2.txt) == ok2 ]] || err_exit '&> does not redirect stderr'
|
||||||
|
fi
|
||||||
|
|
||||||
# ======
|
# ======
|
||||||
exit $((Errors<125?Errors:125))
|
exit $((Errors<125?Errors:125))
|
||||||
|
|
|
@ -53,28 +53,9 @@ then err_exit 'sh -e not working'
|
||||||
fi
|
fi
|
||||||
[[ $($SHELL -D -c 'print hi; print $"hello"') == '"hello"' ]] || err_exit 'ksh -D not working'
|
[[ $($SHELL -D -c 'print hi; print $"hello"') == '"hello"' ]] || err_exit 'ksh -D not working'
|
||||||
|
|
||||||
env=$tmp/.env
|
|
||||||
print $'(print -u1 aha) &>/dev/null\n(print -u2 aha) &>/dev/null' > $env
|
|
||||||
rc=$tmp/.kshrc
|
rc=$tmp/.kshrc
|
||||||
print $'PS1=""\nfunction env_hit\n{\n\tprint OK\n}' > $rc
|
print $'PS1=""\nfunction env_hit\n{\n\tprint OK\n}' > $rc
|
||||||
|
|
||||||
export ENV=/.$env
|
|
||||||
if [[ ! -o privileged ]]
|
|
||||||
then
|
|
||||||
got=$($SHELL -E -c : 2>/dev/null)
|
|
||||||
if [[ $g ]]
|
|
||||||
then
|
|
||||||
got=$(printf %q "$got")
|
|
||||||
err_exit "\$ENV file &>/dev/null does not redirect stdout -- expected '', got $got"
|
|
||||||
fi
|
|
||||||
got=$(set +x; $SHELL -E -c : 2>&1 >/dev/null)
|
|
||||||
if [[ $got != *nonstandard* || $got == *$'\n'* ]]
|
|
||||||
then
|
|
||||||
got=$(printf %q "$got")
|
|
||||||
err_exit "\$ENV file &>/dev/null does not redirect stderr -- expected one diagnostic line, got $got"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
export ENV=/.$rc
|
export ENV=/.$rc
|
||||||
if [[ -o privileged ]]
|
if [[ -o privileged ]]
|
||||||
then
|
then
|
||||||
|
|
Loading…
Reference in a new issue