static void put_classval(Namval_t* np, const char* val, int flag, Namfun_t* nfp) { walk_class(np,1,(struct dcclass *)nfp); if(nfp = nv_stack(np,(Namfun_t*)0)) { free((void*)nfp); if(np->nvalue && !nv_isattr(np,NV_NOFREE)) free((void*)np->nvalue); } if(val) nv_putval(np,val,flag); }
static Namval_t *sh_newnode(register Shfield_t *fp, Namval_t *np) { char *val = np->nvalue + fp->offset; char *name = nv_name(np); register Namval_t *nq; int offset = stktell(stkstd); sfprintf(stkstd,"%s.%s\0",name,fp->name); sfputc(stkstd,0); nq = nv_search(stkptr(stkstd,offset),sh.var_tree,NV_ADD); if(fp->size<0) val = *(char**)val; nv_putval(nq,val,fp->flags|NV_NOFREE); if(fp->make) (*fp->make)(nq); return(nq); }
static int acctinit(History_t *hp) { register char *cp, *acctfile; Namval_t *np = nv_search("ACCTFILE",((Shell_t*)hp->histshell)->var_tree,0); if(!np || !(acctfile=nv_getval(np))) return(0); if(!(cp = getlogin())) { struct passwd *userinfo = getpwuid(getuid()); if(userinfo) cp = userinfo->pw_name; else cp = "unknown"; } logname = strdup(cp); if((acctfd=sh_open(acctfile, O_BINARY|O_WRONLY|O_APPEND|O_CREAT,S_IRUSR|S_IWUSR))>=0 && (unsigned)acctfd < 10) { int n; if((n = fcntl(acctfd, F_DUPFD, 10)) >= 0) { close(acctfd); acctfd = n; } } if(acctfd < 0) { acctfd = 0; return(0); } if(sh_isdevfd(acctfile)) { char newfile[16]; sfsprintf(newfile,sizeof(newfile),"%.8s%d\0",e_devfdNN,acctfd); nv_putval(np,newfile,NV_RDONLY); } else fcntl(acctfd,F_SETFD,FD_CLOEXEC); return(1); }
void bash_init(int mode) { Shell_t *shp = &sh; 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); }
int sh_main(int ac, char *av[], Shinit_f userinit) { register char *name; register int fdin; register Sfio_t *iop; register Shell_t *shp; struct stat statb; int i, rshflag; /* set for restricted shell */ char *command; free(malloc(64*1024)); #ifdef _lib_sigvec /* This is to clear mask that may be left on by rlogin */ clearsigmask(SIGALRM); clearsigmask(SIGHUP); clearsigmask(SIGCHLD); #endif /* _lib_sigvec */ #ifdef _hdr_nc _NutConf(_NC_SET_SUFFIXED_SEARCHING, 1); #endif /* _hdr_nc */ fixargs(av,0); shp = sh_init(ac,av,userinit); time(&mailtime); if(rshflag=sh_isoption(SH_RESTRICTED)) sh_offoption(SH_RESTRICTED); if(sigsetjmp(*((sigjmp_buf*)shp->jmpbuffer),0)) { /* begin script execution here */ sh_reinit((char**)0); shp->gd->pid = getpid(); shp->gd->ppid = getppid(); } shp->fn_depth = shp->dot_depth = 0; command = error_info.id; /* set pidname '$$' */ srand(shp->gd->pid&0x7fff); if(nv_isnull(PS4NOD)) nv_putval(PS4NOD,e_traceprompt,NV_RDONLY); path_pwd(shp,1); iop = (Sfio_t*)0; #if SHOPT_BRACEPAT sh_onoption(SH_BRACEEXPAND); #endif 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) sh_onoption(SH_LOGIN_SHELL); /* decide whether shell is interactive */ if(!sh_isoption(SH_INTERACTIVE) && !sh_isoption(SH_TFLAG) && !sh_isoption(SH_CFLAG) && sh_isoption(SH_SFLAG) && tty_check(0) && tty_check(ERRIO)) sh_onoption(SH_INTERACTIVE); if(sh_isoption(SH_INTERACTIVE)) { 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 )) sh_onoption(SH_RC); for(i=0; i<elementsof(shp->offoptions.v); i++) shp->options.v[i] &= ~shp->offoptions.v[i]; if(sh_isoption(SH_INTERACTIVE)) { #ifdef SIGXCPU signal(SIGXCPU,SIG_DFL); #endif /* SIGXCPU */ #ifdef SIGXFSZ signal(SIGXFSZ,SIG_DFL); #endif /* SIGXFSZ */ sh_onoption(SH_MONITOR); } job_init(shp,sh_isoption(SH_LOGIN_SHELL)); if(sh_isoption(SH_LOGIN_SHELL)) { /* system profile */ sh_source(shp, iop, e_sysprofile); if(!sh_isoption(SH_NOUSRPROFILE) && !sh_isoption(SH_PRIVILEGED)) { char **files = shp->gd->login_files; while ((name = *files++) && !sh_source(shp, iop, sh_mactry(shp,name))); } } /* make sure PWD is set up correctly */ path_pwd(shp,1); if(!sh_isoption(SH_NOEXEC)) { 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 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 #endif { 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); } } } else if(sh_isoption(SH_INTERACTIVE) && sh_isoption(SH_PRIVILEGED)) sh_source(shp, iop, e_suidprofile); } shp->st.cmdname = error_info.id = command; sh_offstate(SH_PROFILE); if(rshflag) sh_onoption(SH_RESTRICTED); /* open input file if specified */ if(shp->comdiv) { shell_c: iop = sfnew(NIL(Sfio_t*),shp->comdiv,strlen(shp->comdiv),0,SF_STRING|SF_READ); }
int b_enum(int argc, char **argv, Shbltin_t *context) { bool pflag = false, iflag = false; int i, n; ssize_t sz = -1; Namval_t *np, *tp, *mp; Namarr_t *ap; char *cp; const char *sp; struct Enum *ep; Shell_t *shp = context->shp; struct { Optdisc_t opt; Namval_t *np; } optdisc; if (cmdinit(argc, argv, context, ERROR_NOTIFY)) return -1; while ((n = optget(argv, enum_usage))) { switch (n) { case 'p': { pflag = true; break; } case 'i': { iflag = true; break; } case ':': { errormsg(SH_DICT, 2, "%s", opt_info.arg); break; } case '?': { errormsg(SH_DICT, ERROR_usage(2), "%s", opt_info.arg); __builtin_unreachable(); } default: { break; } } } argv += opt_info.index; argc -= opt_info.index; if (error_info.errors || argc != 1) { error(ERROR_USAGE | 2, "%s", optusage(NULL)); return 1; } while ((cp = *argv++)) { np = nv_open(cp, shp->var_tree, NV_VARNAME | NV_NOADD); if (!np || !(ap = nv_arrayptr(np)) || ap->fun || ap->nelem < 2) { error(ERROR_exit(1), "%s must name an array containing at least two elements", cp); } n = stktell(shp->stk); sfprintf(shp->stk, "%s.%s%c", NV_CLASS, np->nvname, 0); tp = nv_open(stkptr(shp->stk, n), shp->var_tree, NV_VARNAME); if (pflag) { sh_outenum(shp, sfstdout, tp); continue; } stkseek(shp->stk, n); n = ap->nelem; i = 0; nv_onattr(tp, NV_UINT16); nv_putval(tp, (char *)&i, NV_INTEGER); nv_putsub(np, NULL, 0L, ARRAY_SCAN); do { sz += strlen(nv_getval(np)); } while (nv_nextsub(np)); ep = calloc(1, sizeof(struct Enum)); if (!ep) { error(ERROR_system(1), "out of space"); __builtin_unreachable(); } ep->nelem = n; mp = nv_namptr(ep->node, 0); mp->nvshell = shp; nv_setsize(mp, 10); nv_onattr(mp, NV_UINT16); ep->iflag = iflag; ep->values = malloc(n * sizeof(*ep->values)); nv_putsub(np, NULL, 0L, ARRAY_SCAN); i = 0; do { sp = nv_getval(np); ep->values[i++] = strdup(sp); } while (nv_nextsub(np)); assert(n == i); ep->namfun.dsize = sizeof(struct Enum); ep->namfun.disc = &ENUM_disc; ep->namfun.type = tp; nv_onattr(tp, NV_RDONLY); nv_disc(tp, &ep->namfun, DISC_OP_FIRST); memset(&optdisc, 0, sizeof(optdisc)); optdisc.opt.infof = enuminfo; optdisc.np = tp; nv_addtype(tp, enum_type, &optdisc, sizeof(optdisc)); nv_onattr(np, NV_LTOU | NV_UTOL); } nv_open(0, shp->var_tree, 0); return error_info.errors != 0; }
int b_enum(int argc, char** argv, Shbltin_t *context) #endif { bool pflag=false, iflag=false; int i,n; ssize_t sz = -1; Namval_t *np, *tp, *mp; Namarr_t *ap; char *cp,*sp; struct Enum *ep; Shell_t *shp = context->shp; struct { Optdisc_t opt; Namval_t *np; } optdisc; cmdinit(argc, argv, context, ERROR_CATALOG, ERROR_NOTIFY); for (;;) { switch (optget(argv, enum_usage)) { case 'p': pflag = true; continue; case 'i': iflag = true; continue; case '?': error(ERROR_USAGE|4, "%s", opt_info.arg); break; case ':': error(2, "%s", opt_info.arg); break; } break; } argv += opt_info.index; if (error_info.errors) { error(ERROR_USAGE|2, "%s", optusage(NiL)); return 1; } if(!*argv) sh_outenum(shp,sfstdout,(Namval_t*)0); while(cp = *argv++) { if(!(np = nv_open(cp, shp->var_tree, NV_VARNAME|NV_NOADD)) || !(ap=nv_arrayptr(np)) || ap->fun || (sz=ap->nelem) < 2) error(ERROR_exit(1), "%s must name an array containing at least two elements",cp); n = stktell(shp->stk); sfprintf(shp->stk,"%s.%s%c",NV_CLASS,np->nvname,0); tp = nv_open(stkptr(shp->stk,n), shp->var_tree, NV_VARNAME); if(pflag) { sh_outenum(shp,sfstdout,tp); continue; } stkseek(shp->stk,n); n = sz; i = 0; nv_onattr(tp, NV_UINT16); nv_putval(tp, (char*)&i, NV_INTEGER); nv_putsub(np, (char*)0, 0L, ARRAY_SCAN); do { sz += strlen(nv_getval(np)); } while(nv_nextsub(np)); sz += n*sizeof(char*); if(!(ep = newof(0,struct Enum,1,sz))) error(ERROR_system(1), "out of space"); mp = nv_namptr(ep->node,0); mp->nvshell = shp; nv_setsize(mp,10); nv_onattr(mp, NV_UINT16); ep->iflag = iflag; ep->nelem = n; cp = (char*)&ep->values[n+1]; nv_putsub(np, (char*)0, 0L, ARRAY_SCAN); ep->values[n] = 0; i = 0; do { ep->values[i++] = cp; sp = nv_getval(np); n = strlen(sp); memcpy(cp,sp,n+1); cp += n+1; } while(nv_nextsub(np)); ep->hdr.dsize = sizeof(struct Enum)+sz; ep->hdr.disc = &ENUM_disc; ep->hdr.type = tp; nv_onattr(tp, NV_RDONLY); nv_disc(tp, &ep->hdr,NV_FIRST); memset(&optdisc,0,sizeof(optdisc)); optdisc.opt.infof = enuminfo; optdisc.np = tp; nv_addtype(tp, enum_type, &optdisc.opt, sizeof(optdisc)); nv_onattr(np,NV_LTOU|NV_UTOL); } nv_open(0,shp->var_tree,0); return error_info.errors != 0; }
int b_dot_cmd(int n, char *argv[], Shbltin_t *context) { char *script; Namval_t *np; int jmpval; Shell_t *shp = context->shp; struct sh_scoped savst, *prevscope = shp->st.self; int fd; char *filename = NULL; char *buffer = NULL; struct dolnod *saveargfor = NULL; volatile struct dolnod *argsave = NULL; checkpt_t buff; Sfio_t *iop = NULL; short level; Optdisc_t disc; memset(&disc, 0, sizeof(disc)); disc.version = OPT_VERSION; opt_info.disc = &disc; while ((n = optget(argv, sh_optdot))) { switch (n) { case ':': { errormsg(SH_DICT, 2, "%s", opt_info.arg); break; } case '?': { errormsg(SH_DICT, ERROR_usage(0), "%s", opt_info.arg); return 2; } default: { break; } } } argv += opt_info.index; script = *argv; if (error_info.errors || !script) { errormsg(SH_DICT, ERROR_usage(2), "%s", optusage(NULL)); __builtin_unreachable(); } if (shp->dot_depth + 1 > DOTMAX) { errormsg(SH_DICT, ERROR_exit(1), e_toodeep, script); __builtin_unreachable(); } np = shp->posix_fun; if (!np) { // Check for KornShell style function first. np = nv_search(script, shp->fun_tree, 0); if (np && is_afunction(np) && !nv_isattr(np, NV_FPOSIX)) { if (!FETCH_VT(np->nvalue, ip)) { // TODO: Replace this with a comment explaining why the return value of this // path_search() call is ignored. At the time I wrote this (2019-03-16) no unit test // exercises this statement. I added the void cast to silence Coverity Scan 253792. (void)path_search(shp, script, NULL, 0); if (FETCH_VT(np->nvalue, ip)) { if (nv_isattr(np, NV_FPOSIX)) np = NULL; } else { errormsg(SH_DICT, ERROR_exit(1), e_found, script); __builtin_unreachable(); } } } else { np = NULL; } if (!np) { fd = path_open(shp, script, path_get(shp, script)); if (fd < 0) { errormsg(SH_DICT, ERROR_system(1), e_open, script); __builtin_unreachable(); } filename = path_fullname(shp, stkptr(shp->stk, PATH_OFFSET)); } } *prevscope = shp->st; shp->st.lineno = np ? ((struct functnod *)nv_funtree(np))->functline : 1; shp->st.var_local = shp->st.save_tree = shp->var_tree; if (filename) { shp->st.filename = filename; shp->st.lineno = 1; } level = shp->fn_depth + shp->dot_depth + 1; nv_putval(SH_LEVELNOD, (char *)&level, NV_INT16); shp->st.prevst = prevscope; shp->st.self = &savst; shp->topscope = (Shscope_t *)shp->st.self; prevscope->save_tree = shp->var_tree; if (np) { struct Ufunction *rp = FETCH_VT(np->nvalue, rp); shp->st.filename = strdup(rp->fname ? rp->fname : ""); } nv_putval(SH_PATHNAMENOD, shp->st.filename, NV_NOFREE); shp->posix_fun = NULL; if (np || argv[1]) argsave = sh_argnew(shp, argv, &saveargfor); sh_pushcontext(shp, &buff, SH_JMPDOT); jmpval = sigsetjmp(buff.buff, 0); if (jmpval == 0) { shp->dot_depth++; if (np) { sh_exec(shp, (Shnode_t *)(nv_funtree(np)), sh_isstate(shp, SH_ERREXIT)); } else { buffer = malloc(IOBSIZE + 1); iop = sfnew(NULL, buffer, IOBSIZE, fd, SF_READ); sh_offstate(shp, SH_NOFORK); sh_eval(shp, iop, sh_isstate(shp, SH_PROFILE) ? SH_FUNEVAL : 0); } } sh_popcontext(shp, &buff); if (buffer) free(buffer); if (!np) { free(shp->st.filename); shp->st.filename = NULL; } shp->dot_depth--; if ((np || argv[1]) && jmpval != SH_JMPSCRIPT) { sh_argreset(shp, (struct dolnod *)argsave, saveargfor); } else { prevscope->dolc = shp->st.dolc; prevscope->dolv = shp->st.dolv; } if (shp->st.self != &savst) *shp->st.self = shp->st; // Only restore the top Shscope_t portion for posix functions. memcpy(&shp->st, prevscope, sizeof(Shscope_t)); shp->topscope = (Shscope_t *)prevscope; nv_putval(SH_PATHNAMENOD, shp->st.filename, NV_NOFREE); if (jmpval && jmpval != SH_JMPFUN) siglongjmp(shp->jmplist->buff, jmpval); return shp->exitval; }
// // 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(shp, SH_LOGIN_SHELL) && !sh_isoption(shp, SH_POSIX)) { sh_source(shp, NULL, sh_mactry(shp, (char *)e_bash_logout)); } return; } if (sh_isstate(shp, SH_PREINIT)) { // pre-init stage if (sh_isoption(shp, SH_RESTRICTED)) sh_onoption(shp, SH_RESTRICTED2); sh_onoption(shp, SH_HISTORY2); sh_onoption(shp, SH_INTERACTIVE_COMM); sh_onoption(shp, SH_SOURCEPATH); sh_onoption(shp, SH_HISTAPPEND); sh_onoption(shp, SH_CMDHIST); sh_onoption(shp, SH_LITHIST); sh_onoption(shp, SH_NOEMPTYCMDCOMPL); sh_onoption(shp, SH_POSIX); if (shp->login_sh == 2) sh_onoption(shp, SH_LOGIN_SHELL); if (strcmp(astconf("UNIVERSE", 0, 0), "att") == 0) { sh_onoption(shp, SH_XPG_ECHO); } else { sh_offoption(shp, SH_XPG_ECHO); } sh_offoption(shp, SH_PHYSICAL); // Add builtins. sh_addbuiltin(shp, "shopt", b_shopt, &sh); sh_addbuiltin(shp, "enable", b_builtin, &sh); // Set up some variables needed for --version. // Needs to go here because --version option is parsed before the init script. #if 0 /* This was causing a core dump when running set to display all variables */ if(np=nv_open("HOSTTYPE",shp->var_tree,0)) nv_putval(np, BASH_HOSTTYPE, NV_NOFREE); #endif np = nv_open("MACHTYPE", shp->var_tree, 0); if (np) nv_putval(np, BASH_MACHTYPE, NV_NOFREE); np = nv_open("BASH_VERSION", shp->var_tree, 0); if (np) nv_putval(np, BASH_VERSION, NV_NOFREE); np = nv_open("BASH_VERSINFO", shp->var_tree, 0); if (np) { 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. np = nv_open("BASH_ENV", shp->var_tree, 0); if (np) { const Namdisc_t *dp = nv_discfun(DISCFUN_RESTRICT); Namfun_t *fp = calloc(dp->dsize, 1); fp->disc = dp; nv_disc(np, fp, DISC_NOOP); } // Open GLOBIGNORE node. np = nv_open("GLOBIGNORE", shp->var_tree, 0); if (np) { const Namdisc_t *dp = &SH_GLOBIGNORE_disc; Namfun_t *fp = calloc(dp->dsize, 1); fp->disc = dp; nv_disc(np, fp, DISC_NOOP); } np = nv_open("BASH_EXECUTION_STRING", shp->var_tree, 0); if (np) { np->nvalue.cp = shp->comdiv; nv_onattr(np, NV_NOFREE); } // Set startup files. n = 0; if (sh_isoption(shp, SH_LOGIN_SHELL)) { if (!sh_isoption(shp, SH_POSIX)) { shp->gd->login_files[n++] = (char *)e_bash_profile; shp->gd->login_files[n++] = (char *)e_bash_login; } shp->gd->login_files[n++] = (char *)e_profile; } shp->gd->login_files = login_files; reinit: xtrace = sh_isoption(shp, SH_XTRACE); sh_offoption(shp, SH_XTRACE); verbose = sh_isoption(shp, SH_VERBOSE); sh_offoption(shp, SH_VERBOSE); np = nv_open("SHELLOPTS", shp->var_tree, NV_NOADD); if (np) nv_offattr(np, NV_RDONLY); iop = sfopen(NULL, bash_pre_rc, "s"); sh_eval(shp, iop, 0); if (xtrace) sh_offoption(shp, SH_XTRACE); if (verbose) sh_offoption(shp, SH_VERBOSE); }