diff options
Diffstat (limited to 'usr/src/lib/libshell/common/sh/args.c')
-rw-r--r-- | usr/src/lib/libshell/common/sh/args.c | 879 |
1 files changed, 0 insertions, 879 deletions
diff --git a/usr/src/lib/libshell/common/sh/args.c b/usr/src/lib/libshell/common/sh/args.c deleted file mode 100644 index b70649cdb4..0000000000 --- a/usr/src/lib/libshell/common/sh/args.c +++ /dev/null @@ -1,879 +0,0 @@ -/*********************************************************************** -* * -* This software is part of the ast package * -* Copyright (c) 1982-2010 AT&T Intellectual Property * -* and is licensed under the * -* Common Public License, Version 1.0 * -* by AT&T Intellectual Property * -* * -* A copy of the License is available at * -* http://www.opensource.org/licenses/cpl1.0.txt * -* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * -* * -* Information and Software Systems Research * -* AT&T Research * -* Florham Park NJ * -* * -* David Korn <dgk@research.att.com> * -* * -***********************************************************************/ -#pragma prototyped -/* - * UNIX shell - * - * S. R. Bourne - * Rewritten by David Korn - * AT&T Labs - * - */ - -#include "defs.h" -#include "path.h" -#include "builtins.h" -#include "terminal.h" -#include "edit.h" -#include "FEATURE/poll" -#if SHOPT_KIA -# include "shlex.h" -# include "io.h" -#endif /* SHOPT_KIA */ -#if SHOPT_PFSH -# define PFSHOPT "P" -#else -# define PFSHOPT -#endif -#if SHOPT_BASH -# define BASHOPT "\374" -#else -# define BASHOPT -#endif -#if SHOPT_HISTEXPAND -# define HFLAG "H" -#else -# define HFLAG "" -#endif - -#define SORT 1 -#define PRINT 2 - -static char *null; - -/* The following order is determined by sh_optset */ -static const char optksh[] = PFSHOPT BASHOPT "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, - SH_NOUNSET, SH_VERBOSE, SH_XTRACE, SH_BRACEEXPAND, SH_NOCLOBBER, - SH_GLOBSTARS, SH_RC, SH_LOGIN_SHELL, -#if SHOPT_HISTEXPAND - SH_HISTEXPAND, -#endif - 0 -}; - -#define NUM_OPTS (sizeof(flagval)/sizeof(*flagval)) - -typedef struct _arg_ -{ - Shell_t *sh; - struct dolnod *argfor; /* linked list of blocks to be cleaned up */ - struct dolnod *dolh; - char flagadr[NUM_OPTS+1]; -#if SHOPT_KIA - char *kiafile; -#endif /* SHOPT_KIA */ -} Arg_t; - -static int arg_expand(Shell_t*,struct argnod*,struct argnod**,int); -static void sh_argset(Arg_t*, char *[]); - - -/* ======== option handling ======== */ - -void *sh_argopen(Shell_t *shp) -{ - void *addr = newof(0,Arg_t,1,0); - Arg_t *ap = (Arg_t*)addr; - ap->sh = shp; - return(addr); -} - -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); -} - -/* - * This routine turns options on and off - * The options "PDicr" are illegal from set command. - * The -o option is used to set option by name - * This routine returns the number of non-option arguments - */ -int sh_argopts(int argc,register char *argv[], void *context) -{ - Shell_t *shp = (Shell_t*)context; - register int n,o; - register Arg_t *ap = (Arg_t*)(shp->arg_context); - Lex_t *lp = (Lex_t*)(shp->lex_context); - Shopt_t newflags; - int setflag=0, action=0, trace=(int)sh_isoption(SH_XTRACE); - Namval_t *np = NIL(Namval_t*); - const char *cp; - int verbose,f; - Optdisc_t disc; - newflags=ap->sh->options; - memset(&disc, 0, sizeof(disc)); - disc.version = OPT_VERSION; - disc.infof = infof; - opt_info.disc = &disc; - - if(argc>0) - setflag = 4; - else - argc = -argc; - while((n = optget(argv,setflag?sh_optset:sh_optksh))) - { - o=0; - f=*opt_info.option=='-' && (opt_info.num || opt_info.arg); - switch(n) - { - case 'A': - np = nv_open(opt_info.arg,ap->sh->var_tree,NV_NOASSIGN|NV_ARRAY|NV_VARNAME); - 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))) - { - errormsg(SH_DICT,2, e_option, opt_info.arg); - error_info.errors++; - } - o &= 0xff; - 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->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; - for(tp=shtab_options; o = tp->sh_number; tp++) - if(!(o&SH_COMMANDLINE) && is_option(&newflags,o&0xff)) - off_option(&newflags,o&0xff); - } - continue; - case -7: - f = 0; - goto byname; - case 'D': - on_option(&newflags,SH_NOEXEC); - goto skip; - case 'T': - if (opt_info.num) - ap->sh->test |= opt_info.num; - else - ap->sh->test = 0; - continue; - case 's': - if(setflag) - { - action = SORT; - continue; - } -#if SHOPT_KIA - goto skip; - case 'R': - if(setflag) - n = ':'; - else - { - ap->kiafile = opt_info.arg; - n = 'n'; - } - /*FALLTHROUGH*/ -#endif /* SHOPT_KIA */ -#if SHOPT_REGRESS - goto skip; - case 'I': - continue; -#endif /* SHOPT_REGRESS */ - /*FALLTHROUGH*/ - skip: - default: - if(cp=strchr(optksh,n)) - o = flagval[cp-optksh]; - break; - case ':': - if(opt_info.name[0]=='-'&&opt_info.name[1]=='-') - { - opt_info.arg = argv[opt_info.index-1] + 2; - f = 1; - goto byname; - } - errormsg(SH_DICT,2, "%s", opt_info.arg); - continue; - case '?': - errormsg(SH_DICT,ERROR_usage(0), "%s", opt_info.arg); - return(-1); - } - if(f) - { - if(o==SH_VI || o==SH_EMACS || o==SH_GMACS) - { - off_option(&newflags,SH_VI); - off_option(&newflags,SH_EMACS); - off_option(&newflags,SH_GMACS); - } - on_option(&newflags,o); - off_option(&ap->sh->offoptions,o); - } - else - { - if(o==SH_XTRACE) - trace = 0; - off_option(&newflags,o); - if(setflag==0) - on_option(&ap->sh->offoptions,o); - } - } - if(error_info.errors) - errormsg(SH_DICT,ERROR_usage(2),"%s",optusage(NIL(char*))); - /* check for '-' or '+' argument */ - if((cp=argv[opt_info.index]) && cp[1]==0 && (*cp=='+' || *cp=='-') && - strcmp(argv[opt_info.index-1],"--")) - { - opt_info.index++; - off_option(&newflags,SH_XTRACE); - off_option(&newflags,SH_VERBOSE); - trace = 0; - } - if(trace) - sh_trace(argv,1); - argc -= opt_info.index; - argv += opt_info.index; - if(action==PRINT) - sh_printopts(newflags,verbose,0); - if(setflag) - { - if(action==SORT) - { - if(argc>0) - strsort(argv,argc,strcoll); - else - strsort(ap->sh->st.dolv+1,ap->sh->st.dolc,strcoll); - } - if(np) - { - nv_setvec(np,0,argc,argv); - nv_close(np); - } - else if(argc>0 || ((cp=argv[-1]) && strcmp(cp,"--")==0)) - sh_argset(ap,argv-1); - } - else if(is_option(&newflags,SH_CFLAG)) - { - if(!(ap->sh->comdiv = *argv++)) - { - errormsg(SH_DICT,2,e_cneedsarg); - errormsg(SH_DICT,ERROR_usage(2),optusage(NIL(char*))); - } - argc--; - } - /* handling SH_INTERACTIVE and SH_PRIVILEGED has been moved to - * sh_applyopts(), so that the code can be reused from b_shopt(), too - */ - sh_applyopts(ap->sh,newflags); -#if SHOPT_KIA - if(ap->kiafile) - { - if(!argv[0]) - errormsg(SH_DICT,ERROR_usage(2),"-R requires scriptname"); - if(!(lp->kiafile=sfopen(NIL(Sfio_t*),ap->kiafile,"w+"))) - errormsg(SH_DICT,ERROR_system(3),e_create,ap->kiafile); - if(!(lp->kiatmp=sftmp(2*SF_BUFSIZE))) - errormsg(SH_DICT,ERROR_system(3),e_tmpcreate); - sfputr(lp->kiafile,";vdb;CIAO/ksh",'\n'); - lp->kiabegin = sftell(lp->kiafile); - lp->entity_tree = dtopen(&_Nvdisc,Dtbag); - lp->scriptname = strdup(sh_fmtq(argv[0])); - lp->script=kiaentity(lp,lp->scriptname,-1,'p',-1,0,0,'s',0,""); - lp->fscript=kiaentity(lp,lp->scriptname,-1,'f',-1,0,0,'s',0,""); - lp->unknown=kiaentity(lp,"<unknown>",-1,'p',-1,0,0,'0',0,""); - kiaentity(lp,"<unknown>",-1,'p',0,0,lp->unknown,'0',0,""); - lp->current = lp->script; - ap->kiafile = 0; - } -#endif /* SHOPT_KIA */ - return(argc); -} - -/* apply new options */ - -void sh_applyopts(Shell_t* shp,Shopt_t newflags) -{ - /* cannot set -n for interactive shells since there is no way out */ - if(sh_isoption(SH_INTERACTIVE)) - off_option(&newflags,SH_NOEXEC); - if(is_option(&newflags,SH_PRIVILEGED)) - on_option(&newflags,SH_NOUSRPROFILE); - if(!sh_isstate(SH_INIT) && is_option(&newflags,SH_PRIVILEGED) != sh_isoption(SH_PRIVILEGED) || sh_isstate(SH_INIT) && is_option(&((Arg_t*)shp->arg_context)->sh->offoptions,SH_PRIVILEGED) && shp->userid!=shp->euserid) - { - if(!is_option(&newflags,SH_PRIVILEGED)) - { - setuid(shp->userid); - setgid(shp->groupid); - if(shp->euserid==0) - { - shp->euserid = shp->userid; - shp->egroupid = shp->groupid; - } - } - else if((shp->userid!=shp->euserid && setuid(shp->euserid)<0) || - (shp->groupid!=shp->egroupid && setgid(shp->egroupid)<0) || - (shp->userid==shp->euserid && shp->groupid==shp->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; -} - -/* - * returns the value of $- - */ -char *sh_argdolminus(void* context) -{ - register Arg_t *ap = (Arg_t*)context; - register const char *cp=optksh; - register char *flagp=ap->flagadr; - while(cp< &optksh[NUM_OPTS]) - { - int n = flagval[cp-optksh]; - if(sh_isoption(n)) - *flagp++ = *cp; - cp++; - } - *flagp = 0; - return(ap->flagadr); -} - -/* - * set up positional parameters - */ -static void sh_argset(Arg_t *ap,char *argv[]) -{ - sh_argfree(ap->sh,ap->dolh,0); - ap->dolh = sh_argcreate(argv); - /* link into chain */ - ap->dolh->dolnxt = ap->argfor; - ap->argfor = ap->dolh; - ap->sh->st.dolc = ap->dolh->dolnum-1; - ap->sh->st.dolv = ap->dolh->dolval; -} - -/* - * free the argument list if the use count is 1 - * If count is greater than 1 decrement count and return same blk - * Free the argument list if the use count is 1 and return next blk - * Delete the blk from the argfor chain - * If flag is set, then the block dolh is not freed - */ -struct dolnod *sh_argfree(Shell_t *shp, struct dolnod *blk,int flag) -{ - register struct dolnod* argr=blk; - register struct dolnod* argblk; - register Arg_t *ap = (Arg_t*)shp->arg_context; - if(argblk=argr) - { - if((--argblk->dolrefcnt)==0) - { - argr = argblk->dolnxt; - if(flag && argblk==ap->dolh) - ap->dolh->dolrefcnt = 1; - else - { - /* delete from chain */ - if(ap->argfor == argblk) - ap->argfor = argblk->dolnxt; - else - { - for(argr=ap->argfor;argr;argr=argr->dolnxt) - if(argr->dolnxt==argblk) - break; - if(!argr) - return(NIL(struct dolnod*)); - argr->dolnxt = argblk->dolnxt; - argr = argblk->dolnxt; - } - free((void*)argblk); - } - } - } - return(argr); -} - -/* - * grab space for arglist and copy args - * The strings are copied after the argment vector - */ -struct dolnod *sh_argcreate(register char *argv[]) -{ - register struct dolnod *dp; - register char **pp=argv, *sp; - register int size=0,n; - /* count args and number of bytes of arglist */ - while(sp= *pp++) - size += strlen(sp); - n = (pp - argv)-1; - dp=new_of(struct dolnod,n*sizeof(char*)+size+n); - dp->dolrefcnt=1; /* use count */ - dp->dolnum = n; - dp->dolnxt = 0; - pp = dp->dolval; - sp = (char*)dp + sizeof(struct dolnod) + n*sizeof(char*); - while(n--) - { - *pp++ = sp; - sp = strcopy(sp, *argv++) + 1; - } - *pp = NIL(char*); - return(dp); -} - -/* - * used to set new arguments for functions - */ -struct dolnod *sh_argnew(Shell_t *shp,char *argi[], struct dolnod **savargfor) -{ - register Arg_t *ap = (Arg_t*)shp->arg_context; - register struct dolnod *olddolh = ap->dolh; - *savargfor = ap->argfor; - ap->dolh = 0; - ap->argfor = 0; - sh_argset(ap,argi); - return(olddolh); -} - -/* - * reset arguments as they were before function - */ -void sh_argreset(Shell_t *shp,struct dolnod *blk, struct dolnod *afor) -{ - register Arg_t *ap = (Arg_t*)shp->arg_context; - while(ap->argfor=sh_argfree(shp,ap->argfor,0)); - ap->argfor = afor; - if(ap->dolh = blk) - { - shp->st.dolc = ap->dolh->dolnum-1; - shp->st.dolv = ap->dolh->dolval; - } -} - -/* - * increase the use count so that an sh_argset will not make it go away - */ -struct dolnod *sh_arguse(Shell_t* shp) -{ - register struct dolnod *dh; - register Arg_t *ap = (Arg_t*)shp->arg_context; - if(dh=ap->dolh) - dh->dolrefcnt++; - return(dh); -} - -/* - * Print option settings on standard output - * if mode is inclusive or of PRINT_* - * if <mask> is set, only options with this mask value are displayed - */ -void sh_printopts(Shopt_t oflags,register int mode, Shopt_t *mask) -{ - register const Shtable_t *tp; - const char *name; - int on; - int value; - if(!(mode&PRINT_NO_HEADER)) - sfputr(sfstdout,sh_translate(e_heading),'\n'); - if(mode&PRINT_TABLE) - { - int w; - int c; - int r; - int i; - - c = 0; - for(tp=shtab_options; value=tp->sh_number; tp++) - { - if(mask && !is_option(mask,value&0xff)) - continue; - name = tp->sh_name; - if(name[0] == 'n' && name[1] == 'o' && name[2] != 't') - name += 2; - if(c<(w=strlen(name))) - c = w; - } - c += 4; - if((w = ed_window()) < (2*c)) - w = 2*c; - r = w / c; - i = 0; - for(tp=shtab_options; value=tp->sh_number; tp++) - { - if(mask && !is_option(mask,value&0xff)) - continue; - on = !!is_option(&oflags,value); - value &= 0xff; - name = tp->sh_name; - if(name[0] == 'n' && name[1] == 'o' && name[2] != 't') - { - name += 2; - on = !on; - } - if(++i>=r) - { - i = 0; - sfprintf(sfstdout, "%s%s\n", on ? "" : "no", name); - } - else - sfprintf(sfstdout, "%s%-*s", on ? "" : "no", on ? c : (c-2), name); - } - if(i) - sfputc(sfstdout,'\n'); - return; - } -#if SHOPT_RAWONLY - 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); - } - 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') - { - name += 2; - on = !on; - } - if(mode&PRINT_VERBOSE) - { - sfputr(sfstdout,name,' '); - sfnputc(sfstdout,' ',24-strlen(name)); - 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); - } - else if(!(value&SH_COMMANDLINE) && is_option(&oflags,value&0xff)) - sfprintf(sfstdout," %s%s%s",(mode&PRINT_SHOPT)?"":"--",on?"":"no",name); - } - if(!(mode&(PRINT_VERBOSE|PRINT_ALL))) - sfputc(sfstdout,'\n'); -} - -/* - * build an argument list - */ -char **sh_argbuild(Shell_t *shp,int *nargs, const struct comnod *comptr,int flag) -{ - register struct argnod *argp; - struct argnod *arghead=0; - shp->xargmin = 0; - { - register const struct comnod *ac = comptr; - register int n; - /* see if the arguments have already been expanded */ - if(!ac->comarg) - { - *nargs = 0; - return(&null); - } - else if(!(ac->comtyp&COMSCAN)) - { - register struct dolnod *ap = (struct dolnod*)ac->comarg; - *nargs = ap->dolnum; - return(ap->dolval+ap->dolbot); - } - shp->lastpath = 0; - *nargs = 0; - if(ac) - { - if(ac->comnamp == SYSLET) - flag |= ARG_LET; - argp = ac->comarg; - while(argp) - { - n = arg_expand(shp,argp,&arghead,flag); - if(n>1) - { - if(shp->xargmin==0) - shp->xargmin = *nargs; - shp->xargmax = *nargs+n; - } - *nargs += n; - argp = argp->argnxt.ap; - } - argp = arghead; - } - } - { - register char **comargn; - register int argn; - register char **comargm; - argn = *nargs; - /* allow room to prepend args */ - argn += 1; - - comargn=(char**)stkalloc(shp->stk,(unsigned)(argn+1)*sizeof(char*)); - comargm = comargn += argn; - *comargn = NIL(char*); - if(!argp) - { - /* reserve an extra null pointer */ - *--comargn = 0; - return(comargn); - } - while(argp) - { - struct argnod *nextarg = argp->argchn.ap; - argp->argchn.ap = 0; - *--comargn = argp->argval; - if(!(argp->argflag&ARG_RAW)) - sh_trim(*comargn); - if(!(argp=nextarg) || (argp->argflag&ARG_MAKE)) - { - if((argn=comargm-comargn)>1) - strsort(comargn,argn,strcoll); - comargm = comargn; - } - } - shp->last_table = 0; - return(comargn); - } -} - -#if _pipe_socketpair && !_socketpair_devfd -# define sh_pipe arg_pipe -/* - * create a real pipe (not a socket) and print message on failure - */ -static int arg_pipe(register int pv[]) -{ - int fd[2]; - if(pipe(fd)<0 || (pv[0]=fd[0])<0 || (pv[1]=fd[1])<0) - errormsg(SH_DICT,ERROR_system(1),e_pipe); - pv[0] = sh_iomovefd(pv[0]); - pv[1] = sh_iomovefd(pv[1]); - sh.fdstatus[pv[0]] = IONOSEEK|IOREAD; - sh.fdstatus[pv[1]] = IONOSEEK|IOWRITE; - sh_subsavefd(pv[0]); - sh_subsavefd(pv[1]); - return(0); -} -#endif - -struct argnod *sh_argprocsub(Shell_t *shp,struct argnod *argp) -{ - /* argument of the form <(cmd) or >(cmd) */ - register struct argnod *ap; - int monitor, fd, pv[2]; - int subshell = shp->subshell; - ap = (struct argnod*)stkseek(shp->stk,ARGVAL); - ap->argflag |= ARG_MAKE; - ap->argflag &= ~ARG_RAW; - sfwrite(shp->stk,e_devfdNN,8); - sh_pipe(pv); - fd = argp->argflag&ARG_RAW; - sfputr(shp->stk,fmtbase((long)pv[fd],10,0),0); - ap = (struct argnod*)stkfreeze(shp->stk,0); - shp->inpipe = shp->outpipe = 0; - if(monitor = (sh_isstate(SH_MONITOR)!=0)) - sh_offstate(SH_MONITOR); - shp->subshell = 0; - if(fd) - { - shp->inpipe = pv; - sh_exec((Shnode_t*)argp->argchn.ap,(int)sh_isstate(SH_ERREXIT)); - } - else - { - shp->outpipe = pv; - sh_exec((Shnode_t*)argp->argchn.ap,(int)sh_isstate(SH_ERREXIT)); - } - shp->subshell = subshell; - if(monitor) - sh_onstate(SH_MONITOR); - close(pv[1-fd]); - sh_iosave(shp,-pv[fd], shp->topfd, (char*)0); - return(ap); -} - -/* Argument expansion */ -static int arg_expand(Shell_t *shp,register struct argnod *argp, struct argnod **argchain,int flag) -{ - register int count = 0; - argp->argflag &= ~ARG_MAKE; -#if SHOPT_DEVFD - if(*argp->argval==0 && (argp->argflag&ARG_EXP)) - { - struct argnod *ap; - ap = sh_argprocsub(shp,argp); - ap->argchn.ap = *argchain; - *argchain = ap; - count++; - } - else -#endif /* SHOPT_DEVFD */ - if(!(argp->argflag&ARG_RAW)) - { -#if SHOPT_OPTIMIZE - struct argnod *ap; - sh_stats(STAT_ARGEXPAND); - if(flag&ARG_OPTIMIZE) - argp->argchn.ap=0; - if(ap=argp->argchn.ap) - { - sh_stats(STAT_ARGHITS); - count = 1; - ap->argchn.ap = *argchain; - ap->argflag |= ARG_RAW; - ap->argflag &= ~ARG_EXP; - *argchain = ap; - } - else -#endif /* SHOPT_OPTIMIZE */ - count = sh_macexpand(shp,argp,argchain,flag); - } - else - { - argp->argchn.ap = *argchain; - *argchain = argp; - argp->argflag |= ARG_MAKE; - count++; - } - return(count); -} - |