// Argument expansion. static_fn int arg_expand(Shell_t *shp, struct argnod *argp, struct argnod **argchain, int flag) { int count = 0; argp->argflag &= ~ARG_MAKE; if (*argp->argval == 0 && (argp->argflag & ARG_EXP)) { struct argnod *ap; ap = sh_argprocsub(shp, argp); ap->argchn.ap = *argchain; *argchain = ap; count++; } else if (!(argp->argflag & ARG_RAW)) { struct argnod *ap; sh_stats(STAT_ARGEXPAND); if (flag & ARG_OPTIMIZE) argp->argchn.ap = NULL; ap = argp->argchn.ap; if (ap) { sh_stats(STAT_ARGHITS); count = 1; ap->argchn.ap = *argchain; ap->argflag |= ARG_RAW; ap->argflag &= ~ARG_EXP; *argchain = ap; } else { count = sh_macexpand(shp, argp, argchain, flag); } } else { argp->argchn.ap = *argchain; *argchain = argp; argp->argflag |= ARG_MAKE; count++; } return count; }
static pid_t _spawnveg(Shell_t *shp,const char *path, char* const argv[], char* const envp[], pid_t pgid) { pid_t pid; while(1) { sh_stats(STAT_SPAWN); pid = spawnveg(path,argv,envp,pgid); if(pid>=0 || errno!=EAGAIN) break; } return(pid); }
static pid_t _spawnveg(Shell_t *shp,const char *path, char* const argv[], char* const envp[], pid_t pgid) { pid_t pid; #ifdef SIGTSTP if(job.jobcontrol) { signal(SIGTTIN,SIG_DFL); signal(SIGTTOU,SIG_DFL); } #endif /* SIGTSTP */ while(1) { sh_stats(STAT_SPAWN); #ifdef SPAWN_cwd { char *arg0 = argv[0], **av0= (char**)&argv[0]; int fd; pid = spawnvex(path,argv,envp,shp->vex); *av0 = arg0; if(pid>0 && shp->comsub && (fd=sffileno(sfstdout))!=1 && fd>=0) spawnvex_add(shp->vex, fd, 1,0,0); } #else pid = spawnveg(path,argv,envp,pgid); #endif /* SPAWN_cwd */ if(pid>=0 || errno!=EAGAIN) break; } #ifdef SIGTSTP if(job.jobcontrol) { signal(SIGTTIN,SIG_IGN); signal(SIGTTOU,SIG_IGN); } #endif /* SIGTSTP */ return(pid); }
int path_expand(Shell_t *shp, const char *pattern, struct argnod **arghead) { glob_t gdata; struct argnod *ap; glob_t *gp = &gdata; int flags, extra = 0; #if SHOPT_BASH int off; 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; if (sh_isoption(shp, SH_MARKDIRS)) flags |= GLOB_MARK; if (sh_isoption(shp, SH_GLOBSTARS)) flags |= GLOB_STARSTAR; #if SHOPT_BASH #if 0 if(sh_isoption(shp,SH_BASH) && !sh_isoption(shp,SH_EXTGLOB)) flags &= ~GLOB_AUGMENTED; #endif if (sh_isoption(shp, SH_NULLGLOB)) flags &= ~GLOB_NOCHECK; if (sh_isoption(shp, SH_NOCASEGLOB)) flags |= GLOB_ICASE; #endif if (sh_isstate(shp, SH_COMPLETE)) { extra += scantree(shp, shp->alias_tree, pattern, arghead); extra += scantree(shp, shp->fun_tree, pattern, arghead); gp->gl_nextdir = nextdir; flags |= GLOB_COMPLETE; flags &= ~GLOB_NOCHECK; } #if SHOPT_BASH off = stktell(shp->stk); if (off) sp = stkfreeze(shp->stk, 0); if (sh_isoption(shp, 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(shp, 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; sfputr(shp->stk, "@(", -1); if (!sh_isstate(shp, SH_FCOMPLETE)) { sfputr(shp->stk, cp, -1); for (cp = stkptr(shp->stk, off); *cp; cp++) { if (*cp == ':') *cp = '|'; } } else { cp2 = strtok(cp, ":"); if (!cp2) cp2 = cp; do { sfputc(shp->stk, '*'); sfputr(shp->stk, cp2, -1); cp2 = strtok(NULL, ":"); if (cp2) { *(cp2 - 1) = ':'; sfputc(shp->stk, '|'); } } while (cp2); } sfputc(shp->stk, ')'); gp->gl_fignore = stkfreeze(shp->stk, 1); } else if (!sh_isstate(shp, SH_FCOMPLETE) && sh_isoption(shp, SH_DOTGLOB)) { gp->gl_fignore = ""; } } else #endif gp->gl_fignore = nv_getval(sh_scoped(shp, FIGNORENOD)); if (suflen) gp->gl_suffix = sufstr; gp->gl_intr = &shp->trapnote; suflen = 0; if (strncmp(pattern, "~(N", 3) == 0) flags &= ~GLOB_NOCHECK; ast_glob(pattern, flags, 0, gp); #if SHOPT_BASH if (off) { stkset(shp->stk, sp, off); } else { stkseek(shp->stk, 0); } #endif sh_sigcheck(shp); for (ap = (struct argnod *)gp->gl_list; ap; ap = ap->argnxt.ap) { ap->argchn.ap = ap->argnxt.ap; if (!ap->argnxt.ap) ap->argchn.ap = *arghead; } if (gp->gl_list) *arghead = (struct argnod *)gp->gl_list; return gp->gl_pathc + extra; }