⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ash.c

📁 手机嵌入式Linux下可用的busybox源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	{EINTR, ALL},	{EACCES, ALL},	{EIO, ALL},	{ENOENT, E_OPEN},	{ENOENT, E_CREAT},	{ENOENT, E_EXEC},	{ENOTDIR, E_OPEN},	{ENOTDIR, E_CREAT},	{ENOTDIR, E_EXEC},	{EISDIR, ALL},	{EEXIST, E_CREAT},#ifdef EMFILE	{EMFILE, ALL},#endif	{ENFILE, ALL},	{ENOSPC, ALL},#ifdef EDQUOT	{EDQUOT, ALL},#endif#ifdef ENOSR	{ENOSR, ALL},#endif	{ENXIO, ALL},	{EROFS, ALL},	{ETXTBSY, ALL},#ifdef EAGAIN	{EAGAIN, E_EXEC},#endif	{ENOMEM, ALL},#ifdef ENOLINK	{ENOLINK, ALL},#endif#ifdef EMULTIHOP	{EMULTIHOP, ALL},#endif#ifdef ECOMM	{ECOMM, ALL},#endif#ifdef ESTALE	{ESTALE, ALL},#endif#ifdef ETIMEDOUT	{ETIMEDOUT, ALL},#endif#ifdef ELOOP	{ELOOP, ALL},#endif	{E2BIG, E_EXEC},#ifdef ELIBACC	{ELIBACC, E_EXEC},#endif};#define ERRNAME_SIZE (sizeof(errormsg)/sizeof(struct errname))/* * Return a string describing an error.  The returned string may be a * pointer to a static buffer that will be overwritten on the next call. * Action describes the operation that got the error. */static const char *errmsg(int e, int action){	struct errname const *ep;	static char buf[12];	for (ep = errormsg; ep < errormsg + ERRNAME_SIZE; ep++) {		if (ep->errcode == e && (ep->action & action) != 0)			return strerror(e);	}	snprintf(buf, sizeof buf, "error %d", e);	return buf;}#ifdef CONFIG_ASH_OPTIMIZE_FOR_SIZEstatic void __inton(){	if (--suppressint == 0 && intpending) {		onint();	}}static void forceinton(void){	suppressint = 0;	if (intpending)		onint();}#endif/* flags in argument to evaltree */#define EV_EXIT 01		/* exit after evaluating tree */#define EV_TESTED 02	/* exit status is checked; ignore -e flag */#define EV_BACKCMD 04	/* command executing within back quotes */static int evalskip;	/* set if we are skipping commands */static int skipcount;	/* number of levels to skip */static int loopnest;	/* current loop nesting level */static int funcnest;	/* depth of function calls */static struct strlist *cmdenviron;	/* environment for builtin command */static int exitstatus;	/* exit status of last command */static int oexitstatus;	/* saved exit status */static void evalsubshell(const union node *, int);static void expredir(union node *);static void prehash(union node *);static void eprintlist(struct strlist *);static union node *parsecmd(int);/* * Called to reset things after an exception. *//* * The eval commmand. */static void evalstring(char *, int);static int evalcmd(int argc, char **argv){	char *p;	char *concat;	char **ap;	if (argc > 1) {		p = argv[1];		if (argc > 2) {			STARTSTACKSTR(concat);			ap = argv + 2;			for (;;) {				while (*p)					STPUTC(*p++, concat);				if ((p = *ap++) == NULL)					break;				STPUTC(' ', concat);			}			STPUTC('\0', concat);			p = grabstackstr(concat);		}		evalstring(p, EV_TESTED);	}	return exitstatus;}/* * Execute a command or commands contained in a string. */static void evaltree(union node *, int);static void setinputstring(char *);static void popfile(void);static void setstackmark(struct stackmark *mark);static void popstackmark(struct stackmark *mark);static void evalstring(char *s, int flag){	union node *n;	struct stackmark smark;	setstackmark(&smark);	setinputstring(s);	while ((n = parsecmd(0)) != NEOF) {		evaltree(n, flag);		popstackmark(&smark);	}	popfile();	popstackmark(&smark);}static struct builtincmd *find_builtin(const char *);static void expandarg(union node *, struct arglist *, int);static void calcsize(const union node *);static union node *copynode(const union node *);/* * Make a copy of a parse tree. */static int funcblocksize;	/* size of structures in function */static int funcstringsize;	/* size of strings in node */static pointer funcblock;	/* block to allocate function from */static char *funcstring;	/* block to allocate strings from */static inline union node *copyfunc(union node *n){	if (n == NULL)		return NULL;	funcblocksize = 0;	funcstringsize = 0;	calcsize(n);	funcblock = xmalloc(funcblocksize + funcstringsize);	funcstring = (char *) funcblock + funcblocksize;	return copynode(n);}/* * Add a new command entry, replacing any existing command entry for * the same name. */static inline void addcmdentry(char *name, struct cmdentry *entry){	struct tblentry *cmdp;	INTOFF;	cmdp = cmdlookup(name, 1);	if (cmdp->cmdtype == CMDFUNCTION) {		free(cmdp->param.func);	}	cmdp->cmdtype = entry->cmdtype;	cmdp->param = entry->u;	INTON;}static inline void evalloop(const union node *n, int flags){	int status;	loopnest++;	status = 0;	flags &= EV_TESTED;	for (;;) {		evaltree(n->nbinary.ch1, EV_TESTED);		if (evalskip) {		  skipping:if (evalskip == SKIPCONT && --skipcount <= 0) {				evalskip = 0;				continue;			}			if (evalskip == SKIPBREAK && --skipcount <= 0)				evalskip = 0;			break;		}		if (n->type == NWHILE) {			if (exitstatus != 0)				break;		} else {			if (exitstatus == 0)				break;		}		evaltree(n->nbinary.ch2, flags);		status = exitstatus;		if (evalskip)			goto skipping;	}	loopnest--;	exitstatus = status;}static void evalfor(const union node *n, int flags){	struct arglist arglist;	union node *argp;	struct strlist *sp;	struct stackmark smark;	setstackmark(&smark);	arglist.lastp = &arglist.list;	for (argp = n->nfor.args; argp; argp = argp->narg.next) {		oexitstatus = exitstatus;		expandarg(argp, &arglist, EXP_FULL | EXP_TILDE | EXP_RECORD);		if (evalskip)			goto out;	}	*arglist.lastp = NULL;	exitstatus = 0;	loopnest++;	flags &= EV_TESTED;	for (sp = arglist.list; sp; sp = sp->next) {		setvar(n->nfor.var, sp->text, 0);		evaltree(n->nfor.body, flags);		if (evalskip) {			if (evalskip == SKIPCONT && --skipcount <= 0) {				evalskip = 0;				continue;			}			if (evalskip == SKIPBREAK && --skipcount <= 0)				evalskip = 0;			break;		}	}	loopnest--;  out:	popstackmark(&smark);}static inline void evalcase(const union node *n, int flags){	union node *cp;	union node *patp;	struct arglist arglist;	struct stackmark smark;	setstackmark(&smark);	arglist.lastp = &arglist.list;	oexitstatus = exitstatus;	expandarg(n->ncase.expr, &arglist, EXP_TILDE);	for (cp = n->ncase.cases; cp && evalskip == 0; cp = cp->nclist.next) {		for (patp = cp->nclist.pattern; patp; patp = patp->narg.next) {			if (casematch(patp, arglist.list->text)) {				if (evalskip == 0) {					evaltree(cp->nclist.body, flags);				}				goto out;			}		}	}  out:	popstackmark(&smark);}/* * Evaluate a pipeline.  All the processes in the pipeline are children * of the process creating the pipeline.  (This differs from some versions * of the shell, which make the last process in a pipeline the parent * of all the rest.) */static inline void evalpipe(union node *n, int flags){	struct job *jp;	struct nodelist *lp;	int pipelen;	int prevfd;	int pip[2];	TRACE(("evalpipe(0x%lx) called\n", (long) n));	pipelen = 0;	for (lp = n->npipe.cmdlist; lp; lp = lp->next)		pipelen++;	flags |= EV_EXIT;	INTOFF;	jp = makejob(n, pipelen);	prevfd = -1;	for (lp = n->npipe.cmdlist; lp; lp = lp->next) {		prehash(lp->n);		pip[1] = -1;		if (lp->next) {			if (pipe(pip) < 0) {				close(prevfd);				error("Pipe call failed");			}		}		if (forkshell(jp, lp->n, n->npipe.backgnd) == 0) {			INTON;			if (pip[1] >= 0) {				close(pip[0]);			}			if (prevfd > 0) {				dup2(prevfd, 0);				close(prevfd);			}			if (pip[1] > 1) {				dup2(pip[1], 1);				close(pip[1]);			}			evaltree(lp->n, flags);		}		if (prevfd >= 0)			close(prevfd);		prevfd = pip[0];		close(pip[1]);	}	if (n->npipe.backgnd == 0) {		exitstatus = waitforjob(jp);		TRACE(("evalpipe:  job done exit status %d\n", exitstatus));	}	INTON;}static void find_command(const char *, struct cmdentry *, int, const char *);static int isassignment(const char *word){	if (!is_name(*word)) {		return 0;	}	do {		word++;	} while (is_in_name(*word));	return *word == '=';}static void evalcommand(union node *cmd, int flags){	struct stackmark smark;	union node *argp;	struct arglist arglist;	struct arglist varlist;	char **argv;	int argc;	char **envp;	struct strlist *sp;	int mode;	struct cmdentry cmdentry;	struct job *jp;	char *volatile savecmdname;	volatile struct shparam saveparam;	struct localvar *volatile savelocalvars;	volatile int e;	char *lastarg;	const char *path;	int spclbltin;	struct jmploc *volatile savehandler;	struct jmploc jmploc;#if __GNUC__	/* Avoid longjmp clobbering */	(void) &argv;	(void) &argc;	(void) &lastarg;	(void) &flags;	(void) &spclbltin;#endif	/* First expand the arguments. */	TRACE(("evalcommand(0x%lx, %d) called\n", (long) cmd, flags));	setstackmark(&smark);	arglist.lastp = &arglist.list;	varlist.lastp = &varlist.list;	arglist.list = 0;	oexitstatus = exitstatus;	exitstatus = 0;	path = pathval();	for (argp = cmd->ncmd.assign; argp; argp = argp->narg.next) {		expandarg(argp, &varlist, EXP_VARTILDE);	}	for (argp = cmd->ncmd.args; argp && !arglist.list; argp = argp->narg.next) {		expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);	}	if (argp) {		struct builtincmd *bcmd;		int pseudovarflag;		bcmd = find_builtin(arglist.list->text);		pseudovarflag = bcmd && IS_BUILTIN_ASSIGN(bcmd);		for (; argp; argp = argp->narg.next) {			if (pseudovarflag && isassignment(argp->narg.text)) {				expandarg(argp, &arglist, EXP_VARTILDE);				continue;			}			expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);		}	}	*arglist.lastp = NULL;	*varlist.lastp = NULL;	expredir(cmd->ncmd.redirect);	argc = 0;	for (sp = arglist.list; sp; sp = sp->next)		argc++;	argv = stalloc(sizeof(char *) * (argc + 1));	for (sp = arglist.list; sp; sp = sp->next) {		TRACE(("evalcommand arg: %s\n", sp->text));		*argv++ = sp->text;	}	*argv = NULL;	lastarg = NULL;	if (iflag && funcnest == 0 && argc > 0)		lastarg = argv[-1];	argv -= argc;	/* Print the command if xflag is set. */	if (xflag) {		out2c('+');		eprintlist(varlist.list);		eprintlist(arglist.list);		out2c('\n');	}	/* Now locate the command. */	if (argc == 0) {		cmdentry.cmdtype = CMDBUILTIN;		cmdentry.u.cmd = BLTINCMD;		spclbltin = 1;	} else {		const char *oldpath;		int findflag = DO_ERR;		int oldfindflag;		/*		 * Modify the command lookup path, if a PATH= assignment		 * is present		 */		for (sp = varlist.list; sp; sp = sp->next)			if (varequal(sp->text, defpathvar)) {				path = sp->text + 5;				findflag |= DO_BRUTE;			}		oldpath = path;		oldfindflag = findflag;		spclbltin = -1;		for (;;) {			find_command(argv[0], &cmdentry, findflag, path);			if (cmdentry.cmdtype == CMD

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -