代码模版全.docx
《代码模版全.docx》由会员分享,可在线阅读,更多相关《代码模版全.docx(18页珍藏版)》请在冰豆网上搜索。
代码模版全
//Shell.
#include"types.h"
#include"user.h"
#include"fcntl.h"
//Parsedcommandrepresentation
#defineEXEC1
#defineREDIR2
#definePIPE3
#defineLIST4
#defineBACK5
#defineMAXARGS10
structcmd{
inttype;
};
structexeccmd{
inttype;
char*argv[MAXARGS];
char*eargv[MAXARGS];
};
structredircmd{
inttype;
structcmd*cmd;
char*file;
char*efile;
intmode;
intfd;
};
structpipecmd{
inttype;
structcmd*left;
structcmd*right;
};
structlistcmd{
inttype;
structcmd*left;
structcmd*right;
};
structbackcmd{
inttype;
structcmd*cmd;
};
intfork1(void);//Forkbutpanicsonfailure.
voidpanic(char*);
structcmd*parsecmd(char*);
//Executecmd.Neverreturns.
void
runcmd(structcmd*cmd)
{
intp[2];
structbackcmd*bcmd;
structexeccmd*ecmd;
structlistcmd*lcmd;
structpipecmd*pcmd;
structredircmd*rcmd;
if(cmd==0)
exit();
switch(cmd->type){
default:
panic("runcmd");
caseEXEC:
ecmd=(structexeccmd*)cmd;
if(ecmd->argv[0]==0)
exit();
exec(ecmd->argv[0],ecmd->argv);
printf(2,"exec%sfailed\n",ecmd->argv[0]);
break;
caseREDIR:
rcmd=(structredircmd*)cmd;
close(rcmd->fd);
if(open(rcmd->file,rcmd->mode)<0){
printf(2,"open%sfailed\n",rcmd->file);
exit();
}
runcmd(rcmd->cmd);
break;
caseLIST:
lcmd=(structlistcmd*)cmd;
if(fork1()==0)
runcmd(lcmd->left);
wait();
runcmd(lcmd->right);
break;
casePIPE:
pcmd=(structpipecmd*)cmd;
if(pipe(p)<0)
panic("pipe");
if(fork1()==0){
close
(1);
dup(p[1]);
close(p[0]);
close(p[1]);
runcmd(pcmd->left);
}
if(fork1()==0){
close(0);
dup(p[0]);
close(p[0]);
close(p[1]);
runcmd(pcmd->right);
}
close(p[0]);
close(p[1]);
wait();
wait();
break;
caseBACK:
bcmd=(structbackcmd*)cmd;
if(fork1()==0)
runcmd(bcmd->cmd);
break;
}
exit();
}
int
getcmd(char*buf,intnbuf)
{
printf(2,"$");
memset(buf,0,nbuf);
gets(buf,nbuf);
if(buf[0]==0)//EOF
return-1;
return0;
}
int
main(void)
{
staticcharbuf[100];
intfd;
//Assumesthreefiledescriptorsopen.
while((fd=open("console",O_RDWR))>=0){
if(fd>=3){
close(fd);
break;
}
}
//Readandruninputcommands.
while(getcmd(buf,sizeof(buf))>=0){
if(buf[0]=='c'&&buf[1]=='d'&&buf[2]==''){
//Clumsybutwillhavetodofornow.
//Chdirhasnoeffectontheparentifruninthechild.
buf[strlen(buf)-1]=0;//chop\n
if(chdir(buf+3)<0)
printf(2,"cannotcd%s\n",buf+3);
continue;
}
if(fork1()==0)
runcmd(parsecmd(buf));
wait();
}
exit();
}
void
panic(char*s)
{
printf(2,"%s\n",s);
exit();
}
int
fork1(void)
{
intpid;
pid=fork();
if(pid==-1)
panic("fork");
returnpid;
}
//PAGEBREAK!
//Constructors
structcmd*
execcmd(void)
{
structexeccmd*cmd;
cmd=malloc(sizeof(*cmd));
memset(cmd,0,sizeof(*cmd));
cmd->type=EXEC;
return(structcmd*)cmd;
}
structcmd*
redircmd(structcmd*subcmd,char*file,char*efile,intmode,intfd)
{
structredircmd*cmd;
cmd=malloc(sizeof(*cmd));
memset(cmd,0,sizeof(*cmd));
cmd->type=REDIR;
cmd->cmd=subcmd;
cmd->file=file;
cmd->efile=efile;
cmd->mode=mode;
cmd->fd=fd;
return(structcmd*)cmd;
}
structcmd*
pipecmd(structcmd*left,structcmd*right)
{
structpipecmd*cmd;
cmd=malloc(sizeof(*cmd));
memset(cmd,0,sizeof(*cmd));
cmd->type=PIPE;
cmd->left=left;
cmd->right=right;
return(structcmd*)cmd;
}
structcmd*
listcmd(structcmd*left,structcmd*right)
{
structlistcmd*cmd;
cmd=malloc(sizeof(*cmd));
memset(cmd,0,sizeof(*cmd));
cmd->type=LIST;
cmd->left=left;
cmd->right=right;
return(structcmd*)cmd;
}
structcmd*
backcmd(structcmd*subcmd)
{
structbackcmd*cmd;
cmd=malloc(sizeof(*cmd));
memset(cmd,0,sizeof(*cmd));
cmd->type=BACK;
cmd->cmd=subcmd;
return(structcmd*)cmd;
}
//PAGEBREAK!
//Parsing
charwhitespace[]="\t\r\n\v";
charsymbols[]="<|>&;()";
int
gettoken(char**ps,char*es,char**q,char**eq)
{
char*s;
intret;
s=*ps;
while(ss++;
if(q)
*q=s;
ret=*s;
switch(*s){
case0:
break;
case'|':
case'(':
case')':
case';':
case'&':
case'<':
s++;
break;
case'>':
s++;
if(*s=='>'){
ret='+';
s++;
}
break;
default:
ret='a';
while(sstrchr(whitespace,*s)&&!
strchr(symbols,*s))
s++;
break;
}
if(eq)
*eq=s;
while(ss++;
*ps=s;
returnret;
}
int
peek(char**ps,char*es,char*toks)
{
char*s;
s=*ps;
while(ss++;
*ps=s;
return*s&&strchr(toks,*s);
}
structcmd*parseline(char**,char*);
structcmd*parsepipe(char**,char*);
structcmd*parseexec(char**,char*);
structcmd*nulterminate(structcmd*);
structcmd*
parsecmd(char*s)
{
char*es;
structcmd*cmd;
es=s+strlen(s);
cmd=parseline(&s,es);
peek(&s,es,"");
if(s!
=es){
printf(2,"leftovers:
%s\n",s);
panic("syntax");
}
nulterminate(cmd);
returncmd;
}
structcmd*
parseline(char**ps,char*es)
{
structcmd*cmd;
cmd=parsepipe(ps,es);
while(peek(ps,es,"&")){
gettoken(ps,es,0,0);
cmd=backcmd(cmd);
}
if(peek(ps,es,";")){
gettoken(ps,es,0,0);
cmd=listcmd(cmd,parseline(ps,es));
}
returncmd;
}
structcmd*
parsepipe(char**ps,char*es)
{
structcmd*cmd;
cmd=parseexec(ps,es);
if(peek(ps,es,"|")){
gettoken(ps,es,0,0);
cmd=pipecmd(cmd,parsepipe(ps,es));
}
returncmd;
}
structcmd*
parseredirs(structcmd*cmd,char**ps,char*es)
{
inttok;
char*q,*eq;
while(peek(ps,es,"<>")){
tok=gettoken(ps,es,0,0);
if(gettoken(ps,es,&q,&eq)!
='a')
panic("missingfileforredirection");
switch(tok){
case'<':
cmd=redircmd(cmd,q,eq,O_RDONLY,0);
break;
case'>':
cmd=redircmd(cmd,q,eq,O_WRONLY|O_CREATE,1);
break;
case'+':
//>>
cmd=redircmd(cmd,q,eq,O_WRONLY|O_CREATE,1);
break;
}
}
returncmd;
}
structcmd*
parseblock(char**ps,char*es)
{
structcmd*cmd;
if(!
peek(ps,es,"("))
panic("parseblock");
gettoken(ps,es,0,0);
cmd=parseline(ps,es);
if(!
peek(ps,es,")"))
panic("syntax-missing)");
gettoken(ps,es,0,0);
cmd=parseredirs(cmd,ps,es);
returncmd;
}
structcmd*
parseexec(char**ps,char*es)
{
char*q,*eq;
inttok,argc;
structexeccmd*cmd;
structcmd*ret;
if(peek(ps,es,"("))
returnparseblock(ps,es);
ret=execcmd();
cmd=(structexeccmd*)ret;
argc=0;
ret=parseredirs(ret,ps,es);
while(!
peek(ps,es,"|)&;")){
if((tok=gettoken(ps,es,&q,&eq))==0)
break;
if(tok!
='a')
panic("syntax");
cmd->argv[argc]=q;
cmd->eargv[argc]=eq;
argc++;
if(argc>=MAXARGS)
panic("toomanyargs");
ret=parseredirs(ret,ps,es);
}
cmd->argv[argc]=0;
cmd->eargv[argc]=0;
returnret;
}
//NUL-terminateallthecountedstrings.
structcmd*
nulterminate(structcmd*cmd)
{
inti;
structbackcmd*bcmd;
structexeccmd*ecmd;
structlistcmd*lcmd;
structpipecmd*pcmd;
structredircmd*rcmd;
if(cmd==0)
return0;
switch(cmd->type){
caseEXEC:
ecmd=(structexeccmd*)cmd;
for(i=0;ecmd->argv[i];i++)
*ecmd->eargv[i]=0;
break;
caseREDIR:
rcmd=(structredircmd*)cmd;
nulterminate(rcmd->cmd);
*rcmd->efile=0;
break;
casePIPE:
pcmd=(structpipecmd*)cmd;
nulterminate(pcmd->left);
nulterminate(pcmd->right);
break;
caseLIST:
lcmd=(structlistcmd*)cmd;
nulterminate(lcmd->left);
nulterminate(lcmd->right);
break;
caseBACK:
bcmd=(structbackcmd*)cmd;
nulterminate(bcmd->cmd);
break;
}
returncmd;
}