1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-03-09 15:50:02 +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:
Martijn Dekker 2020-09-01 06:19:19 +01:00
parent 84331a96fc
commit 921bbcaeb7
25 changed files with 95 additions and 1148 deletions

View file

@ -42,11 +42,6 @@
#else
# define PFSHOPT
#endif
#if SHOPT_BASH
# define BASHOPT "\374"
#else
# define BASHOPT
#endif
#if SHOPT_HISTEXPAND
# define HFLAG "H"
#else
@ -59,15 +54,13 @@
static char *null;
/* 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[] =
{
#if SHOPT_PFSH
SH_PFSH,
#endif
#if SHOPT_BASH
SH_POSIX,
#endif
SH_DICTIONARY, SH_INTERACTIVE, SH_RESTRICTED, SH_CFLAG,
SH_ALLEXPORT, SH_NOTIFY, SH_ERREXIT, SH_NOGLOB, SH_TRACKALL,
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)
{
#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!=':')
sfputr(sp,sh_set,-1);
return(1);
@ -168,31 +145,17 @@ int sh_argopts(int argc,register char *argv[], void *context)
if(f)
nv_unset(np);
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 */
byname:
if(!opt_info.arg||!*opt_info.arg||*opt_info.arg=='-')
{
action = PRINT;
/* print style: -O => shopt options
* bash => print unset options also, no heading
*/
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);
continue;
}
o = sh_lookopt(opt_info.arg,&f);
if(o<=0
|| (!sh_isoption(SH_BASH) && (o&SH_BASHEXTRA))
|| ((!sh_isoption(SH_BASH) || n=='o') && (o&SH_BASHOPT))
|| (setflag && (o&SH_COMMANDLINE)))
if(o<=0 || (setflag && (o&SH_COMMANDLINE)))
{
errormsg(SH_DICT,2, e_option, opt_info.arg);
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)
errormsg(SH_DICT,ERROR_exit(1), e_restricted, opt_info.arg);
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 */
{
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))
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;
}
@ -647,23 +554,11 @@ void sh_printopts(Shopt_t oflags,register int mode, Shopt_t *mask)
on_option(&oflags,SH_VIRAW);
#endif
if(!(mode&(PRINT_ALL|PRINT_VERBOSE))) /* only print set options */
{
if(mode&PRINT_SHOPT)
sfwrite(sfstdout,"shopt -s",3);
else
sfwrite(sfstdout,"set --default",13);
}
sfwrite(sfstdout,"set --default",13);
for(tp=shtab_options; value=tp->sh_number; tp++)
{
if(mask && !is_option(mask,value&0xff))
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);
name = tp->sh_name;
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');
}
else if(mode&PRINT_ALL) /* print unset options also */
{
if(mode&PRINT_SHOPT)
sfprintf(sfstdout, "shopt -%c %s\n",
on?'s':'u',
name);
else
sfprintf(sfstdout, "set %co %s\n",
on?'-':'+',
name);
}
sfprintf(sfstdout, "set %co %s\n", on?'-':'+', name);
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)))
sfputc(sfstdout,'\n');

View file

@ -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);
}

View file

