|
|

楼主 |
发表于 2005-6-23 17:43:33
|
显示全部楼层
程序代码如下:
[php]
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#define EOL 1
#define ARG 2
#define AMPERSAND 3
#define SEMICOLON 4
#define MAXARG 512/*命令行参数个数的最大值*/
#define MAXBUF 512/*输入行的最大长度 */
#define FOREGROUND 0/*前台执行*/
#define BACKGROUND 1/*后台操作*/
void exit(int);/*不写这个会有个警告,不知道怎么回事,没有意义*/
static char inpbuf[MAXBUF],tokbuf[2*MAXBUF],*ptr=inpbuf,*tok=tokbuf;
int userin(char *p)
{
int c,count;
ptr=inpbuf;
tok=tokbuf;
printf("%s",p);/*命令行提示*/
for(count=0;;){
if((c=getchar())==EOF)
return(EOF);
if(count<MAXBUF)
inpbuf[count++]=c;
if(c=='\n' && count<MAXBUF){
inpbuf[count]='\0';
return(count);
}
/*如果输入过长重新输入*/
if(c=='\n'){
printf("smallsh:inpbuf line too long\n");
count=0;
printf("%s",p);
}
}
}
static char special[]={' ','\t','*',';','\n','\0'};/*除去特殊字符*/
int inarg(char c)
{
char *wrk;
for(wrk=special;*wrk!='\0';wrk++)
if(c==*wrk)
return(0);
return(1);
}
int gettok(char *outptr)
{
int type;
outptr=tok;
for(;*ptr==' '||*ptr=='\t';ptr++);
*tok++=*ptr;
switch(*ptr++){
case'\n':
type=EOL;break;
case'&':
type=AMPERSAND;break;
case';':
type=SEMICOLON;break;
default:
type=ARG;
while(inarg(*ptr))
*tok++=*ptr++;
}
*tok++='\0';
return(type);
}
int runcommand(char **cline,int where)
{
int pid,exitstat,ret;
if((pid=fork())<0){
perror("fork fail");
return(-1);
}
if(!pid) {
execvp(*cline,cline);
perror(*cline);
exit(127);
if(where==BACKGROUND){
printf("[process id %d]\n",pid);
return(0);
}
while((ret=wait(&exitstat)) && ret!=-1);
return(ret==-1?-1:exitstat);
}
}
int procline()
{
char *arg[MAXARG+1];
int toktype;
int narg;
int type;
for (narg=0;;)
{
switch(toktype=gettok(&arg[narg]))
{
case ARG:
if(narg<MAXARG)
narg++;
break;
case EOL:
case SEMICOLON:
case AMPERSAND:
type=(toktype==AMPERSAND)?BACKGROUND:FOREGROUND;
if(narg!=0){
arg[narg]=NULL;
runcommand(arg,type);
}
if(toktype==EOL)
return 0;
narg=0;
break;
}
}
}
int main(int argc,char *argv[])
{
char *prompt="command>";
while(userin(prompt)!=EOF)
procline();
return 1;
}
[/php] |
|