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

📄 ash.c

📁 手机嵌入式Linux下可用的busybox源码
💻 C
📖 第 1 页 / 共 5 页
字号:
static void expari(int);#endifstatic char *trap[NSIG];	/* trap handler commands */static char sigmode[NSIG - 1];	/* current value of signal */static char gotsig[NSIG - 1];	/* indicates specified signal received */static int pendingsigs;	/* indicates some signal received *//* * This file was generated by the mkbuiltins program. */#ifdef BB_FEATURE_ASH_JOB_CONTROLstatic int bgcmd(int, char **);static int fgcmd(int, char **);static int killcmd(int, char **);#endifstatic int bltincmd(int, char **);static int cdcmd(int, char **);static int breakcmd(int, char **);#ifdef CONFIG_ASH_CMDCMDstatic int commandcmd(int, char **);#endifstatic int dotcmd(int, char **);static int evalcmd(int, char **);static int execcmd(int, char **);static int exitcmd(int, char **);static int exportcmd(int, char **);static int histcmd(int, char **);static int hashcmd(int, char **);static int helpcmd(int, char **);static int jobscmd(int, char **);static int localcmd(int, char **);static int pwdcmd(int, char **);static int readcmd(int, char **);static int returncmd(int, char **);static int setcmd(int, char **);static int setvarcmd(int, char **);static int shiftcmd(int, char **);static int trapcmd(int, char **);static int umaskcmd(int, char **);#ifdef CONFIG_ASH_ALIASstatic int aliascmd(int, char **);static int unaliascmd(int, char **);#endifstatic int unsetcmd(int, char **);static int waitcmd(int, char **);static int ulimitcmd(int, char **);static int timescmd(int, char **);#ifdef CONFIG_ASH_MATH_SUPPORTstatic int letcmd(int, char **);#endifstatic int typecmd(int, char **);#ifdef CONFIG_ASH_GETOPTSstatic int getoptscmd(int, char **);#endif#ifndef BB_TRUE_FALSEstatic int true_main(int, char **);static int false_main(int, char **);#endifstatic void setpwd(const char *, int);#define BUILTIN_NOSPEC  "0"#define BUILTIN_SPECIAL "1"#define BUILTIN_REGULAR "2"#define BUILTIN_ASSIGN  "4"#define BUILTIN_SPEC_ASSG  "5"#define BUILTIN_REG_ASSG   "6"#define IS_BUILTIN_SPECIAL(builtincmd) ((builtincmd)->name[0] & 1)#define IS_BUILTIN_REGULAR(builtincmd) ((builtincmd)->name[0] & 2)#define IS_BUILTIN_ASSIGN(builtincmd) ((builtincmd)->name[0] & 4)struct builtincmd {	const char *name;	int (*const builtinfunc) (int, char **);	//unsigned flags;};/* It is CRUCIAL that this listing be kept in ascii order, otherwise * the binary search in find_builtin() will stop working. If you value * your kneecaps, you'll be sure to *make sure* that any changes made * to this array result in the listing remaining in ascii order. You * have been warned. */static const struct builtincmd builtincmds[] = {	{BUILTIN_SPECIAL ".", dotcmd},	/* first, see declare DOTCMD */	{BUILTIN_SPECIAL ":", true_main},#ifdef CONFIG_ASH_ALIAS	{BUILTIN_REG_ASSG "alias", aliascmd},#endif#ifdef BB_FEATURE_ASH_JOB_CONTROL	{BUILTIN_REGULAR "bg", bgcmd},#endif	{BUILTIN_SPECIAL "break", breakcmd},	{BUILTIN_SPECIAL "builtin", bltincmd},	{BUILTIN_REGULAR "cd", cdcmd},	{BUILTIN_NOSPEC "chdir", cdcmd},#ifdef CONFIG_ASH_CMDCMD	{BUILTIN_REGULAR "command", commandcmd},#endif	{BUILTIN_SPECIAL "continue", breakcmd},	{BUILTIN_SPECIAL "eval", evalcmd},	{BUILTIN_SPECIAL "exec", execcmd},	{BUILTIN_SPECIAL "exit", exitcmd},	{BUILTIN_SPEC_ASSG "export", exportcmd},	{BUILTIN_REGULAR "false", false_main},	{BUILTIN_REGULAR "fc", histcmd},#ifdef BB_FEATURE_ASH_JOB_CONTROL	{BUILTIN_REGULAR "fg", fgcmd},#endif#ifdef CONFIG_ASH_GETOPTS	{BUILTIN_REGULAR "getopts", getoptscmd},#endif	{BUILTIN_NOSPEC "hash", hashcmd},	{BUILTIN_NOSPEC "help", helpcmd},	{BUILTIN_REGULAR "jobs", jobscmd},#ifdef BB_FEATURE_ASH_JOB_CONTROL	{BUILTIN_REGULAR "kill", killcmd},#endif#ifdef CONFIG_ASH_MATH_SUPPORT	{BUILTIN_REGULAR "let", letcmd},#endif	{BUILTIN_ASSIGN "local", localcmd},	{BUILTIN_NOSPEC "pwd", pwdcmd},	{BUILTIN_REGULAR "read", readcmd},	{BUILTIN_SPEC_ASSG "readonly", exportcmd},	{BUILTIN_SPECIAL "return", returncmd},	{BUILTIN_SPECIAL "set", setcmd},	{BUILTIN_NOSPEC "setvar", setvarcmd},	{BUILTIN_SPECIAL "shift", shiftcmd},	{BUILTIN_SPECIAL "times", timescmd},	{BUILTIN_SPECIAL "trap", trapcmd},	{BUILTIN_REGULAR "true", true_main},	{BUILTIN_NOSPEC "type", typecmd},	{BUILTIN_NOSPEC "ulimit", ulimitcmd},	{BUILTIN_REGULAR "umask", umaskcmd},#ifdef CONFIG_ASH_ALIAS	{BUILTIN_REGULAR "unalias", unaliascmd},#endif	{BUILTIN_SPECIAL "unset", unsetcmd},	{BUILTIN_REGULAR "wait", waitcmd},};#define NUMBUILTINS  (sizeof (builtincmds) / sizeof (struct builtincmd) )#define DOTCMD &builtincmds[0]static struct builtincmd *BLTINCMD;static struct builtincmd *EXECCMD;static struct builtincmd *EVALCMD;/* states */#define JOBSTOPPED 1	/* all procs are stopped */#define JOBDONE 2		/* all procs are completed *//* * A job structure contains information about a job.  A job is either a * single process or a set of processes contained in a pipeline.  In the * latter case, pidlist will be non-NULL, and will point to a -1 terminated * array of pids. */struct procstat {	pid_t pid;			/* process id */	int status;			/* status flags (defined above) */	char *cmd;			/* text of command being run */};static int job_warning;	/* user was warned about stopped jobs */#ifdef BB_FEATURE_ASH_JOB_CONTROLstatic void setjobctl(int enable);#else#define setjobctl(on)	/* do nothing */#endifstruct job {	struct procstat ps0;	/* status of process */	struct procstat *ps;	/* status or processes when more than one */	short nprocs;		/* number of processes */	short pgrp;			/* process group of this job */	char state;			/* true if job is finished */	char used;			/* true if this entry is in used */	char changed;		/* true if status has changed */#ifdef BB_FEATURE_ASH_JOB_CONTROL	char jobctl;		/* job running under job control */#endif};static struct job *jobtab;	/* array of jobs */static int njobs;		/* size of array */static int backgndpid = -1;	/* pid of last background process */#ifdef BB_FEATURE_ASH_JOB_CONTROLstatic int initialpgrp;	/* pgrp of shell on invocation */static int curjob;		/* current job */static int jobctl;#endifstatic struct job *makejob(const union node *, int);static int forkshell(struct job *, const union node *, int);static int waitforjob(struct job *);static int docd(char *, int);static void getpwd(void);static char *padvance(const char **, const char *);static char nullstr[1];	/* zero length string */static char *curdir = nullstr;	/* current working directory */static int cdcmd(int argc, char **argv){	const char *dest;	const char *path;	char *p;	struct stat statb;	int print = 0;	nextopt(nullstr);	if ((dest = *argptr) == NULL && (dest = bltinlookup("HOME")) == NULL)		error("HOME not set");	if (*dest == '\0')		dest = ".";	if (dest[0] == '-' && dest[1] == '\0') {		dest = bltinlookup("OLDPWD");		if (!dest || !*dest) {			dest = curdir;		}		print = 1;		if (dest)			print = 1;		else			dest = ".";	}	if (*dest == '/' || (path = bltinlookup("CDPATH")) == NULL)		path = nullstr;	while ((p = padvance(&path, dest)) != NULL) {		if (stat(p, &statb) >= 0 && S_ISDIR(statb.st_mode)) {			if (!print) {				/*				 * XXX - rethink				 */				if (p[0] == '.' && p[1] == '/' && p[2] != '\0')					p += 2;				print = strcmp(p, dest);			}			if (docd(p, print) >= 0)				return 0;		}	}	error("can't cd to %s", dest);	/* NOTREACHED */}/* * Update curdir (the name of the current directory) in response to a * cd command.  We also call hashcd to let the routines in exec.c know * that the current directory has changed. */static void hashcd(void);static inline void updatepwd(const char *dir){	hashcd();			/* update command hash table */	/*	 * If our argument is NULL, we don't know the current directory	 */	if (dir == NULL || curdir == nullstr) {		setpwd(0, 1);	} else {		setpwd(dir, 1);	}}/* * Actually do the chdir.  In an interactive shell, print the * directory name if "print" is nonzero. */static int docd(char *dest, int print){	TRACE(("docd(\"%s\", %d) called\n", dest, print));	INTOFF;	if (chdir(dest) < 0) {		INTON;		return -1;	}	updatepwd(dest);	INTON;	if (print && iflag)		puts(curdir);	return 0;}static int pwdcmd(int argc, char **argv){	puts(curdir);	return 0;}/* Ask system the current directory */static void getpwd(void){	curdir = xgetcwd(0);	if (curdir == 0)		curdir = nullstr;}static void setpwd(const char *val, int setold){	char *cated = NULL;	if (setold) {		setvar("OLDPWD", curdir, VEXPORT);	}	INTOFF;	if (curdir != nullstr) {		if (val != NULL && *val != '/')			val = cated = concat_path_file(curdir, val);		free(curdir);	}	if (!val)		getpwd();	else		curdir = simplify_path(val);	free(cated);	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 */#define EXREDIR 4		/* redirection error */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 void exraise(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 void onint(void){	sigset_t mysigset;	if (suppressint) {		intpending++;		return;	}	intpending = 0;	sigemptyset(&mysigset);	sigprocmask(SIG_SETMASK, &mysigset, NULL);	if (!(rootshell && iflag)) {		signal(SIGINT, SIG_DFL);		raise(SIGINT);	}	exraise(EXINT);	/* 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 void exverror(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 void exerror(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 */	short 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[] = {

⌨️ 快捷键说明

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