@ -96,10 +96,6 @@ int path_expand(Shell_t *shp,const char *pattern, struct argnod **arghead)
register struct argnod *ap;
register glob_t *gp= &gdata;
register int flags,extra=0;
#if SHOPT_BASH
register int off;
register char *sp, *cp, *cp2;
#endif
sh_stats(STAT_GLOBS);
memset(gp,0,sizeof(gdata));
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;
if(sh_isoption(SH_GLOBSTARS))
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 KSHELL
@ -129,62 +115,6 @@ int path_expand(Shell_t *shp,const char *pattern, struct argnod **arghead)
flags |= GLOB_COMPLETE;
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));
if(suflen)
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)
flags &= ~GLOB_NOCHECK;
glob(pattern, flags, 0, gp);
#if SHOPT_BASH
if(off)
stakset(sp,off);
else
stakseek(0);
#endif
sh_sigcheck(shp);
for(ap= (struct argnod*)gp->gl_list; ap; ap = ap->argnxt.ap)
{

View file

@ -87,10 +87,6 @@ char e_version[] = "\n@(#)$Id: Version "
#define ATTRS 1
"A"
#endif
#if SHOPT_BASH
#define ATTRS 1
"B"
#endif
#if SHOPT_BGX
#define ATTRS 1
"J"
@ -116,10 +112,6 @@ char e_version[] = "\n@(#)$Id: Version "
#endif
SH_RELEASE " $\0\n";
#if SHOPT_BASH
extern void bash_init(Shell_t*,int);
#endif
#define RANDMASK 0x7fff
#ifndef ARG_MAX
@ -1103,7 +1095,7 @@ int sh_type(register const char *path)
}
for (;;)
{
if (!(t & (SH_TYPE_KSH|SH_TYPE_BASH)))
if (!(t & SH_TYPE_KSH))
{
if (*s == 'k')
{
@ -1111,14 +1103,6 @@ int sh_type(register const char *path)
t |= SH_TYPE_KSH;
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)))
{
@ -1143,6 +1127,8 @@ int sh_type(register const char *path)
{
s++;
t |= SH_TYPE_SH;
if (!(t & SH_TYPE_KSH))
t |= SH_TYPE_POSIX;
if ((t & SH_TYPE_KSH) && *s == '9' && *(s+1) == '3')
s += 2;
#if _WINIX
@ -1152,7 +1138,7 @@ int sh_type(register const char *path)
if (!isalnum(*s))
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);
if(type&SH_TYPE_LOGIN)
shp->login_sh = 2;
if(type&SH_TYPE_POSIX || strcmp(astconf("CONFORMANCE",0,0),"standard")==0)
sh_onoption(SH_POSIX);
}
env_init(shp);
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 */
else if(type&SH_TYPE_PROFILE)
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
/* look for options */
/* shp->st.dolc is $# */

View file

@ -576,13 +576,9 @@ int sh_lex(Lex_t* lp)
return(lp->token=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)
{
lp->nonstandard = 1;
errormsg(SH_DICT,ERROR_warn(0),e_lexnonstandard,shp->inlineno);
}
/* bash-style "&>file" shorthand for ">file 2>&1" */
lp->digits = -1;
c = '>';
}

View file

@ -163,7 +163,6 @@ int sh_main(int ac, char *av[], Shinit_f userinit)
if((beenhere++)==0)
{
sh_onstate(SH_PROFILE);
((Lex_t*)shp->lex_context)->nonstandard = 0;
if(shp->gd->ppid==1)
shp->login_sh++;
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_RC);
}
if(!sh_isoption(SH_RC) && (sh_isoption(SH_BASH) && !sh_isoption(SH_POSIX)
#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);
#endif
for(i=0; i<elementsof(shp->offoptions.v); i++)
shp->options.v[i] &= ~shp->offoptions.v[i];
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 SHOPT_BASH
if(sh_isoption(SH_BASH) && !sh_isoption(SH_POSIX))
{
if(name = sh_mactry(shp,nv_getval(ENVNOD)))
name = *name ? strdup(name) : (char*)0;
#if SHOPT_SYSRC
sh_source(shp, iop, e_bash_sysrc);
#endif
sh_source(shp, iop, shp->gd->rcfile ? shp->gd->rcfile : sh_mactry(shp,(char*)e_bash_rc));
}
else
if(!strmatch(name, "?(.)/./*"))
sh_source(shp, iop, e_sysrc);
#endif
if(name)
{
if(name = sh_mactry(shp,nv_getval(ENVNOD)))
name = *name ? strdup(name) : (char*)0;
#if SHOPT_SYSRC
if(!strmatch(name, "?(.)/./*"))
sh_source(shp, iop, e_sysrc);
#endif
if(name)
{
sh_source(shp, iop, name);
free(name);
}
sh_source(shp, iop, name);
free(name);
}
}
else if(sh_isoption(SH_INTERACTIVE) && sh_isoption(SH_PRIVILEGED))

View file

@ -549,7 +549,7 @@ void nv_setlist(register struct argnod *arg,register int flags, Namval_t *typ)
{
if(!(arg->argflag&ARG_APPEND))
_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);
}
skip:

View file

@ -1086,19 +1086,6 @@ int sh_exec(register const Shnode_t *t, int flags)
}
if(np)
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)
{
/* 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 */
if((shp->fn_depth && !shp->prefix) || np==SYSLOCAL)
if((shp->fn_depth && !shp->prefix))
flgs |= NV_NOSCOPE;
}
else if(np==SYSEXPORT)