summaryrefslogtreecommitdiff
path: root/usr/src/lib/libshell/common/sh/init.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libshell/common/sh/init.c')
-rw-r--r--usr/src/lib/libshell/common/sh/init.c165
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;