diff options
Diffstat (limited to 'usr/src/lib/libshell/common/sh/init.c')
-rw-r--r-- | usr/src/lib/libshell/common/sh/init.c | 165 |
1 files changed, 130 insertions, 35 deletions
diff --git a/usr/src/lib/libshell/common/sh/init.c b/usr/src/lib/libshell/common/sh/init.c index 0bd2f92b79..7371b8de98 100644 --- a/usr/src/lib/libshell/common/sh/init.c +++ b/usr/src/lib/libshell/common/sh/init.c @@ -1,7 +1,7 @@ /*********************************************************************** * * * This software is part of the ast package * -* Copyright (c) 1982-2008 AT&T Intellectual Property * +* Copyright (c) 1982-2009 AT&T Intellectual Property * * and is licensed under the * * Common Public License, Version 1.0 * * by AT&T Intellectual Property * @@ -29,7 +29,6 @@ #include "defs.h" #include <stak.h> -#include <ctype.h> #include <ccode.h> #include <pwd.h> #include <tmx.h> @@ -44,6 +43,7 @@ #include "builtins.h" #include "FEATURE/time" #include "FEATURE/dynamic" +#include "FEATURE/externs" #include "lexstates.h" #include "version.h" @@ -56,6 +56,10 @@ char e_version[] = "\n@(#)$Id: Version " #define ATTRS 1 "B" #endif +#if SHOPT_BGX +#define ATTRS 1 + "J" +#endif #if SHOPT_ACCT #define ATTRS 1 "L" @@ -68,6 +72,10 @@ char e_version[] = "\n@(#)$Id: Version " #define ATTRS 1 "P" #endif +#if SHOPT_REGRESS +#define ATTRS 1 + "R" +#endif #if ATTRS " " #endif @@ -162,6 +170,7 @@ static int nbltins; static void env_init(Shell_t*); static Init_t *nv_init(Shell_t*); static Dt_t *inittree(Shell_t*,const struct shtable2*); +static int shlvl; #ifdef _WINIX # define EXE "?(.exe)" @@ -195,22 +204,27 @@ static char *nospace(int unused) static void put_ed(register Namval_t* np,const char *val,int flags,Namfun_t *fp) { register const char *cp, *name=nv_name(np); + register int newopt=0; Shell_t *shp = nv_shell(np); if(*name=='E' && nv_getval(sh_scoped(shp,VISINOD))) goto done; - sh_offoption(SH_VI); - sh_offoption(SH_EMACS); - sh_offoption(SH_GMACS); if(!(cp=val) && (*name=='E' || !(cp=nv_getval(sh_scoped(shp,EDITNOD))))) goto done; /* turn on vi or emacs option if editor name is either*/ cp = path_basename(cp); if(strmatch(cp,"*[Vv][Ii]*")) - sh_onoption(SH_VI); + newopt=SH_VI; else if(strmatch(cp,"*gmacs*")) - sh_onoption(SH_GMACS); + newopt=SH_GMACS; else if(strmatch(cp,"*macs*")) - sh_onoption(SH_EMACS); + newopt=SH_EMACS; + if(newopt) + { + sh_offoption(SH_VI); + sh_offoption(SH_EMACS); + sh_offoption(SH_GMACS); + sh_onoption(newopt); + } done: nv_putv(np, val, flags, fp); } @@ -220,11 +234,12 @@ static void put_history(register Namval_t* np,const char *val,int flags,Namfun_t { Shell_t *shp = nv_shell(np); void *histopen = shp->hist_ptr; + char *cp; if(val && histopen) { - if(np==HISTFILE && strcmp(val,nv_getval(HISTFILE))==0) + if(np==HISTFILE && (cp=nv_getval(np)) && strcmp(val,cp)==0) return; - if(np==HISTSIZE && sh_arith(val)==nv_getnum(HISTSIZE)) + if(np==HISTSIZE && sh_arith(val)==nv_getnum(HISTSIZE)) return; hist_close(shp->hist_ptr); } @@ -340,13 +355,17 @@ static void put_cdpath(register Namval_t* np,const char *val,int flags,Namfun_t } #endif - /* Trap for LC_ALL, LC_TYPE, LC_MESSAGES, LC_COLLATE and LANG */ + /* Trap for LC_ALL, LC_CTYPE, LC_MESSAGES, LC_COLLATE and LANG */ static void put_lang(Namval_t* np,const char *val,int flags,Namfun_t *fp) { Shell_t *shp = nv_shell(np); int type; char *lc_all = nv_getval(LCALLNOD); char *name = nv_name(np); + if((shp->test&1) && !val && !nv_getval(np)) + return; + if(shp->test&2) + nv_putv(np, val, flags, fp); if(name==(LCALLNOD)->nvname) type = LC_ALL; else if(name==(LCTYPENOD)->nvname) @@ -357,22 +376,30 @@ static void put_cdpath(register Namval_t* np,const char *val,int flags,Namfun_t type = LC_COLLATE; else if(name==(LCNUMNOD)->nvname) type = LC_NUMERIC; - else if(name==(LANGNOD)->nvname && (!lc_all || *lc_all==0)) - type = LC_ALL; +#ifdef LC_LANG + else if(name==(LANGNOD)->nvname) + type = LC_LANG; +#else +#define LC_LANG LC_ALL + else if(name==(LANGNOD)->nvname && (!lc_all || !*lc_all)) + type = LC_LANG; +#endif else type= -1; if(sh_isstate(SH_INIT) && type>=0 && type!=LC_ALL && lc_all && *lc_all) type= -1; - if(type>=0 || type==LC_ALL) + if(type>=0 || type==LC_ALL || type==LC_LANG) { - if(!setlocale(type,val?val:"")) + if(!setlocale(type,val?val:"-") && val) { if(!sh_isstate(SH_INIT) || shp->login_sh==0) errormsg(SH_DICT,0,e_badlocale,val); return; } } - if(CC_NATIVE==CC_ASCII && (type==LC_ALL || type==LC_CTYPE)) + if(!(shp->test&2)) + nv_putv(np, val, flags, fp); + if(CC_NATIVE==CC_ASCII && (type==LC_ALL || type==LC_LANG || type==LC_CTYPE)) { if(sh_lexstates[ST_BEGIN]!=sh_lexrstates[ST_BEGIN]) free((void*)sh_lexstates[ST_BEGIN]); @@ -423,7 +450,6 @@ static void put_cdpath(register Namval_t* np,const char *val,int flags,Namfun_t if(type==LC_ALL || type==LC_MESSAGES) error_info.translate = msg_translate; #endif - nv_putv(np, val, flags, fp); } #endif /* _hdr_locale */ @@ -431,10 +457,18 @@ static void put_cdpath(register Namval_t* np,const char *val,int flags,Namfun_t static void put_ifs(register Namval_t* np,const char *val,int flags,Namfun_t *fp) { register struct ifs *ip = (struct ifs*)fp; + Shell_t *shp; ip->ifsnp = 0; + if(!val) + { + fp = nv_stack(np, NIL(Namfun_t*)); + if(fp && !fp->nofree) + free((void*)fp); + } if(val != np->nvalue.cp) nv_putv(np, val, flags, fp); - + if(!val && !(flags&NV_CLONE) && (fp=np->nvfun) && !fp->disc && (shp=(Shell_t*)(fp->last))) + nv_stack(np,&((Init_t*)shp->init_context)->IFS_init.hdr); } /* @@ -505,8 +539,10 @@ static void put_seconds(register Namval_t* np,const char *val,int flags,Namfun_t struct tms tp; if(!val) { - nv_stack(np, NIL(Namfun_t*)); - nv_unset(np); + fp = nv_stack(np, NIL(Namfun_t*)); + if(fp && !fp->nofree) + free((void*)fp); + nv_putv(np, val, flags, fp); return; } if(!np->nvalue.dp) @@ -552,7 +588,9 @@ static void put_rand(register Namval_t* np,const char *val,int flags,Namfun_t *f register long n; if(!val) { - nv_stack(np, NIL(Namfun_t*)); + fp = nv_stack(np, NIL(Namfun_t*)); + if(fp && !fp->nofree) + free((void*)fp); nv_unset(np); return; } @@ -608,7 +646,9 @@ static void put_lineno(Namval_t* np,const char *val,int flags,Namfun_t *fp) Shell_t *shp = nv_shell(np); if(!val) { - nv_stack(np, NIL(Namfun_t*)); + fp = nv_stack(np, NIL(Namfun_t*)); + if(fp && !fp->nofree) + free((void*)fp); nv_unset(np); return; } @@ -627,8 +667,11 @@ static char* get_lineno(register Namval_t* np, Namfun_t *fp) static char* get_lastarg(Namval_t* np, Namfun_t *fp) { - Shell_t *shp = nv_shell(np); - NOT_USED(np); + Shell_t *shp = nv_shell(np); + char *cp; + int pid; + if(sh_isstate(SH_INIT) && (cp=shp->lastarg) && *cp=='*' && (pid=strtol(cp+1,&cp,10)) && *cp=='*') + nv_putval(np,(pid==getppid()?cp+1:0),0); return(shp->lastarg); } @@ -640,14 +683,15 @@ static void put_lastarg(Namval_t* np,const char *val,int flags,Namfun_t *fp) sfprintf(shp->strbuf,"%.*g",12,*((double*)val)); val = sfstruse(shp->strbuf); } + if(val) + val = strdup(val); if(shp->lastarg && !nv_isattr(np,NV_NOFREE)) free((void*)shp->lastarg); else nv_offattr(np,NV_NOFREE); - if(val) - shp->lastarg = strdup(val); - else - shp->lastarg = 0; + shp->lastarg = (char*)val; + nv_offattr(np,NV_EXPORT); + np->nvenv = 0; } static int hasgetdisc(register Namfun_t *fp) @@ -979,6 +1023,7 @@ Shell_t *sh_init(register int argc,register char *argv[], Shinit_f userinit) register int n; int type; static char *login_files[3]; + memfatal(); n = strlen(e_version); if(e_version[n-1]=='$' && e_version[n-2]==' ') e_version[n-2]=0; @@ -1001,6 +1046,41 @@ Shell_t *sh_init(register int argc,register char *argv[], Shinit_f userinit) #if ERROR_VERSION >= 20000102L error_info.catalog = e_dict; #endif +#if SHOPT_REGRESS + { + Opt_t* nopt; + Opt_t* oopt; + char* a; + char** av = argv; + char* regress[3]; + + sh_regress_init(shp); + regress[0] = "__regress__"; + regress[2] = 0; + /* NOTE: only shp is used by __regress__ at this point */ + shp->bltindata.shp = shp; + while ((a = *++av) && a[0] == '-' && (a[1] == 'I' || a[1] == '-' && a[2] == 'r')) + { + if (a[1] == 'I') + { + if (a[2]) + regress[1] = a + 2; + else if (!(regress[1] = *++av)) + break; + } + else if (strncmp(a+2, "regress", 7)) + break; + else if (a[9] == '=') + regress[1] = a + 10; + else if (!(regress[1] = *++av)) + break; + nopt = optctx(0, 0); + oopt = optctx(nopt, 0); + b___regress__(2, regress, &shp->bltindata); + optctx(oopt, nopt); + } + } +#endif shp->cpipe[0] = -1; shp->coutpipe = -1; shp->userid=getuid(); @@ -1051,6 +1131,11 @@ Shell_t *sh_init(register int argc,register char *argv[], Shinit_f userinit) shp->login_sh = 2; } env_init(shp); + if(!ENVNOD->nvalue.cp) + { + sfprintf(shp->strbuf,"%s/.kshrc",nv_getval(HOME)); + nv_putval(ENVNOD,sfstruse(shp->strbuf),NV_RDONLY); + } *SHLVL->nvalue.ip +=1; #if SHOPT_SPAWN { @@ -1058,15 +1143,20 @@ Shell_t *sh_init(register int argc,register char *argv[], Shinit_f userinit) * try to find the pathname for this interpreter * try using environment variable _ or argv[0] */ - char *last, *cp=nv_getval(L_ARGNOD); + char *cp=nv_getval(L_ARGNOD); char buff[PATH_MAX+1]; shp->shpath = 0; +#if _AST_VERSION >= 20090202L + if((n = pathprog(NiL, buff, sizeof(buff))) > 0 && n <= sizeof(buff)) + shp->shpath = strdup(buff); +#else sfprintf(shp->strbuf,"/proc/%d/exe",getpid()); if((n=readlink(sfstruse(shp->strbuf),buff,sizeof(buff)-1))>0) { buff[n] = 0; shp->shpath = strdup(buff); } +#endif else if((cp && (sh_type(cp)&SH_TYPE_SH)) || (argc>0 && strchr(cp= *argv,'/'))) { if(*cp=='/') @@ -1168,17 +1258,16 @@ Shell_t *sh_init(register int argc,register char *argv[], Shinit_f userinit) /* set[ug]id scripts require the -p flag */ if(shp->userid!=shp->euserid || shp->groupid!=shp->egroupid) { -#if SHOPT_P_SUID +#ifdef SHOPT_P_SUID /* require sh -p to run setuid and/or setgid */ - if(!sh_isoption(SH_PRIVILEGED) && shp->euserid < SHOPT_P_SUID) + if(!sh_isoption(SH_PRIVILEGED) && shp->userid >= SHOPT_P_SUID) { setuid(shp->euserid=shp->userid); setgid(shp->egroupid=shp->groupid); } else -#else - sh_onoption(SH_PRIVILEGED); #endif /* SHOPT_P_SUID */ + sh_onoption(SH_PRIVILEGED); #ifdef SHELLMAGIC /* careful of #! setuid scripts with name beginning with - */ if(shp->login_sh && argv[1] && strcmp(argv[0],argv[1])==0) @@ -1305,7 +1394,14 @@ int sh_reinit(char *argv[]) sh_offstate(SH_FORKED); shp->fn_depth = shp->dot_depth = 0; sh_sigreset(0); + if(!(SHLVL->nvalue.ip)) + { + shlvl = 0; + SHLVL->nvalue.ip = &shlvl; + nv_onattr(SHLVL,NV_INTEGER|NV_EXPORT|NV_NOFREE); + } *SHLVL->nvalue.ip +=1; + shp->st.filename = strdup(shp->lastarg); return(1); } @@ -1314,7 +1410,7 @@ int sh_reinit(char *argv[]) */ Namfun_t *nv_cover(register Namval_t *np) { - if(np==IFSNOD || np==PATHNOD || np==SHELLNOD || np==FPATHNOD || np==CDPNOD || np==SECONDS) + if(np==IFSNOD || np==PATHNOD || np==SHELLNOD || np==FPATHNOD || np==CDPNOD || np==SECONDS || np==ENVNOD) return(np->nvfun); #ifdef _hdr_locale if(np==LCALLNOD || np==LCTYPENOD || np==LCMSGNOD || np==LCCOLLNOD || np==LCNUMNOD || np==LANGNOD) @@ -1433,7 +1529,6 @@ static void stat_init(Shell_t *shp) */ static Init_t *nv_init(Shell_t *shp) { - static int shlvl=0; Namval_t *np; register Init_t *ip; double d=0; |