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

📄 ash.c

📁 为samsung2410 ARM移植的busybox工具包
💻 C
📖 第 1 页 / 共 5 页
字号:
 */static voidgetpwd(void){	curdir = xgetcwd(0);	if(curdir==0)		curdir = nullstr;}static voidsetpwd(const char *val, int setold){	if (setold) {		setvar("OLDPWD", curdir, VEXPORT);	}	INTOFF;	if (curdir != nullstr) {		free(curdir);		curdir = nullstr;	}	if (!val) {		getpwd();	} else {		curdir = savestr(val);	}	INTON;	setvar("PWD", curdir, VEXPORT);}/* * Errors and exceptions. *//* * Code to handle exceptions in C. *//* * We enclose jmp_buf in a structure so that we can declare pointers to * jump locations.  The global variable handler contains the location to * jump to when an exception occurs, and the global variable exception * contains a code identifying the exeception.  To implement nested * exception handlers, the user should save the value of handler on entry * to an inner scope, set handler to point to a jmploc structure for the * inner scope, and restore handler on exit from the scope. */struct jmploc {	jmp_buf loc;};/* exceptions */#define EXINT 0         /* SIGINT received */#define EXERROR 1       /* a generic error */#define EXSHELLPROC 2   /* execute a shell procedure */#define EXEXEC 3        /* command execution failed */static struct jmploc *handler;static int exception;static void exverror (int, const char *, va_list)    __attribute__((__noreturn__));/* * Called to raise an exception.  Since C doesn't include exceptions, we * just do a longjmp to the exception handler.  The type of exception is * stored in the global variable "exception". */static void exraise (int) __attribute__((__noreturn__));static voidexraise(int e){#ifdef DEBUG	if (handler == NULL)		abort();#endif	flushall();	exception = e;	longjmp(handler->loc, 1);}/* * Called from trap.c when a SIGINT is received.  (If the user specifies * that SIGINT is to be trapped or ignored using the trap builtin, then * this routine is not called.)  Suppressint is nonzero when interrupts * are held using the INTOFF macro.  The call to _exit is necessary because * there is a short period after a fork before the signal handlers are * set to the appropriate value for the child.  (The test for iflag is * just defensive programming.) */static voidonint(void) {	sigset_t mysigset;	if (suppressint) {		intpending++;		return;	}	intpending = 0;	sigemptyset(&mysigset);	sigprocmask(SIG_SETMASK, &mysigset, NULL);	if (rootshell && iflag)		exraise(EXINT);	else {		signal(SIGINT, SIG_DFL);		raise(SIGINT);	}	/* NOTREACHED */}static char *commandname;       /* currently executing command *//* * Exverror is called to raise the error exception.  If the first argument * is not NULL then error prints an error message using printf style * formatting.  It then raises the error exception. */static voidexverror(int cond, const char *msg, va_list ap){	CLEAR_PENDING_INT;	INTOFF;#ifdef DEBUG	if (msg)		TRACE(("exverror(%d, \"%s\") pid=%d\n", cond, msg, getpid()));	else		TRACE(("exverror(%d, NULL) pid=%d\n", cond, getpid()));#endif	if (msg) {		if (commandname)			out2fmt("%s: ", commandname);		vfprintf(stderr, msg, ap);		out2c('\n');	}	exraise(cond);	/* NOTREACHED */}static void error(const char *msg, ...){	va_list ap;	va_start(ap, msg);	exverror(EXERROR, msg, ap);	/* NOTREACHED */	va_end(ap);}static voidexerror(int cond, const char *msg, ...){	va_list ap;	va_start(ap, msg);	exverror(cond, msg, ap);	/* NOTREACHED */	va_end(ap);}/* * Table of error messages. */struct errname {	short errcode;          /* error number */	char  action;           /* operation which encountered the error */};/* * Types of operations (passed to the errmsg routine). */#define E_OPEN 01       /* opening a file */#define E_CREAT 02      /* creating a file */#define E_EXEC 04       /* executing a program */#define ALL (E_OPEN|E_CREAT|E_EXEC)static const struct errname errormsg[] = {	{ 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 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 intevalcmd(argc, argv)	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 voidevalstring(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 = ckmalloc(funcblocksize + funcstringsize);	funcstring = (char *) funcblock + funcblocksize;	return copynode(n);}/* * Free a parse tree. */static voidfreefunc(union node *n){	if (n)		ckfree(n);}/* * Add a new command entry, replacing any existing command entry for * the same name. */static inline voidaddcmdentry(char *name, struct cmdentry *entry){	struct tblentry *cmdp;	INTOFF;	cmdp = cmdlookup(name, 1);	if (cmdp->cmdtype == CMDFUNCTION) {		freefunc(cmdp->param.func);	}	cmdp->cmdtype = entry->cmdtype;	cmdp->param = entry->u;	INTON;}static inline voidevalloop(const union node *n, int flags){	int status;	loopnest++;	status = 0;	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 & EV_TESTED);		status = exitstatus;		if (evalskip)			goto skipping;	}	loopnest--;	exitstatus = status;}static voidevalfor(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++;	for (sp = arglist.list ; sp ; sp = sp->next) {		setvar(n->nfor.var, sp->text, 0);		evaltree(n->nfor.body, flags & EV_TESTED);		if (evalskip) {			if (evalskip == SKIPCONT && --skipcount <= 0) {				evalskip = 0;				continue;			}			if (evalskip == SKIPBREAK && --skipcount <= 0)				evalskip = 0;			break;		}	}	loopnest--;out:	popstackmark(&smark);}static inline voidevalcase(const union node *n, int flags){	union node *cp;	union node *patp;	struct arglist arglist;	struct stackmark smark;	setstac

⌨️ 快捷键说明

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