Esempio n. 1
0
File: args.c Progetto: att/ast
// 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;
}
Esempio n. 2
0
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);
}
Esempio n. 3
0
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);
}
Esempio n. 4
0
File: expand.c Progetto: att/ast
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;
}