Esempio n. 1
0
File: macro.c Progetto: whizzter/lcc
/*
 * Do macro expansion in a row of tokens.
 * Flag is NULL if more input can be gathered.
 */
void
expandrow(Tokenrow *trp, char *flag)
{
	Token *tp;
	Nlist *np;

	if (flag)
		setsource(flag, NULL, "");
	for (tp = trp->tp; tp<trp->lp; ) {
		if (tp->type!=NAME
		 || quicklook(tp->t[0], tp->len>1?tp->t[1]:0)==0
		 || (np = lookup(tp, 0))==NULL
		 || (np->flag&(ISDEFINED|ISMAC))==0
		 || tp->hideset && checkhideset(tp->hideset, np)) {
			tp++;
			continue;
		}
		trp->tp = tp;
		if (np->val==KDEFINED) {
			tp->type = DEFINED;
			if ((tp+1)<trp->lp && (tp+1)->type==NAME)
				(tp+1)->type = NAME1;
			else if ((tp+3)<trp->lp && (tp+1)->type==LP
			 && (tp+2)->type==NAME && (tp+3)->type==RP)
				(tp+2)->type = NAME1;
			else
				error(ERROR, "Incorrect syntax for `defined'");
			tp++;
			continue;
		}
		if (np->flag&ISMAC)
			builtin(trp, np->val);
		else {
			expand(trp, np);
		}
		tp = trp->tp;
	}
	if (flag)
		unsetsource();
}
Esempio n. 2
0
void	ft_launch_exec(char *command, char ***env, int *execve_flag)
{
	char	**path;
	char	**cmd_arg;

	if (ft_strsrch(command, '|') != -1)
		exec_pipe(env, command, execve_flag);
	else
	{
		cmd_arg = get_clean_arg(command, *env);
		if (((path = ft_path(env, cmd_arg[0])) == NULL)
				&& ft_strcmp(command, "exit") != 0)
			ft_putendl("Set a good path or you will take expensive.");
		if ((ft_rd(command, env, execve_flag) == 1)
				&& (builtin(env, cmd_arg) == 0))
		{
			ft_execute_cmd(path, cmd_arg, *env, execve_flag);
			if (path)
				ft_tabfree(path);
		}
	}
}
static lval * lval_eval_sexpr(lval *v) {

	/* Evaluate children */
	for (int i = 0; i < v->count; i++) {
		v->cell[i] = lval_eval(v->cell[i]);
	}

	/* Error checking */
	for (int i = 0; i < v->count; i++) {
		if (v->cell[i]->type == LVAL_ERR) {
			return lval_take(v, i);
		}
	}

	/* Empty expression */
	if (v->count == 0) {
		return v;
	}

	/* Single expression */
	if (v->count == 1) {
		return lval_take(v, 0);
	}

	/* Ensure fist element is symbol */
	lval *f = lval_pop(v, 0);
	if (f->type != LVAL_SYM) {
		lval_del(f);
		lval_del(v);
		return lval_err("S-Expression does not start with symbol!");
	}

	/* Call builtin with operator */
	lval *result = builtin(v, f->sym);
	lval_del(f);
	return result;
}
Esempio n. 4
0
int
main(int argc, char *argv[])
{
	int i;
	int argi;
	Source *s;
	struct block *l;
	int restricted, errexit;
	char **wp;
	struct env env;
	pid_t ppid;

	/* make sure argv[] is sane */
	if (!*argv) {
		static const char *empty_argv[] = {
			"ksh", (char *) 0
		};

		argv = (char **) empty_argv;
		argc = 1;
	}
	kshname = *argv;

	ainit(&aperm);		/* initialize permanent Area */

	/* set up base environment */
	memset(&env, 0, sizeof(env));
	env.type = E_NONE;
	ainit(&env.area);
	e = &env;
	newblock();		/* set up global l->vars and l->funs */

	/* Do this first so output routines (eg, errorf, shellf) can work */
	initio();

	initvar();

	initctypes();

	inittraps();

	coproc_init();

	/* set up variable and command dictionaries */
	ktinit(&taliases, APERM, 0);
	ktinit(&aliases, APERM, 0);
	ktinit(&homedirs, APERM, 0);

	/* define shell keywords */
	initkeywords();

	/* define built-in commands */
	ktinit(&builtins, APERM, 64); /* must be 2^n (currently 40 builtins) */
	for (i = 0; shbuiltins[i].name != NULL; i++)
		builtin(shbuiltins[i].name, shbuiltins[i].func);
	for (i = 0; kshbuiltins[i].name != NULL; i++)
		builtin(kshbuiltins[i].name, kshbuiltins[i].func);

	init_histvec();

	def_path = _PATH_DEFPATH;
	{
		size_t len = confstr(_CS_PATH, (char *) 0, 0);
		char *new;

		if (len > 0) {
			confstr(_CS_PATH, new = alloc(len + 1, APERM), len + 1);
			def_path = new;
		}
	}
Esempio n. 5
0
int main(int argc, char **argv) {
	for (;;) {
		int c = getopt(argc, argv, "y");
		if (c == -1) break;
		switch (c) {
		case 'y':
			option_easy = 1;
			option_prompt = "> ";
			break;
		default:
			fprintf(stderr, "unrecognized option: %c\n", c);
			break;
		}
	}

	field_init_z(Z);
	field_init_multiz(M);
	symtab_init(tab);

	builtin(fun_rnd);
	builtin(fun_random);
	builtin(fun_ord);
	builtin(fun_order);
	builtin(fun_nextprime);
	builtin(fun_sqrt);
	builtin(fun_inv);
	builtin(fun_type);
	builtin(fun_pairing);
	builtin(fun_zmod);
	builtin(fun_poly);
	builtin(fun_polymod);
	builtin(fun_extend);
	builtin(fun_exit);
	builtin(fun_CHECK);
	builtin(fun_init_pairing_a);
	builtin(fun_init_pairing_d);
	builtin(fun_init_pairing_e);
	builtin(fun_init_pairing_f);
	builtin(fun_init_pairing_g);
	builtin(fun_init_pairing_i);
	run_init_pairing_a(NULL);
	symtab_put(reserved, val_new_field(M), "M");
	symtab_put(reserved, val_new_field(Z), "Z");

	if (argc > optind) {
		FILE *fp = fopen(argv[optind], "r");
		if (!fp) pbc_die("fopen failed on %s", argv[optind]);
		YY_BUFFER_STATE st = yy_create_buffer(fp, YY_BUF_SIZE);
		yy_switch_to_buffer(st);
		yywrapfun = yywrap_return1;
		yyparse();
		yy_delete_buffer(st);
	}
	else {
		yywrapfun = yywrap_readline;
		yywrap();
		while (!end_of_input) {
			if (2 == yyparse()) pbc_die("parser out of memory");
		}
		putchar('\n');
	}

	symtab_clear(tab);
	field_clear(M);
	return 0;
}
Esempio n. 6
0
intrcall(Namep np, struct Listblock *argsp, int nargs)
#endif
{
	int i, rettype;
	Addrp ap;
	register struct Specblock *sp;
	register struct Chain *cp;
	expptr q, ep;
	int mtype;
	int op;
	int f1field, f2field, f3field;

	packed.ijunk = np->vardesc.varno;
	f1field = packed.bits.f1;
	f2field = packed.bits.f2;
	f3field = packed.bits.f3;
	if(nargs == 0)
		goto badnargs;

	mtype = 0;
	for(cp = argsp->listp ; cp ; cp = cp->nextp)
	{
		ep = (expptr)cp->datap;
		if( ISCONST(ep) && ep->headblock.vtype==TYSHORT )
			cp->datap = (char *) mkconv(tyint, ep);
		mtype = maxtype(mtype, ep->headblock.vtype);
	}

	switch(f1field)
	{
	case INTRBOOL:
		op = f3field;
		if( ! ONEOF(mtype, MSKINT|MSKLOGICAL) )
			goto badtype;
		if(op == OPBITNOT)
		{
			if(nargs != 1)
				goto badnargs;
			q = mkexpr(OPBITNOT, (expptr)argsp->listp->datap, ENULL);
		}
		else
		{
			if(nargs != 2)
				goto badnargs;
			q = mkexpr(op, (expptr)argsp->listp->datap,
			    		(expptr)argsp->listp->nextp->datap);
		}
		frchain( &(argsp->listp) );
		free( (charptr) argsp);
		return(q);

	case INTRCONV:
		rettype = f2field;
		switch(rettype) {
		  case TYLONG:
			rettype = tyint;
			break;
		  case TYLOGICAL:
			rettype = tylog;
		  }
		if( ISCOMPLEX(rettype) && nargs==2)
		{
			expptr qr, qi;
			qr = (expptr) argsp->listp->datap;
			qi = (expptr) argsp->listp->nextp->datap;
			if(ISCONST(qr) && ISCONST(qi))
				q = mkcxcon(qr,qi);
			else	q = mkexpr(OPCONV,mkconv(rettype-2,qr),
			    mkconv(rettype-2,qi));
		}
		else if(nargs == 1) {
			if (f3field && ((Exprp)argsp->listp->datap)->vtype
					== TYDCOMPLEX)
				rettype = TYDREAL;
			q = mkconv(rettype+100, (expptr)argsp->listp->datap);
			if (q->tag == TADDR)
				q->addrblock.parenused = 1;
			}
		else goto badnargs;

		q->headblock.vtype = rettype;
		frchain(&(argsp->listp));
		free( (charptr) argsp);
		return(q);


#if 0
	case INTRCNST:

/* Machine-dependent f77 stuff that f2c omits:

intcon contains
	radix for short int
	radix for long int
	radix for single precision
	radix for double precision
	precision for short int
	precision for long int
	precision for single precision
	precision for double precision
	emin for single precision
	emin for double precision
	emax for single precision
	emax for double prcision
	largest short int
	largest long int

realcon contains
	tiny for single precision
	tiny for double precision
	huge for single precision
	huge for double precision
	mrsp (epsilon) for single precision
	mrsp (epsilon) for double precision
*/
	{	register struct Incstblock *cstp;
		extern ftnint intcon[14];
		extern double realcon[6];

		cstp = consttab + f3field;
		for(i=0 ; i<f2field ; ++i)
			if(cstp->atype == mtype)
				goto foundconst;
			else
				++cstp;
		goto badtype;

foundconst:
		switch(cstp->rtype)
		{
		case TYLONG:
			return(mkintcon(intcon[cstp->constno]));

		case TYREAL:
		case TYDREAL:
			return(mkrealcon(cstp->rtype,
			    realcon[cstp->constno]) );

		default:
			Fatal("impossible intrinsic constant");
		}
	}
#endif

	case INTRGEN:
		sp = spectab + f3field;
		if(no66flag)
			if(sp->atype == mtype)
				goto specfunct;
			else err66("generic function");

		for(i=0; i<f2field ; ++i)
			if(sp->atype == mtype)
				goto specfunct;
			else
				++sp;
		warn1 ("bad argument type to intrinsic %s", np->fvarname);

/* Made this a warning rather than an error so things like "log (5) ==>
   log (5.0)" can be accommodated.  When none of these cases matches, the
   argument is cast up to the first type in the spectab list; this first
   type is assumed to be the "smallest" type, e.g. REAL before DREAL
   before COMPLEX, before DCOMPLEX */

		sp = spectab + f3field;
		mtype = sp -> atype;
		goto specfunct;

	case INTRSPEC:
		sp = spectab + f3field;
specfunct:
		if(tyint==TYLONG && ONEOF(sp->rtype,M(TYSHORT)|M(TYLOGICAL))
		    && (sp+1)->atype==sp->atype)
			++sp;

		if(nargs != sp->nargs)
			goto badnargs;
		if(mtype != sp->atype)
			goto badtype;

/* NOTE!!  I moved fixargs (YES) into the ELSE branch so that constants in
   the inline expression wouldn't get put into the constant table */

		fixargs (NO, argsp);
		cast_args (mtype, argsp -> listp);

		if(q = Inline((int)(sp-spectab), mtype, argsp->listp))
		{
			frchain( &(argsp->listp) );
			free( (charptr) argsp);
		} else {

		    if(sp->othername) {
			/* C library routines that return double... */
			/* sp->rtype might be TYREAL */
			ap = builtin(sp->rtype,
				callbyvalue[sp->othername], 1);
			q = fixexpr((Exprp)
				mkexpr(OPCCALL, (expptr)ap, (expptr)argsp) );
		    } else {
			fixargs(YES, argsp);
			ap = builtin(sp->rtype, sp->spxname, 0);
			q = fixexpr((Exprp)
				mkexpr(OPCALL, (expptr)ap, (expptr)argsp) );
		    } /* else */
		} /* else */
		return(q);

	case INTRMIN:
	case INTRMAX:
		if(nargs < 2)
			goto badnargs;
		if( ! ONEOF(mtype, MSKINT|MSKREAL) )
			goto badtype;
		argsp->vtype = mtype;
		q = mkexpr( (f1field==INTRMIN ? OPMIN : OPMAX), (expptr)argsp, ENULL);

		q->headblock.vtype = mtype;
		rettype = f2field;
		if(rettype == TYLONG)
			rettype = tyint;
		else if(rettype == TYUNKNOWN)
			rettype = mtype;
		return( mkconv(rettype, q) );

	default:
		fatali("intrcall: bad intrgroup %d", f1field);
	}
badnargs:
	errstr("bad number of arguments to intrinsic %s", np->fvarname);
	goto bad;

badtype:
	errstr("bad argument type to intrinsic %s", np->fvarname);

bad:
	return( errnode() );
}
Esempio n. 7
0
/* 
 * eval - Evaluate the command line that the user has just typed in
 * 
 * If the user has requested a built-in command (quit, jobs, bg or fg)
 * then execute it immediately. Otherwise, fork a child process and
 * run the job in the context of the child. If the job is running in
 * the foreground, wait for it to terminate and then return.  Note:
 * each child process must have a unique process group ID so that our
 * background children don't receive SIGINT (SIGTSTP) from the kernel
 * when we type ctrl-c (ctrl-z) at the keyboard.  
 */
void 
eval(char *cmdline) 
{
    int bg;              /* should the job run in bg or fg? */
    struct cmdline_tokens tok;
    pid_t pid; /* recorrd the process id of child process*/
    int jid;   /* record job id*/
    sigset_t mask,emptyset; /* mask is a set of signal to be handled,
                             emptyset is for sigsuspend  */

    sigemptyset(&emptyset);

    /* Parse command line */
    bg = parseline(cmdline, &tok); 

    if (bg == -1) /* parsing error */
        return;
    if (tok.argv[0] == NULL) /* ignore empty lines */
        return;
    if(!builtin(&tok)) 
    {
    	/*
    	 *before starting the process of a child, signals shall 
    	 *be blocked in case of race problem
    	 */

        sigemptyset(&mask);
        sigaddset(&mask,SIGCHLD);
        sigaddset(&mask,SIGINT);
        sigaddset(&mask,SIGTSTP);
        sigprocmask(SIG_BLOCK,&mask,NULL);

        /*
         * child process
         */
    	if((pid=fork())==0)
    	{
           /* child process inherit from the parent process, 
            so the blocked signals should be restored here.*/
    		sigprocmask(SIG_UNBLOCK,&mask,NULL); 

    		//each child process should be in a different group
    		setpgid(0,0); 

    		// children process enable redirection
    		redirect(tok.infile,tok.outfile); 

           //children process loads a program and never return unless error
    		if(execve(tok.argv[0],tok.argv,environ)<0) 
    		{
    			printf("%s: Command not found!\n",tok.argv[0]);
    			exit(0);
    		}
    	}

        /*
         *parent process
         */

       if(bg)
       {
    	addjob(job_list,pid,BG,cmdline);

    	// parent reenable the signal interuption
    	sigprocmask(SIG_UNBLOCK,&mask,NULL);  

    	jid=pid2jid(pid);
    	printf("[%d] (%d) %s\n",jid,pid,cmdline);
       }
       if(!bg)
       {
       	addjob(job_list,pid,FG,cmdline);
       	sigprocmask(SIG_UNBLOCK,&mask,NULL);

       	/*
       	 * as a foreground job, parent process will wait 
       	 *for the child to cease.
       	 */
       	while(fgpid(job_list))
       	{
       		sigsuspend(&emptyset);
       	}
       }

    }        

    return;
}
Esempio n. 8
0
int eval_line(char *cmdline, int e_flag)
{
    char *_argv[MAXARGS];                         /* _argv for execve(), denoted by underscore to distinguish from main argv array*/
    char buf[MAXLINE];                            /* holds modified command line */
    int background;                               /* should the job run in background or foreground? */
    pid_t pid;                                    /* process id */
    int ret = EXIT_SUCCESS;

    strcpy(buf, cmdline);                         /* buf[] will be modified by parse() */
    /* build the argv array */
    background = parse(buf, _argv);

    if(e_flag > 0)
        Echo(_argv);

    if (_argv[0] == NULL)  /* ignore empty lines */
        { return ret; }

    if (builtin(_argv, process_table) == 1) /* the work is done */
        { return ret; }

    if(background)
    {
        block_signal(SIGINT, 1);
    }

    /* child runs user job */
    if ((pid = fork()) == 0)
    {
        if (execvp(_argv[0], _argv/*, environ*/) == -1)
        {
            printf("%s: execve failed: %s\n", _argv[0], strerror(errno));
            _exit(EXIT_FAILURE);
        }
    }

    if (background && pid != 0)                   /* parent waits for foreground job to terminate */
    {
        printf("background process %d: %s", (int) pid, cmdline);

        // Add to process table:
        int err;
        if( (err = insert_process_table(process_table, pid)) == -1)
        {
            fprintf(stderr, "insert_process_table failed: line %d: %s\n", __LINE__, strerror(errno));
        }

        // Passing 0 unblocks the signal.
        block_signal(SIGINT, 0);
    }
    else
    {
        if (waitpid(pid, &ret, 0) == -1)
        {
            printf("%s: waitpid failed: %s\n", _argv[0], strerror(errno));
            exit(EXIT_FAILURE);
        }
        // If in verbose mode, print out a detailed message:
        if(verbose)
        {
            printf("process %d, completed normally, status %d\n", pid, ret);
        }
    }


    return ret;
}
Esempio n. 9
0
	void visit(const Structure* structure) {
		Assert(isTheoryOpen());

		printTab();
		output() << "Data: " << '\n';
		indent();

		auto voc = structure->vocabulary();
		for (auto it = voc->firstSort(); it != voc->lastSort(); ++it) {
			auto s = it->second;
			if (not s->builtin()) {
				printTab();
				auto name = s->name();
				name = capitalize(name);
				output() << name << " = ";
				auto st = structure->inter(s);
				visit(st);
				output() << '\n';
			}
		}
		for (auto it = voc->firstPred(); it != voc->lastPred(); ++it) {
			auto sp = it->second->nonbuiltins();
			for (auto jt = sp.cbegin(); jt != sp.cend(); ++jt) {
				auto p = *jt;
				if (p->arity() == 1 && p->sorts()[0]->pred() == p) { // If it is in fact a sort, ignore it
					continue;
				}
				auto pi = structure->inter(p);
				if (pi->ct()->size() == 0 && pi->cf()->size() == 0) {
					continue;
				}
				if (not pi->approxTwoValued()) {
					output() << "Partial: " << '\n'; //TEMPORARY GO TO PARTIAL BLOCK
				}
				printTab();
				auto name = p->nameNoArity();
				name = capitalize(name);
				output() << name << " = ";
				visit(pi->ct());
				if (not pi->approxTwoValued()) {
					visit(pi->cf());
					output() << '\n';
					output() << "Data: "; //RETURN TO DATA BLOCK
				}
				output() << '\n';
			}
		}
		for (auto it = voc->firstFunc(); it != voc->lastFunc(); ++it) {
			auto sf = it->second->nonbuiltins();
			for (auto jt = sf.cbegin(); jt != sf.cend(); ++jt) {
				auto f = *jt;
				auto fi = structure->inter(f);
				if (fi->approxTwoValued()) {
					printTab();
					auto name = f->nameNoArity();
					name = capitalize(name);
					output() << name << " = ";
					auto ft = fi->funcTable();
					visit(ft);
				} else {
					auto pi = fi->graphInter();
					auto ct = pi->ct();
					auto cf = pi->cf();
					if (ct->approxEmpty() && cf->approxEmpty()) {
						continue;
					}
					output() << "Partial: " << '\n'; //TEMPORARY GO TO PARTIAL BLOCK
					printTab();
					auto name = f->nameNoArity();
					name = capitalize(name);
					output() << name << " = ";
					printAsFunc(ct);
					printAsFunc(cf);
					output() << '\n';
					output() << "Data: "; //RETURN TO DATA BLOCK
				}
				output() << '\n';
			}
		}
		unindent();
		output() << '\n';
	}
Esempio n. 10
0
// si le premier parametre est une commande integree,
// l'executer et renvoyer "vrai"
bool builtin_command(char **argv) {
    if (argv[0] == NULL)       // commande vide
        return true;
    if (strcmp(argv[0], "&") == 0) // ignorer & tout seul
        return true;

    builtin("exit", exit_try());
    builtin("quit", exit_try());

    builtin("jobs", builtin_jobs());
    builtin("fg",   builtin_fg(argv));
    builtin("bg",   builtin_bg(argv));
    builtin("int",  builtin_int(argv));
    builtin("term", builtin_term(argv));
    builtin("stop", builtin_stop(argv));
    builtin("wait", builtin_wait());

    builtin("dirs", dirs_print());
    builtin("cd", dirs_cd(argv[1]));
    builtin("pushd", dirs_pushd(argv[1]));
    builtin("popd", dirs_popd());

    return false; // ce n'est pas une commande integree
}
Esempio n. 11
0
int execute(TREPTR argt, int execflg, int *pf1, int *pf2)
{
	/* `stakbot' is preserved by this routine */
	register TREPTR t;
	STKPTR sav = savstak();

	sigchk();

	if ((t = argt) && execbrk == 0) {
		register int treeflgs;
		int oldexit, type;
		register char **com;

		treeflgs = t->tretyp;
		type = treeflgs & COMMSK;
		oldexit = exitval;
		exitval = 0;

		switch (type) {

		case TCOM:
			{
				STRING a1;
				int argn, internal;
				ARGPTR schain = gchain;
				IOPTR io = t->treio;
				gchain = 0;
				argn = getarg((void *)t);/*FIXME*/
				com = scan(argn);
				a1 = com[1];
				gchain = schain;

				if ((internal = syslook(com[0], commands)) || argn == 0)
					setlist(((COMPTR) t)->comset, 0);

				if (argn && (flags & noexec) == 0) {	/* print command if execpr */
					if (flags & execpr) {
						argn = 0;
						prs(execpmsg);
						while (com[argn] != ENDARGS) {
							prs(com[argn++]);
							blank();
						}
						newline();
					}

					switch (internal) {

					case SYSDOT:
						if (a1) {
							register int f;

							if ((f = pathopen(getpath(a1), a1)) < 0)
								failed(a1, notfound);
							else
								execexp(0, f);
						}
						break;

					case SYSTIMES:
					{
						struct tms t;
						times(&t);
						prt(t.tms_cutime);
						blank();
						prt(t.tms_cstime);
						newline();
					}
					break;

					case SYSEXIT:
						exitsh(a1 ? stoi(a1) : oldexit);

					case SYSNULL:
						io = 0;
						break;

					case SYSCONT:
						execbrk = -loopcnt;
						break;

					case SYSBREAK:
						if ((execbrk = loopcnt) && a1)
							breakcnt = stoi(a1);
						break;

					case SYSTRAP:
						if (a1) {
							BOOL clear;
							if ((clear = digit(*a1)) == 0)
								++com;
							while (*++com) {
								int i;
								if ((i = stoi(*com)) >= MAXTRAP || i < MINTRAP)
									failed(*com, badtrap);
								else if (clear)
									clrsig(i);
								else {
									replace(&trapcom[i], a1);
									if (*a1)
										getsig(i);
									else
										ignsig(i);
								}
							}
						} else {	/* print out current traps */
							int i;

							for (i = 0; i < MAXTRAP; i++) {
								if (trapcom[i]) {
									prn(i);
									prs(colon);
									prs(trapcom[i]);
									newline();
								}
							}
						}
						break;

					case SYSEXEC:
						com++;
						initio(io);
						ioset = 0;
						io = 0;
						if (a1 == 0)
							break;

					case SYSLOGIN:
						flags |= forked;
						oldsigs();
						execa((const char **)com);
						done();

					case SYSCD:
						if (flags & rshflg)
							failed(com[0], restricted);
						else if ((a1 == 0 && (a1 = (char *)homenod.namval) == 0) || chdir(a1) < 0) /* FIXME */
							failed(a1, baddir);
						break;

					case SYSSHFT:
						if (dolc < 1)
							error(badshift);
						else {
							dolv++;
							dolc--;
						}
						assnum(&dolladr, dolc);
						break;

					case SYSWAIT:
						await(-1);
						break;

					case SYSREAD:
						exitval = readvar(&com[1]);
						break;

/*
				case SYSTST:
					exitval=testcmd(com);
					break;
*/

					case SYSSET:
						if (a1) {
							int argc;
							argc = options(argn, (const char **)com);
							if (argc > 1)
								setargs((const char **)com + argn - argc);
						} else if (((COMPTR) t)->comset == 0)
						        /* Scan name chain and print */
							namscan(printnam);
						break;

					case SYSRDONLY:
						exitval = N_RDONLY;
					case SYSXPORT:
						if (exitval == 0)
							exitval = N_EXPORT;;

						if (a1) {
							while (*++com)
								attrib(lookup(*com), exitval);
						} else {
							namscan(printflg);
						}
						exitval = 0;
						break;

					case SYSEVAL:
						if (a1)
							execexp(a1, (UFD)&com[2]);	/* FIXME */
						break;

					case SYSUMASK:
						if (a1) {
							int c, i;
							i = 0;
							while ((c = *a1++) >= '0' && c <= '7')
								i = (i << 3) + c - '0';
							umask(i);
						} else {
							int i, j;
							umask(i = umask(0));
							prc('0');
							for (j = 6; j >= 0; j -= 3)
								prc(((i >> j) & 07) + '0');
							newline();
						}
						break;

					default:
						internal = builtin(argn, com);

					}

					if (internal) {
						if (io)
							error(illegal);
						chktrap();
						break;
					}
				} else if (t->treio == 0)
					break;
			}

		case TFORK:
			if (execflg && (treeflgs & (FAMP | FPOU)) == 0)
				parent = 0;
			else {
				while ((parent = fork()) == -1) {
					sigchk();
					alarm(10);
					pause();
				}
			}

			if (parent) {	/* This is the parent branch of fork;    */
				/* it may or may not wait for the child. */
				if (treeflgs & FPRS && flags & ttyflg) {
					prn(parent);
					newline();
				}
				if (treeflgs & FPCL)
					closepipe(pf1);
				if ((treeflgs & (FAMP | FPOU)) == 0)
					await(parent);
				else if ((treeflgs & FAMP) == 0)
					post(parent);
				else
					assnum(&pcsadr, parent);

				chktrap();
				break;
			} else {	/* this is the forked branch (child) of execute */
				flags |= forked;
				iotemp = 0;
				postclr();
				settmp();

				/* Turn off INTR and QUIT if `FINT'  */
				/* Reset ramaining signals to parent */
				/* except for those `lost' by trap   */
				oldsigs();
				if (treeflgs & FINT) {
					signal(INTR, SIG_IGN);
					signal(QUIT, SIG_IGN);
				}

				/* pipe in or out */
				if (treeflgs & FPIN) {
					sh_rename(pf1[INPIPE], 0);
					close(pf1[OTPIPE]);
				}
				if (treeflgs & FPOU) {
					sh_rename(pf2[OTPIPE], 1);
					close(pf2[INPIPE]);
				}

				/* default std input for & */
				if (treeflgs & FINT && ioset == 0)
					sh_rename(chkopen(devnull), 0);

				/* io redirection */
				initio(t->treio);
				if (type != TCOM)
					execute(((FORKPTR) t)->forktre, 1, NULL, NULL);
				else if (com[0] != ENDARGS) {
					setlist(((COMPTR) t)->comset, N_EXPORT);
					execa((const char **)com);
				}
				done();
			}

		case TPAR:
			sh_rename(dup(2), output);
			execute(((PARPTR) t)->partre, execflg, NULL, NULL);
			done();

		case TFIL:
		{
			int pv[2];
			chkpipe(pv);
			if (execute(((LSTPTR) t)->lstlef, 0, pf1, pv) == 0)
				execute(((LSTPTR) t)->lstrit, execflg, pv, pf2);
			else
				closepipe(pv);
			break;
                }
		case TLST:
			execute(((LSTPTR) t)->lstlef, 0, NULL, NULL);
			execute(((LSTPTR) t)->lstrit, execflg, NULL, NULL);
			break;

		case TAND:
			if (execute(((LSTPTR) t)->lstlef, 0, NULL, NULL) == 0)
				execute(((LSTPTR) t)->lstrit, execflg, NULL, NULL);
			break;

		case TORF:
			if (execute(((LSTPTR) t)->lstlef, 0, NULL, NULL) != 0)
				execute(((LSTPTR) t)->lstrit, execflg, NULL, NULL);
			break;

		case TFOR:
		{
			NAMPTR n = lookup(((FORPTR) t)->fornam);
			char **args;
			DOLPTR argsav = 0;

			if (((FORPTR) t)->forlst == 0) {
				args = (char **)dolv + 1;
				argsav = useargs();
			} else {
				ARGPTR schain = gchain;
				gchain = 0;
				trim((args = scan(getarg(((FORPTR) t)->forlst)))[0]);
				gchain = schain;
			}
			loopcnt++;
			while (*args != ENDARGS && execbrk == 0) {
				assign(n, *args++);
				execute(((FORPTR) t)->fortre, 0, NULL, NULL);
				if (execbrk < 0) {
					execbrk = 0;
				}
			}
			if (breakcnt)
				breakcnt--;
			execbrk = breakcnt;
			loopcnt--;
			argfor = freeargs(argsav);
        		break;
		}

		case TWH:
		case TUN:
		{
			int i = 0;

			loopcnt++;
			while (execbrk == 0 && (execute(((WHPTR) t)->whtre, 0, NULL, NULL) == 0) == (type == TWH)) {
				i = execute(((WHPTR) t)->dotre, 0, NULL, NULL);
				if (execbrk < 0)
					execbrk = 0;
			}
			if (breakcnt)
				breakcnt--;

			execbrk = breakcnt;
			loopcnt--;
			exitval = i;
			break;
		}

		case TIF:
			if (execute(((IFPTR) t)->iftre, 0, NULL, NULL) == 0)
				execute(((IFPTR) t)->thtre, execflg, NULL, NULL);
			else
				execute(((IFPTR) t)->eltre, execflg, NULL, NULL);
			break;

		case TSW:
		{
			register char *r = mactrim(((SWPTR) t)->swarg);
			t = (TREPTR) ((SWPTR) t)->swlst;
			while (t) {
				ARGPTR rex = ((REGPTR) t)->regptr;
				while (rex) {
					register char *s;
					if (gmatch(r, s = macro(rex->argval)) || (trim(s), eq(r, s))) {
						execute(((REGPTR)t)->regcom, 0, NULL, NULL);
						t = 0;
						break;
					} else
						rex = ((ARGPTR)rex)->argnxt;
				}
				if (t)
					t = (TREPTR) ((REGPTR) t)->regnxt;
			}
		}
		break;

		}
		exitset();
	}
Esempio n. 12
0
void execute(struct treenode *node, int *pipe1, int *pipe2)
{
	int flag, ret;
	pid_t pid;
	int pv[2];
	struct treenode *tmp;

	if (node == NULL) {
		return;
	}

	switch (node->type) {
		case CMDLIST:
			flag = node->flags;
			execute(node->left, NULL, NULL);
			execute(node->right, NULL, NULL);
			free_treenode(node);
			return; 	//why return? Because the rest will be executed by child.

		case FILTER:
			flag = node->flags;
			pipe(pv);

			tmp = node->left;
			tmp->flags |= PIPE_OUT | (flag & (PIPE_IN | LAST_IN_PAR));
			execute(node->left, pipe1, pv);

			tmp = node->right;
			tmp->flags |= PIPE_IN | (flag & (PIPE_OUT | AND | LAST_IN_PAR));
			execute(node->right, pv, pipe2);

			free_treenode(node);
			return;

		case COMMAND:
			if (builtin(node) == 0) {
				free_treenode(node);
				return;
			}

		case PARENTHESES:
			pid = 0;
			flag = node->flags;

			//if the LAST_IN_PAR, not fork, use the current 
			if ((flag & LAST_IN_PAR) == 0) {
				pid = fork();
				if (pid == -1) {
					perror("fail to fork");
					return;
				}
			}

			// parent
			if (pid != 0) {
				if ((flag & PIPE_IN) != 0) {
					close(pipe1[0]);
					close(pipe1[1]);
				}

				if ((flag & AND) != 0) {
					printf("%d\n", pid);
					free_treenode(node);
					return;
				}

				pwait(pid);
				free_treenode(node);
				return;
			}

			//child
			if (node->in || node->out) {
				if (redirect(node) != 0) {
					exit(-1);
				}
			}

			if ((flag & PIPE_IN) != 0) {
				close(STDIN_FILENO);
				dup(pipe1[0]);
				close(pipe1[0]);
				close(pipe1[1]);
			}

			if ((flag & PIPE_OUT) != 0) {
				close(STDOUT_FILENO);
				dup(pipe2[1]);
				close(pipe2[1]);
				close(pipe2[0]);
			}

			if (node->type == PARENTHESES) {
				tmp = node->child;
				execute(tmp, NULL, NULL);
				exit(1);
			}

			ret = execute_cmd(node);
			exit(ret);
	}
}
Esempio n. 13
0
/*
 * Do macro expansion in a row of tokens.
 * Flag is NULL if more input can be gathered.
 */
void
    expandrow(Tokenrow * trp, char *flag)
{
    Token * tp;
    Nlist * np;

    MacroValidatorList  validators;
    mvl_init(&validators);
    /* Sets all token-identifiers to 0 because tokens may not be initialised (never use C!) */
    tokenrow_zeroTokenIdentifiers(trp);

    if (flag)
        setsource(flag, -1, -1, "", 0);
    for (tp = trp->tp; tp < trp->lp;)
    {
        mvl_check(&validators, tp);

        if (tp->type != NAME
            || quicklook(tp->t[0], tp->len > 1 ? tp->t[1] : 0) == 0
            || (np = lookup(tp, 0)) == NULL
            || (np->flag & (ISDEFINED | ISMAC)) == 0
            || (np->flag & ISACTIVE) != 0)
        {
            tp++;
            continue;
        }
        trp->tp = tp;
        if (np->val == KDEFINED)
        {
            tp->type = DEFINED;
            if ((tp + 1) < trp->lp && (tp + 1)->type == NAME)
                (tp + 1)->type = NAME1;
            else
                if ((tp + 3) < trp->lp && (tp + 1)->type == LP
                    && (tp + 2)->type == NAME && (tp + 3)->type == RP)
                    (tp + 2)->type = NAME1;
                else
                    error(ERROR, "Incorrect syntax for `defined'");
            tp++;
            continue;
        }
        else
            if (np->val == KMACHINE)
            {
                if (((tp - 1) >= trp->bp) && ((tp - 1)->type == SHARP))
                {
                    tp->type = ARCHITECTURE;
                    if ((tp + 1) < trp->lp && (tp + 1)->type == NAME)
                        (tp + 1)->type = NAME2;
                    else
                        if ((tp + 3) < trp->lp && (tp + 1)->type == LP
                            && (tp + 2)->type == NAME && (tp + 3)->type == RP)
                            (tp + 2)->type = NAME2;
                        else
                            error(ERROR, "Incorrect syntax for `#machine'");
                }
                tp++;
                continue;
            }

        if (np->flag & ISMAC)
            builtin(trp, np->val);
        else
            expand(trp, np, &validators);
        tp = trp->tp;
    }   // end for
    if (flag)
        unsetsource();

    mvl_destruct(&validators);
}
Esempio n. 14
0
/* main - Start of shell, doesn't care for arguments */
int main(int argc, char* argv[])
{
    int retval;

    char cmd_line[MAX_LENGTH];
    /* Allocate memory for argument vector */
    char **args = (char **) malloc(MAX_ARGS * sizeof(char*));

    /* Register proper signals to handle */
    register_signals();

    /* Set string for promt */
    USER = getenv("USER");

    /* Main loop */
    while (1)
    {

#ifndef SIGNALDETECTION
        /* Check if any background processes has exited */
        retval = check_background_procs();
        if (retval == -1 && errno != ECHILD)
            perror("wait failed");
#endif

        /* Print a new promt */
        print_prompt();

        /* Fetch new command from terminal */
        if (fgets(cmd_line, MAX_LENGTH, stdin) != NULL) /* Success */
        {
            /* Parse user command */
            retval = parse_command(cmd_line, args);

            if (retval == 1) /* Empty cmd */
                continue; /* Restart loop, for checking background etc.. */

            /* If the command is available as a builtin, use that */
            if (builtin(args))
            {
                retval = run_builtin(args);
                if (retval == B_EXIT) /* EXIT */
                {
                    retval = check_background_procs();
                    /* retval == 0 means no error for having no children were
                     * returned */

                    /* Kill all child processes */
                    if (retval == 0)
                        retval = kill(-getpid(), SIGKILL);

                    break; /* Breaks main loop and exits */
                }
                else if (retval == B_FALIURE) /* Something went wrong */
                    fprintf(stderr, "Command, %s, could not be executed\n", args[0]);
            }
            else /* Run a command */
            {
                /* Run in the background */
                if (background(args))
                {
                    run_program(args, 1);
                }
                else /* Run blocking */
                {
                    retval = run_program_block(args);
                    if (retval IS_ERROR)
                    {
                        if (retval == INVALIDARGS)
                            fprintf(stderr, "Invalid argument\n");
                        else if (retval == PIPEERROR)
                            fprintf(stderr, "Pipe error\n");
                        else if (retval == FORKERROR)
                            fprintf(stderr, "Fork error\n");
                    }
                }
            }
        }
    }

    /* Free memmory */
    free(args);
    
    return 0;
}
Esempio n. 15
0
int main(int argc, char **argv) {
    int ierr, nhits, vselect;
    const char *conffile;
    const char *logfile;
    FILE* output;
    FastBitQueryHandle qh;
    FastBitResultSetHandle rh;

    ierr = 0;
    vselect = 1;
    logfile = 0;
    conffile = 0;
#if defined(DEBUG) || defined(_DEBUG)
#if DEBUG + 0 > 10 || _DEBUG + 0 > 10
    ierr = INT_MAX;
#elif DEBUG + 0 > 0
    ierr += 7 * DEBUG;
#elif _DEBUG + 0 > 0
    ierr += 5 * _DEBUG;
#else
    ierr += 3;
#endif
#endif
    /* process arguments started with - */
    while (vselect < argc && argv[vselect][0] == '-') {
	if (argv[vselect][1] == 'c' || argv[vselect][1] == 'C') {
	    if (vselect+1 < argc) {
		conffile = argv[vselect+1];
		vselect += 2;
	    }
	    else {
		vselect += 1;
	    }
	}
	else if (argv[vselect][1] == 'h' || argv[vselect][1] == 'H') {
	    usage(*argv);
	    vselect += 1;
	}
#if defined(TCAPI_USE_LOGFILE)
	else if (argv[vselect][1] == 'l' || argv[vselect][1] == 'L') {
	    if (vselect+1 < argc) {
		logfile = argv[vselect+1];
		vselect += 2;
	    }
	    else {
		vselect += 1;
	    }
	}
#endif
	else if (argv[vselect][1] == 'm' || argv[vselect][1] == 'M' ||
		 argv[vselect][1] == 'v' || argv[vselect][1] == 'V') {
	    if (vselect+1 < argc &&
		(isdigit(argv[vselect+1][0]) != 0 ||
		 (argv[vselect+1][0] == '-' &&
		  isdigit(argv[vselect+1][1]) != 0))) {
		ierr += atoi(argv[vselect+1]);
		vselect += 2;
	    }
	    else {
		ierr += 1;
		vselect += 1;
	    }
	}
	else {
	    fprintf(stderr, "%s: unknown option %s\n", *argv, argv[vselect]);
	    ++ vselect;
	}
    }

    fastbit_init((const char*)conffile);
    fastbit_set_verbose_level(ierr);
    fastbit_set_logfile(logfile);
#if defined(TCAPI_USE_LOGFILE)
    output = fastbit_get_logfilepointer();
    printf("%s: output=0x%8.8x, stdout=0x%8.8x\n", *argv, output, stdout);
#else
    output = stdout;
#endif
    if (argc <= vselect) {
	builtin(*argv, output);
	return -1;
    }

    if (argc == vselect+1) /* buld indexes */
	return fastbit_build_indexes(argv[vselect], (const char*)0);

    qh = fastbit_build_query(0, argv[vselect], argv[vselect+1]);
    if (qh == 0) {
	fprintf(output, "%s failed to process query \"%s\" on data in %s\n",
		argv[0], argv[vselect+1], argv[vselect]);
	fastbit_cleanup();
	return -2;
    }

    nhits = fastbit_get_result_rows(qh);
    fprintf(output, "%s: applying \"%s\" on data in %s produced %d hit%s\n",
	    argv[0], argv[vselect+1], argv[vselect], nhits,
	    (nhits>1 ? "s" : ""));
    if (nhits <= 0)
	return 0;

    /* print the selected values specified in the select clause.  Since the
       select clause was nil in the call to fastbit_build_query, there
       would be nothing to print here! */
    rh = fastbit_build_result_set(qh);
    if (rh != 0) {
	int ncols = fastbit_get_result_columns(qh);
	fprintf(output, "%s\n", fastbit_get_select_clause(qh));
	while (fastbit_result_set_next(rh) == 0) {
	    int i;
	    fprintf(output, "%s", fastbit_result_set_getString(rh, 0));
	    for (i = 1; i < ncols; ++ i)
		fprintf(output, ", %s", fastbit_result_set_getString(rh, i));
	    fprintf(output, "\n");
	}
	fastbit_destroy_result_set(rh);
    }
    fflush(output);

    vselect += 2;
    /* print attributes explicitly specified on the command line */
    if (argc > vselect) {
	int i, j;
	for (i = vselect; i < argc; i += 2) {
	    char t = (i+1<argc ? argv[i+1][0] : 'i');
	    switch (t) {
	    default:
	    case 'i':
	    case 'I': {
		const int32_t *tmp = fastbit_get_qualified_ints(qh, argv[i]);
		if (tmp != 0) {
		    fprintf(output, "%s[%d]=", argv[i], nhits);
		    for (j = 0; j < nhits; ++ j)
			fprintf(output, "%d ", (int)tmp[j]);
		    fprintf(output, "\n");
		}
		else {
		    fprintf(output, "%s: failed to retrieve values for "
			    "column %s (requested type %c)\n",
			    argv[0], argv[i], t);
		}
		break;}
	    case 'u':
	    case 'U': {
		const uint32_t *tmp = fastbit_get_qualified_uints(qh, argv[i]);
		if (tmp != 0) {
		    fprintf(output, "%s[%d]=", argv[i], nhits);
		    for (j = 0; j < nhits; ++ j)
			fprintf(output, "%u ", (unsigned)tmp[j]);
		    fprintf(output, "\n");
		}
		else {
		    fprintf(output, "%s: failed to retrieve value for "
			    "column %s (requested type %c)\n",
			    argv[0], argv[i], t);
		}
		break;}
	    case 'l':
	    case 'L': {
		const int64_t *tmp = fastbit_get_qualified_longs(qh, argv[i]);
		if (tmp != 0) {
		    fprintf(output, "%s[%d]=", argv[i], nhits);
		    for (j = 0; j < nhits; ++ j)
			fprintf(output, "%lld ", (long long)tmp[j]);
		    fprintf(output, "\n");
		}
		else {
		    fprintf(output, "%s: failed to retrieve value for "
			    "column %s (requested type %c)\n",
			    argv[0], argv[i], t);
		}
		break;}
	    case 'r':
	    case 'R':
	    case 'f':
	    case 'F': {
		const float *tmp = fastbit_get_qualified_floats(qh, argv[i]);
		if (tmp != 0) {
		    fprintf(output, "%s[%d]=", argv[i], nhits);
		    for (j = 0; j < nhits; ++ j)
			fprintf(output, "%g ", tmp[j]);
		    fprintf(output, "\n");
		}
		else {
		    fprintf(output, "%s: failed to retrieve value for "
			    "column %s (requested type %c)\n",
			    argv[0], argv[i], t);
		}
		break;}
	    case 'd':
	    case 'D': {
		const double *tmp = fastbit_get_qualified_doubles(qh, argv[i]);
		if (tmp != 0) {
		    fprintf(output, "%s[%d]=", argv[i], nhits);
		    for (j = 0; j < nhits; ++ j)
			fprintf(output, "%lG ", tmp[j]);
		    fprintf(output, "\n");
		}
		else {
		    fprintf(output, "%s: failed to retrieve value for "
			    "column %s (requested type %c)\n",
			    argv[0], argv[i], t);
		}
		break;}
	    case 's':
	    case 'S':
	    case 't':
	    case 'T': {
		const char **tmp = fastbit_get_qualified_strings(qh, argv[i]);
		if (tmp != 0) {
		    fprintf(output, "%s[%d]=", argv[i], nhits);
		    for (j = 0; j < nhits; ++ j)
			fprintf(output, "\"%s\" ", tmp[j]);
		    fprintf(output, "\n");
		}
		else {
		    fprintf(output, "%s: failed to retrieve value for "
			    "column %s (requested type %c)\n",
			    argv[0], argv[i], t);
		}
		break;}
	    }
	}
    }

    ierr = fastbit_destroy_query(qh);
    fastbit_cleanup();
    return ierr;
} /* main */
Esempio n. 16
0
PUBLIC WORD parse(INT old_nesting)
{
        int nesting = (int) old_nesting;
        int quoted;
	
        nextsym();

        if( symb==s_eof ) return nesting;

	parse_depth++;

	if( ( quoted = (symb==s_quote) ) != 0 ) nextsym();

/*	trace("Parse %squoted depth %d",quoted?"":"un",parse_depth); */
		
        for(;;)
        {
                switch ( (int)symb )
                {
                case s_builtin: if(!quoted) { builtin(); break; }

                case s_macro:   if(!quoted) { eval(); break; }

		case s_hexvar:
                case s_var:     if(!quoted) { evalvar(); break; }

                default:
                case s_token:  
				if( toksize == 1 ) wrch(token[0]);
				else wrstr(token);
				break;

                case s_lbra:
                        if( nesting++ > 0) wrch(c_lbra);
                        break;

                case s_rbra:
                        if( --nesting > 0 ) wrch(c_rbra);
                        break;

                case s_eof: return nesting;

                case s_quote:
                        if( quoted ) wrch(c_quote);
                        pbchar(c_quote);
                        nesting = (int) parse((WORD)nesting);
                        break;
                       
                case s_concat:
                        if( quoted ) wrch(c_concat);
                        break;
                }

                if ( nesting <= old_nesting ) break;

                nextsym();
        }

	parse_depth--;

	return nesting;
}
Esempio n. 17
0
static int
main_init(int argc, const char *argv[], Source **sp, struct block **lp)
{
	int argi, i;
	Source *s = NULL;
	struct block *l;
	unsigned char restricted_shell, errexit, utf_flag;
	char *cp;
	const char *ccp, **wp;
	struct tbl *vp;
	struct stat s_stdin;
#if !defined(_PATH_DEFPATH) && defined(_CS_PATH)
	ssize_t k;
#endif

#if defined(MKSH_EBCDIC) || defined(MKSH_FAUX_EBCDIC)
	ebcdic_init();
#endif
	set_ifs(TC_IFSWS);

#ifdef __OS2__
	os2_init(&argc, &argv);
#endif

	/* do things like getpgrp() et al. */
	chvt_reinit();

	/* make sure argv[] is sane, for weird OSes */
	if (!*argv) {
		argv = empty_argv;
		argc = 1;
	}
	kshname = argv[0];

	/* initialise permanent Area */
	ainit(&aperm);
	/* max. name length: -2147483648 = 11 (+ NUL) */
	vtemp = alloc(offsetof(struct tbl, name[0]) + 12, APERM);

	/* set up base environment */
	env.type = E_NONE;
	ainit(&env.area);
	/* set up global l->vars and l->funs */
	newblock();

	/* Do this first so output routines (eg, errorf, shellf) can work */
	initio();

	/* determine the basename (without '-' or path) of the executable */
	ccp = kshname;
	goto begin_parsing_kshname;
	while ((i = ccp[argi++])) {
		if (mksh_cdirsep(i)) {
			ccp += argi;
 begin_parsing_kshname:
			argi = 0;
			if (*ccp == '-')
				++ccp;
		}
	}
	if (!*ccp)
		ccp = empty_argv[0];

	/*
	 * Turn on nohup by default. (AT&T ksh does not have a nohup
	 * option - it always sends the hup).
	 */
	Flag(FNOHUP) = 1;

	/*
	 * Turn on brace expansion by default. AT&T kshs that have
	 * alternation always have it on.
	 */
	Flag(FBRACEEXPAND) = 1;

	/*
	 * Turn on "set -x" inheritance by default.
	 */
	Flag(FXTRACEREC) = 1;

	/* define built-in commands and see if we were called as one */
	ktinit(APERM, &builtins,
	    /* currently up to 54 builtins: 75% of 128 = 2^7 */
	    7);
	for (i = 0; mkshbuiltins[i].name != NULL; i++)
		if (!strcmp(ccp, builtin(mkshbuiltins[i].name,
		    mkshbuiltins[i].func)))
			Flag(FAS_BUILTIN) = 1;

	if (!Flag(FAS_BUILTIN)) {
		/* check for -T option early */
		argi = parse_args(argv, OF_FIRSTTIME, NULL);
		if (argi < 0)
			return (1);

#if defined(MKSH_BINSHPOSIX) || defined(MKSH_BINSHREDUCED)
		/* are we called as -sh or /bin/sh or so? */
		if (!strcmp(ccp, "sh" MKSH_EXE_EXT)) {
			/* either also turns off braceexpand */
#ifdef MKSH_BINSHPOSIX
			/* enable better POSIX conformance */
			change_flag(FPOSIX, OF_FIRSTTIME, true);
#endif
#ifdef MKSH_BINSHREDUCED
			/* enable kludge/compat mode */
			change_flag(FSH, OF_FIRSTTIME, true);
#endif
		}
#endif
	}

	initvar();

	inittraps();

	coproc_init();

	/* set up variable and command dictionaries */
	ktinit(APERM, &taliases, 0);
	ktinit(APERM, &aliases, 0);
#ifndef MKSH_NOPWNAM
	ktinit(APERM, &homedirs, 0);
#endif

	/* define shell keywords */
	initkeywords();

	init_histvec();

	/* initialise tty size before importing environment */
	change_winsz();

#ifdef _PATH_DEFPATH
	def_path = _PATH_DEFPATH;
#else
#ifdef _CS_PATH
	if ((k = confstr(_CS_PATH, NULL, 0)) > 0 &&
	    confstr(_CS_PATH, cp = alloc(k + 1, APERM), k + 1) == k + 1)
		def_path = cp;
	else
#endif
		/*
		 * this is uniform across all OSes unless it
		 * breaks somewhere hard; don't try to optimise,
		 * e.g. add stuff for Interix or remove /usr
		 * for HURD, because e.g. Debian GNU/HURD is
		 * "keeping a regular /usr"; this is supposed
		 * to be a sane 'basic' default PATH
		 */
		def_path = MKSH_UNIXROOT "/bin" MKSH_PATHSEPS
		    MKSH_UNIXROOT "/usr/bin" MKSH_PATHSEPS
		    MKSH_UNIXROOT "/sbin" MKSH_PATHSEPS
		    MKSH_UNIXROOT "/usr/sbin";
#endif

	/*
	 * Set PATH to def_path (will set the path global variable).
	 * (import of environment below will probably change this setting).
	 */
	vp = global(TPATH);
	/* setstr can't fail here */
	setstr(vp, def_path, KSH_RETURN_ERROR);

#ifndef MKSH_NO_CMDLINE_EDITING
	/*
	 * Set edit mode to emacs by default, may be overridden
	 * by the environment or the user. Also, we want tab completion
	 * on in vi by default.
	 */
	change_flag(FEMACS, OF_SPECIAL, true);
#if !MKSH_S_NOVI
	Flag(FVITABCOMPLETE) = 1;
#endif
#endif

	/* import environment */
	init_environ();

	/* override default PATH regardless of environment */
#ifdef MKSH_DEFPATH_OVERRIDE
	vp = global(TPATH);
	setstr(vp, MKSH_DEFPATH_OVERRIDE, KSH_RETURN_ERROR);
#endif

	/* for security */
	typeset(TinitIFS, 0, 0, 0, 0);

	/* assign default shell variable values */
	typeset("PATHSEP=" MKSH_PATHSEPS, 0, 0, 0, 0);
	substitute(initsubs, 0);

	/* Figure out the current working directory and set $PWD */
	vp = global(TPWD);
	cp = str_val(vp);
	/* Try to use existing $PWD if it is valid */
	set_current_wd((mksh_abspath(cp) && test_eval(NULL, TO_FILEQ, cp,
	    Tdot, true)) ? cp : NULL);
	if (current_wd[0])
		simplify_path(current_wd);
	/* Only set pwd if we know where we are or if it had a bogus value */
	if (current_wd[0] || *cp)
		/* setstr can't fail here */
		setstr(vp, current_wd, KSH_RETURN_ERROR);

	for (wp = initcoms; *wp != NULL; wp++) {
		c_builtin(wp);
		while (*wp != NULL)
			wp++;
	}
	setint_n(global("OPTIND"), 1, 10);

	kshuid = getuid();
	kshgid = getgid();
	kshegid = getegid();

	safe_prompt = ksheuid ? "$ " : "# ";
	vp = global("PS1");
	/* Set PS1 if unset or we are root and prompt doesn't contain a # */
	if (!(vp->flag & ISSET) ||
	    (!ksheuid && !strchr(str_val(vp), '#')))
		/* setstr can't fail here */
		setstr(vp, safe_prompt, KSH_RETURN_ERROR);
	setint_n((vp = global("BASHPID")), 0, 10);
	vp->flag |= INT_U;
	setint_n((vp = global("PGRP")), (mksh_uari_t)kshpgrp, 10);
	vp->flag |= INT_U;
	setint_n((vp = global("PPID")), (mksh_uari_t)kshppid, 10);
	vp->flag |= INT_U;
	setint_n((vp = global("USER_ID")), (mksh_uari_t)ksheuid, 10);
	vp->flag |= INT_U;
	setint_n((vp = global("KSHUID")), (mksh_uari_t)kshuid, 10);
	vp->flag |= INT_U;
	setint_n((vp = global("KSHEGID")), (mksh_uari_t)kshegid, 10);
	vp->flag |= INT_U;
	setint_n((vp = global("KSHGID")), (mksh_uari_t)kshgid, 10);
	vp->flag |= INT_U;
	setint_n((vp = global("RANDOM")), rndsetup(), 10);
	vp->flag |= INT_U;
	setint_n((vp_pipest = global("PIPESTATUS")), 0, 10);

	/* Set this before parsing arguments */
	Flag(FPRIVILEGED) = (kshuid != ksheuid || kshgid != kshegid) ? 2 : 0;

	/* this to note if monitor is set on command line (see below) */
#ifndef MKSH_UNEMPLOYED
	Flag(FMONITOR) = 127;
#endif
	/* this to note if utf-8 mode is set on command line (see below) */
	UTFMODE = 2;

	if (!Flag(FAS_BUILTIN)) {
		argi = parse_args(argv, OF_CMDLINE, NULL);
		if (argi < 0)
			return (1);
	}

	/* process this later only, default to off (hysterical raisins) */
	utf_flag = UTFMODE;
	UTFMODE = 0;

	if (Flag(FAS_BUILTIN)) {
		/* auto-detect from environment variables, always */
		utf_flag = 3;
	} else if (Flag(FCOMMAND)) {
		s = pushs(SSTRINGCMDLINE, ATEMP);
		if (!(s->start = s->str = argv[argi++]))
			errorf(Tf_optfoo, "", "", 'c', Treq_arg);
		while (*s->str) {
			if (ctype(*s->str, C_QUOTE))
				break;
			s->str++;
		}
		if (!*s->str)
			s->flags |= SF_MAYEXEC;
		s->str = s->start;
#ifdef MKSH_MIDNIGHTBSD01ASH_COMPAT
		/* compatibility to MidnightBSD 0.1 /bin/sh (kludge) */
		if (Flag(FSH) && argv[argi] && !strcmp(argv[argi], "--"))
			++argi;
#endif
		if (argv[argi])
			kshname = argv[argi++];
	} else if (argi < argc && !Flag(FSTDIN)) {
		s = pushs(SFILE, ATEMP);
#ifdef __OS2__
		/*
		 * A bug in OS/2 extproc (like shebang) handling makes
		 * it not pass the full pathname of a script, so we need
		 * to search for it. This changes the behaviour of a
		 * simple "mksh foo", but can't be helped.
		 */
		s->file = argv[argi++];
		if (search_access(s->file, X_OK) != 0)
			s->file = search_path(s->file, path, X_OK, NULL);
		if (!s->file || !*s->file)
			s->file = argv[argi - 1];
#else
		s->file = argv[argi++];
#endif
		s->u.shf = shf_open(s->file, O_RDONLY, 0,
		    SHF_MAPHI | SHF_CLEXEC);
		if (s->u.shf == NULL) {
			shl_stdout_ok = false;
			warningf(true, Tf_sD_s, s->file, cstrerror(errno));
			/* mandated by SUSv4 */
			exstat = 127;
			unwind(LERROR);
		}
		kshname = s->file;
	} else {
		Flag(FSTDIN) = 1;
		s = pushs(SSTDIN, ATEMP);
		s->file = "<stdin>";
		s->u.shf = shf_fdopen(0, SHF_RD | can_seek(0),
		    NULL);
		if (isatty(0) && isatty(2)) {
			Flag(FTALKING) = Flag(FTALKING_I) = 1;
			/* The following only if isatty(0) */
			s->flags |= SF_TTY;
			s->u.shf->flags |= SHF_INTERRUPT;
			s->file = NULL;
		}
	}

	/* this bizarreness is mandated by POSIX */
	if (fstat(0, &s_stdin) >= 0 && S_ISCHR(s_stdin.st_mode) &&
	    Flag(FTALKING))
		reset_nonblock(0);

	/* initialise job control */
	j_init();
	/* do this after j_init() which calls tty_init_state() */
	if (Flag(FTALKING)) {
		if (utf_flag == 2) {
#ifndef MKSH_ASSUME_UTF8
			/* auto-detect from locale or environment */
			utf_flag = 4;
#else /* this may not be an #elif */
#if MKSH_ASSUME_UTF8
			utf_flag = 1;
#else
			/* always disable UTF-8 (for interactive) */
			utf_flag = 0;
#endif
#endif
		}
#ifndef MKSH_NO_CMDLINE_EDITING
		x_init();
#endif
	}

#ifdef SIGWINCH
	sigtraps[SIGWINCH].flags |= TF_SHELL_USES;
	setsig(&sigtraps[SIGWINCH], x_sigwinch,
	    SS_RESTORE_ORIG|SS_FORCE|SS_SHTRAP);
#endif

	l = e->loc;
	if (Flag(FAS_BUILTIN)) {
		l->argc = argc;
		l->argv = argv;
		l->argv[0] = ccp;
	} else {
		l->argc = argc - argi;
		/*
		 * allocate a new array because otherwise, when we modify
		 * it in-place, ps(1) output changes; the meaning of argc
		 * here is slightly different as it excludes kshname, and
		 * we add a trailing NULL sentinel as well
		 */
		l->argv = alloc2(l->argc + 2, sizeof(void *), APERM);
		l->argv[0] = kshname;
		memcpy(&l->argv[1], &argv[argi], l->argc * sizeof(void *));
		l->argv[l->argc + 1] = NULL;
		getopts_reset(1);
	}

	/* divine the initial state of the utf8-mode Flag */
	ccp = null;
	switch (utf_flag) {

	/* auto-detect from locale or environment */
	case 4:
#if HAVE_SETLOCALE_CTYPE
		ccp = setlocale(LC_CTYPE, "");
#if HAVE_LANGINFO_CODESET
		if (!isuc(ccp))
			ccp = nl_langinfo(CODESET);
#endif
		if (!isuc(ccp))
			ccp = null;
#endif
		/* FALLTHROUGH */

	/* auto-detect from environment */
	case 3:
		/* these were imported from environ earlier */
		if (ccp == null)
			ccp = str_val(global("LC_ALL"));
		if (ccp == null)
			ccp = str_val(global("LC_CTYPE"));
		if (ccp == null)
			ccp = str_val(global("LANG"));
		UTFMODE = isuc(ccp);
		break;

	/* not set on command line, not FTALKING */
	case 2:
	/* unknown values */
	default:
		utf_flag = 0;
		/* FALLTHROUGH */

	/* known values */
	case 1:
	case 0:
		UTFMODE = utf_flag;
		break;
	}

	/* Disable during .profile/ENV reading */
	restricted_shell = Flag(FRESTRICTED);
	Flag(FRESTRICTED) = 0;
	errexit = Flag(FERREXIT);
	Flag(FERREXIT) = 0;

	/*
	 * Do this before profile/$ENV so that if it causes problems in them,
	 * user will know why things broke.
	 */
	if (!current_wd[0] && Flag(FTALKING))
		warningf(false, "can't determine current directory");

	if (Flag(FLOGIN))
		include(MKSH_SYSTEM_PROFILE, 0, NULL, true);
	if (!Flag(FPRIVILEGED)) {
		if (Flag(FLOGIN))
			include(substitute("$HOME/.profile", 0), 0, NULL, true);
		if (Flag(FTALKING)) {
			cp = substitute("${ENV:-" MKSHRC_PATH "}", DOTILDE);
			if (cp[0] != '\0')
				include(cp, 0, NULL, true);
		}
	} else {
		include(MKSH_SUID_PROFILE, 0, NULL, true);
		/* turn off -p if not set explicitly */
		if (Flag(FPRIVILEGED) != 1)
			change_flag(FPRIVILEGED, OF_INTERNAL, false);
	}

	if (restricted_shell) {
		c_builtin(restr_com);
		/* After typeset command... */
		Flag(FRESTRICTED) = 1;
	}
	Flag(FERREXIT) = errexit;

	if (Flag(FTALKING) && s)
		hist_init(s);
	else
		/* set after ENV */
		Flag(FTRACKALL) = 1;

	alarm_init();

	*sp = s;
	*lp = l;
	return (0);
}
Esempio n. 18
0
int
main(int argc, char *argv[])
{
	register int i;
	int argi;
	Source *s;
	struct block *l;
	int restricted, errexit;
	char **wp;
	struct env env;
	pid_t ppid;

#ifdef MEM_DEBUG
	chmem_set_defaults("ct", 1);
	/* chmem_push("+c", 1); */
#endif /* MEM_DEBUG */

#ifdef OS2
	setmode (0, O_BINARY);
	setmode (1, O_TEXT);
#endif

	/* make sure argv[] is sane */
	if (!*argv) {
		static const char	*empty_argv[] = {
					    "pdksh", (char *) 0
					};

		argv = (char **)__UNCONST(empty_argv);
		argc = 1;
	}
	kshname = *argv;

	ainit(&aperm);		/* initialize permanent Area */

	/* set up base environment */
	memset(&env, 0, sizeof(env));
	env.type = E_NONE;
	ainit(&env.area);
	e = &env;
	newblock();		/* set up global l->vars and l->funs */

	/* Do this first so output routines (eg, errorf, shellf) can work */
	initio();

	initvar();

	initctypes();

	inittraps();

#ifdef KSH
	coproc_init();
#endif /* KSH */

	/* set up variable and command dictionaries */
	tinit(&taliases, APERM, 0);
	tinit(&aliases, APERM, 0);
	tinit(&homedirs, APERM, 0);

	/* define shell keywords */
	initkeywords();

	/* define built-in commands */
	tinit(&builtins, APERM, 64); /* must be 2^n (currently 40 builtins) */
	for (i = 0; shbuiltins[i].name != NULL; i++)
		builtin(shbuiltins[i].name, shbuiltins[i].func);
	for (i = 0; kshbuiltins[i].name != NULL; i++)
		builtin(kshbuiltins[i].name, kshbuiltins[i].func);

	init_histvec();

	def_path = DEFAULT__PATH;
#if defined(HAVE_CONFSTR) && defined(_CS_PATH)
	{
		size_t len = confstr(_CS_PATH, (char *) 0, 0);
		char *new;

		if (len > 0) {
			confstr(_CS_PATH, new = alloc(len + 1, APERM), len + 1);
			def_path = new;
		}
	}