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

📄 msh.c

📁 shell-HHARM9200.rar 华恒 AT91rm9200 中Busybox shell的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* vi: set sw=4 ts=4: *//* * Minix shell port for busybox * * This version of the Minix shell was adapted for use in busybox * by Erik Andersen <andersen@codepoet.org> * * - backtick expansion did not work properly *   Jonas Holmberg <jonas.holmberg@axis.com> *   Robert Schwebel <r.schwebel@pengutronix.de> *   Erik Andersen <andersen@codepoet.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Original copyright notice is retained at the end of this file. */#include <ctype.h>#include <dirent.h>#include <errno.h>#include <fcntl.h>#include <limits.h>#include <setjmp.h>#include <signal.h>#include <stddef.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#include <unistd.h>#include <sys/stat.h>#include <sys/times.h>#include <sys/types.h>#include <sys/wait.h>#include "cmdedit.h"#include "busybox.h"/* -------- sh.h -------- *//* * shell */#define	LINELIM	2100#define	NPUSH	8	/* limit to input nesting */#undef NOFILE#define	NOFILE	20	/* Number of open files */#define	NUFILE	10	/* Number of user-accessible files */#define	FDBASE	10	/* First file usable by Shell *//* * values returned by wait */#define	WAITSIG(s) ((s)&0177)#define	WAITVAL(s) (((s)>>8)&0377)#define	WAITCORE(s) (((s)&0200)!=0)/* * library and system defintions */typedef void xint;	/* base type of jmp_buf, for not broken compilers *//* * shell components */#define	QUOTE	0200#define	NOBLOCK	((struct op *)NULL)#define	NOWORD	((char *)NULL)#define	NOWORDS	((char **)NULL)#define	NOPIPE	((int *)NULL)/* * Description of a command or an operation on commands. * Might eventually use a union. */struct op {	int	type;	/* operation type, see below */	char	**words;	/* arguments to a command */	struct	ioword	**ioact;	/* IO actions (eg, < > >>) */	struct op *left;	struct op *right;	char	*str;	/* identifier for case and for */};#define	TCOM	1	/* command */#define	TPAREN	2	/* (c-list) */#define	TPIPE	3	/* a | b */#define	TLIST	4	/* a [&;] b */#define	TOR	5	/* || */#define	TAND	6	/* && */#define	TFOR	7#define	TDO	8#define	TCASE	9#define	TIF	10#define	TWHILE	11#define	TUNTIL	12#define	TELIF	13#define	TPAT	14	/* pattern in case */#define	TBRACE	15	/* {c-list} */#define	TASYNC	16	/* c & *//* * actions determining the environment of a process */#define	BIT(i)	(1<<(i))#define	FEXEC	BIT(0)	/* execute without forking *//* * flags to control evaluation of words */#define	DOSUB	1	/* interpret $, `, and quotes */#define	DOBLANK	2	/* perform blank interpretation */#define	DOGLOB	4	/* interpret [?* */#define	DOKEY	8	/* move words with `=' to 2nd arg. list */#define	DOTRIM	16	/* trim resulting string */#define	DOALL	(DOSUB|DOBLANK|DOGLOB|DOKEY|DOTRIM)static	char	**dolv;static	int	dolc;static	int	exstat;static  char	gflg;static  int	interactive;	/* Is this an interactive shell */static  int	execflg;static  int	multiline;	/* \n changed to ; */static  struct	op	*outtree;	/* result from parser */static	xint	*failpt;static	xint	*errpt;static	struct brkcon	*brklist;static	int	isbreak;static int newfile(char *s);static char *findeq(char *cp);static char *cclass(char *p, int sub);static void initarea(void);extern int msh_main(int argc, char **argv);struct	brkcon {	jmp_buf	brkpt;	struct	brkcon	*nextlev;} ;/* * redirection */struct ioword {	short	io_unit;	/* unit affected */	short	io_flag;	/* action (below) */	char	*io_name;	/* file name */};#define	IOREAD	1	/* < */#define	IOHERE	2	/* << (here file) */#define	IOWRITE	4	/* > */#define	IOCAT	8	/* >> */#define	IOXHERE	16	/* ${}, ` in << */#define	IODUP	32	/* >&digit */#define	IOCLOSE	64	/* >&- */#define	IODEFAULT (-1)	/* token for default IO unit */static	struct	wdblock	*wdlist;static	struct	wdblock	*iolist;/* * parsing & execution environment */static struct	env {	char	*linep;	struct	io	*iobase;	struct	io	*iop;	xint	*errpt;	int	iofd;	struct	env	*oenv;} e;/* * flags: * -e: quit on error * -k: look for name=value everywhere on command line * -n: no execution * -t: exit after reading and executing one command * -v: echo as read * -x: trace * -u: unset variables net diagnostic */static	char	*flag;static	char	*null;	/* null value for variable */static	int	intr;	/* interrupt pending */static	char	*trap[_NSIG+1];static	char	ourtrap[_NSIG+1];static	int	trapset;	/* trap pending */static	int	heedint;	/* heed interrupt signals */static	int	yynerrs;	/* yacc */static	char	line[LINELIM];static	char	*elinep;/* * other functions */static int(*inbuilt(char *s))(struct op *);static char *rexecve (char *c , char **v, char **envp );static char *space (int n );static char *strsave (char *s, int a );static char *evalstr (char *cp, int f );static char *putn (int n );static char *itoa (int n );static char *unquote (char *as );static struct var *lookup (char *n );static int rlookup (char *n );static struct wdblock *glob (char *cp, struct wdblock *wb );static int my_getc( int ec);static int subgetc (int ec, int quoted );static char **makenv (void);static char **eval (char **ap, int f );static int setstatus (int s );static int waitfor (int lastpid, int canintr );static void onintr (int s ); /* SIGINT handler */static int newenv (int f );static void quitenv (void);static void err (char *s );static int anys (char *s1, char *s2 );static int any (int c, char *s );static void next (int f );static void setdash (void);static void onecommand (void);static void runtrap (int i );static int gmatch (char *s, char *p );/* * error handling */static void leave (void); /* abort shell (or fail in subshell) */static void fail (void);	 /* fail but return to process next command */static void warn (char *s );static void sig (int i );	 /* default signal handler *//* -------- area stuff -------- */#define	REGSIZE		sizeof(struct region)#define GROWBY		256//#define	SHRINKBY   64#undef	SHRINKBY#define FREE 32767#define BUSY 0#define	ALIGN (sizeof(int)-1)struct region {	struct	region *next;	int	area;};/* -------- grammar stuff -------- */typedef union {	char	*cp;	char	**wp;	int	i;	struct	op *o;} YYSTYPE;#define	WORD	256#define	LOGAND	257#define	LOGOR	258#define	BREAK	259#define	IF	260#define	THEN	261#define	ELSE	262#define	ELIF	263#define	FI	264#define	CASE	265#define	ESAC	266#define	FOR	267#define	WHILE	268#define	UNTIL	269#define	DO	270#define	DONE	271#define	IN	272#define	YYERRCODE 300/* flags to yylex */#define	CONTIN	01	/* skip new lines to complete command */#define	SYNTAXERR	zzerr()static struct op *pipeline(int cf );static struct op *andor(void);static struct op *c_list(void);static int synio(int cf );static void musthave (int c, int cf );static struct op *simple(void);static struct op *nested(int type, int mark );static struct op *command(int cf );static struct op *dogroup(int onlydone );static struct op *thenpart(void);static struct op *elsepart(void);static struct op *caselist(void);static struct op *casepart(void);static char **pattern(void);static char **wordlist(void);static struct op *list(struct op *t1, struct op *t2 );static struct op *block(int type, struct op *t1, struct op *t2, char **wp );static struct op *newtp(void);static struct op *namelist(struct op *t );static char **copyw(void);static void word(char *cp );static struct ioword **copyio(void);static struct ioword *io (int u, int f, char *cp );static void zzerr(void);static void yyerror(char *s );static int yylex(int cf );static int collect(int c, int c1 );static int dual(int c );static void diag(int ec );static char *tree(unsigned size );/* -------- var.h -------- */struct	var {	char	*value;	char	*name;	struct	var	*next;	char	status;};#define	COPYV	1	/* flag to setval, suggesting copy */#define	RONLY	01	/* variable is read-only */#define	EXPORT	02	/* variable is to be exported */#define	GETCELL	04	/* name & value space was got with getcell */static	struct	var	*vlist;		/* dictionary */static	struct	var	*homedir;	/* home directory */static	struct	var	*prompt;	/* main prompt */static	struct	var	*cprompt;	/* continuation prompt */static	struct	var	*path;		/* search path for commands */static	struct	var	*shell;		/* shell to interpret command files */static	struct	var	*ifs;		/* field separators */static int yyparse (void);static struct var *lookup (char *n );static void setval (struct var *vp, char *val );static void nameval (struct var *vp, char *val, char *name );static void export (struct var *vp );static void ronly (struct var *vp );static int isassign (char *s );static int checkname (char *cp );static int assign (char *s, int cf );static void putvlist (int f, int out );static int eqname (char *n1, char *n2 );static int execute (struct op *t, int *pin, int *pout, int act );/* -------- io.h -------- *//* io buffer */struct iobuf {  unsigned id;				/* buffer id */  char buf[512];			/* buffer */  char *bufp;				/* pointer into buffer */  char *ebufp;				/* pointer to end of buffer */};/* possible arguments to an IO function */struct ioarg {	char	*aword;	char	**awordlist;	int	afile;		/* file descriptor */	unsigned afid;		/* buffer id */	long	afpos;		/* file position */	struct iobuf *afbuf;	/* buffer for this file */};//static struct ioarg ioargstack[NPUSH];#define AFID_NOBUF	(~0)#define AFID_ID		0/* an input generator's state */struct	io {	int	(*iofn)(struct  ioarg *, struct io *);	struct	ioarg	*argp;	int	peekc;	char	prev;		/* previous character read by readc() */	char	nlcount;	/* for `'s */	char	xchar;		/* for `'s */	char	task;		/* reason for pushed IO */};//static	struct	io	iostack[NPUSH];#define	XOTHER	0	/* none of the below */#define	XDOLL	1	/* expanding ${} */#define	XGRAVE	2	/* expanding `'s */#define	XIO	3	/* file IO *//* in substitution */#define	INSUB()	(e.iop->task == XGRAVE || e.iop->task == XDOLL)/* * input generators for IO structure */static int nlchar (struct ioarg *ap );static int strchar (struct ioarg *ap );static int qstrchar (struct ioarg *ap );static int filechar (struct ioarg *ap );static int herechar (struct ioarg *ap );static int linechar (struct ioarg *ap );static int gravechar (struct ioarg *ap, struct io *iop );static int qgravechar (struct ioarg *ap, struct io *iop );static int dolchar (struct ioarg *ap );static int wdchar (struct ioarg *ap );static void scraphere (void);static void freehere (int area );static void gethere (void);static void markhere (char *s, struct ioword *iop );static int herein (char *hname, int xdoll );static int run (struct ioarg *argp, int (*f)(struct ioarg *));/* * IO functions */static int eofc (void);static int readc (void);static void unget (int c );static void ioecho (int c );static void prs (char *s );static void prn (unsigned u );static void closef (int i );static void closeall (void);/* * IO control */static void pushio (struct ioarg *argp, int (*f)(struct ioarg *));static int remap (int fd );static int openpipe (int *pv );static void closepipe (int *pv );static struct io *setbase (struct io *ip );static	struct	ioarg	temparg;	/* temporary for PUSHIO */#define	PUSHIO(what,arg,gen) ((temparg.what = (arg)),pushio(&temparg,(gen)))#define	RUN(what,arg,gen) ((temparg.what = (arg)), run(&temparg,(gen)))/* -------- word.h -------- */#define	NSTART	16	/* default number of words to allow for initially */struct	wdblock {	short	w_bsize;	short	w_nword;	/* bounds are arbitrary */	char	*w_words[1];};static struct wdblock *addword (char *wd, struct wdblock *wb );static struct wdblock *newword (int nw );static char **getwords (struct wdblock *wb );/* -------- area.h -------- *//* * storage allocation */static char *getcell (unsigned nbytes );static void garbage (void);static void setarea (char *cp, int a );static int getarea (char *cp );static void freearea (int a );static void freecell (char *cp );static	int	areanum;	/* current allocation area */#define	NEW(type) (type *)getcell(sizeof(type))#define	DELETE(obj)	freecell((char *)obj)/* -------- misc stuff -------- */static int forkexec (struct op *t, int *pin, int *pout, int act, char **wp, int *pforked );static int iosetup (struct ioword *iop, int pipein, int pipeout );static void echo(char **wp );static struct op **find1case (struct op *t, char *w );static struct op *findcase (struct op *t, char *w );static void brkset(struct brkcon *bc );static int dolabel(struct op *t );static int dohelp(struct op *t );static int dochdir(struct op *t );static int doshift(struct op *t );static int dologin(struct op *t );static int doumask(struct op *t );static int doexec(struct op *t );static int dodot(struct op *t );static int dowait(struct op *t );static int doread(struct op *t );static int doeval(struct op *t );static int dotrap(struct op *t );static int getsig(char *s );static void setsig (int n, sighandler_t f);static int getn(char *as );static int dobreak(struct op *t );static int docontinue(struct op *t );static int brkcontin (char *cp, int val );static int doexit(struct op *t );static int doexport(struct op *t );static int doreadonly(struct op *t );static void rdexp (char **wp, void (*f)(struct var *), int key);static void badid(char *s );static int doset(struct op *t );static void varput (char *s, int out );static int dotimes(struct op *t );static int expand (char *cp, struct wdblock **wbp, int f );static char *blank(int f );static int dollar(int quoted );static int grave(int quoted );static void globname (char *we, char *pp );static char *generate (char *start1, char *end1, char *middle, char *end );static int anyspcl(struct wdblock *wb );static int xstrcmp (char *p1, char *p2 );static void glob0 (char *a0, unsigned int a1, int a2, int (*a3)(char *, char *));static void glob1 (char *base, char *lim );static void glob2 (char *i, char *j );static void glob3 (char *i, char *j, char *k );static void readhere (char **name, char *s, int ec );static void pushio (struct ioarg *argp, int (*f)(struct ioarg *));static int xxchar(struct ioarg *ap );struct	here {	char	*h_tag;	int	h_dosub;	struct	ioword *h_iop;	struct	here	*h_next;};static	char	*signame[] = {	"Signal 0",	"Hangup",	(char *)NULL,	/* interrupt */	"Quit",	"Illegal instruction",	"Trace/BPT trap",	"Abort",	"Bus error",	"Floating Point Exception",	"Killed",	"SIGUSR1",	"SIGSEGV",	"SIGUSR2",	(char *)NULL,	/* broken pipe */	"Alarm clock",	"Terminated",};#define	NSIGNAL (sizeof(signame)/sizeof(signame[0]))struct res {	char *r_name;	int	  r_val;};static struct res restab[] = {    {"for",		FOR},    {"case",	CASE},    {"esac",	ESAC},    {"while",	WHILE},    {"do",		DO},    {"done",	DONE},    {"if",		IF},    {"in",		IN},    {"then",	THEN},    {"else",	ELSE},    {"elif",	ELIF},    {"until",	UNTIL},    {"fi",		FI},    {";;",		BREAK},    {"||",		LOGOR},    {"&&",		LOGAND},    {"{",		'{'},    {"}",		'}'},    {0,		0},};struct builtincmd {	const char *name;	int (*builtinfunc)(struct op *t);};static const struct	builtincmd	builtincmds[] = {    {".",		dodot},    {":",		dolabel},    {"break",	dobreak},    {"cd",		dochdir},    {"continue",docontinue},    {"eval",	doeval},    {"exec",	doexec},    {"exit",	doexit},    {"export",	doexport},    {"help",	dohelp},    {"login",	dologin},    {"newgrp",	dologin},    {"read",	doread},    {"readonly",doreadonly},    {"set",		doset},    {"shift",	doshift},    {"times",	dotimes},    {"trap",	dotrap},    {"umask",	doumask},    {"wait",	dowait},    {0,0}};/* Globals */extern	char	**environ;	/* environment pointer */static char	**dolv;static int	dolc;static int	exstat;static char	gflg;static int	interactive;	/* Is this an interactive shell */static int	execflg;static int	multiline;	/* \n changed to ; */static struct	op	*outtree;	/* result from parser */static xint	*failpt;static xint	*errpt;static struct	brkcon	*brklist;static int	isbreak;static struct	wdblock	*wdlist;static struct	wdblock	*iolist;static char	*trap[_NSIG+1];static char	ourtrap[_NSIG+1];static int	trapset;	/* trap pending */static int	yynerrs;	/* yacc */static char	line[LINELIM];static struct	var	*vlist;		/* dictionary */static struct	var	*homedir;	/* home directory */static struct	var	*prompt;	/* main prompt */static struct	var	*cprompt;	/* continuation prompt */static struct	var	*path;		/* search path for commands */static struct	var	*shell;		/* shell to interpret command files */static struct	var	*ifs;		/* field separators */static struct	ioarg ioargstack[NPUSH];static struct	io	iostack[NPUSH];static int	areanum;	/* current allocation area */static int	intr;static int	inparse;static char	flags['z'-'a'+1];static char	*flag = flags-'a';static char	*elinep = line+sizeof(line)-5;static char	*null	= "";static int	heedint =1;static struct env e ={line, iostack, iostack-1, (xint *)NULL, FDBASE, (struct env *)NULL};static void (*qflag)(int) = SIG_IGN;static	int	startl;static	int	peeksym;static	int	nlseen;static	int	iounit = IODEFAULT;static	YYSTYPE	yylval;static struct iobuf sharedbuf = {AFID_NOBUF};static struct iobuf mainbuf = {AFID_NOBUF};static unsigned bufid = AFID_ID;	/* buffer id counter */static struct ioarg temparg = {0, 0, 0, AFID_NOBUF, 0};static	struct here *inhere;		/* list of hear docs while parsing */static	struct here *acthere;		/* list of active here documents */static	struct region *areabot;		/* bottom of area */static	struct region *areatop;		/* top of area */static	struct region *areanxt;		/* starting point of scan */static void * brktop;static void * brkaddr;#ifdef CONFIG_FEATURE_COMMAND_EDITINGstatic char * current_prompt;#endif/* -------- sh.c -------- *//* * shell */extern int msh_main(int argc, char **argv){	register int f;	register char *s;	int cflag;	char *name, **ap;	int (*iof)(struct ioarg *);	initarea();	if ((ap = environ) != NULL) {		while (*ap)			assign(*ap++, !COPYV);		for (ap = environ; *ap;)			export(lookup(*ap++));	}	closeall();	areanum = 1;	shell = lookup("SHELL");

⌨️ 快捷键说明

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