Linux 用C语言实现简单的shell(1)
发一波福利,操作系统的实验内容,大家可以借鉴一下,不过我的代码可能也存在一定的问题。
因为在一开始老师是一节一节课教的,当时并不知道后面还会用输入输出重定向,管道等一系列问题,我的兴趣也不在这个方面也没有预习,所以一来代码写的比较丑,二来没有对于代码进行一个合理的规划,写的也比较乱。
代码暂时实现到输入输出重定向,之后可能会加上管道处理等方面的程序。
如果让我重新写这段代码应该会规划的更好一点吧
/*author:Samsons date:2015.4.10*/ #include <stdio.h> #include <signal.h> #include <unistd.h> #include <string.h> #include <stdlib.h> #include <fcntl.h> #include <sys/wait.h> #define MAX(100) #define LEN(100) char *arglist[MAX]; //shell指令参数表 int num; //shell指令参数个数 int execute(char* arglist[])//执行外部命令 { int error; error=execvp(arglist[0],arglist); if (error==-1) printf("failed\n"); exit(1); } char* make(char *buf)//将字符串传入参数表内 { char *cp; cp=malloc(strlen(buf)+1); if (cp==NULL) { fprintf(stderr,"no memory\n"); exit(1); } strcpy(cp,buf); return cp; } int my_system(char *buf,char *arglist[])//对于字符串进行分割 { int num,j,i,last; char buffer[LEN]; num=0; i=0; while (num<MAX) { if (buf[i]=='\n') { arglist[num]=NULL; return num; } if (buf[i]==' ') i++; last=i; while (buf[i]!=' ' && buf[i]!='\n') i++; for (j=last;j<i;j++) buffer[j-last]=buf[j]; buffer[j-last]='\0'; arglist[num++]=make(buffer); } } int inner(char *arglist[])//执行内置指令 { if (strcmp(arglist[0],"exit\0")==0)//exit { exit(0); return 1; } else if (strcmp(arglist[0],"pwd\0")==0)//pwd { char buf[LEN]; getcwd(buf,sizeof(buf));//获得当前目录 printf("Current dir is:%s\n",buf); return 1; } else if (strcmp(arglist[0],"cd\0")==0)//cd { char buf[LEN]; if (chdir(arglist[1])>=0) { getcwd(buf,sizeof(buf)); printf("Current dir is:%s\n",buf); } return 1; } else return 0; } void cat_in(char *q)//输入重定向 { char t[30]; int fd; if (q[0]=='<') { strcpy(t,q+1); fd=open(t,O_RDONLY); arglist[1]=NULL; if (fd==-1) { printf("file open failed\n"); return; } dup(fd,0); close(fd); } } void cat_out(char *q)//输出重定向 { char t[30]; int fd; if (q[0]=='>') { strcpy(t,q+1); arglist[num-1]=NULL; num--; fd=open(t,O_CREAT|O_RDWR); if (fd==-1) { printf("file open failed\n"); return; } dup2(fd,1); close(fd); } } int main() { int i,pid; char buf[LEN]; while (1) { fgets(buf,LEN,stdin);//读入单行指令 num=my_system(buf,arglist);//指令分割 int inner_flag; inner_flag=inner(arglist);//内置指令判断 if (inner_flag==0) { pid=fork();//建立新的进程 if (pid==0) { if (arglist[1]!=NULL) { char q[LEN]; strcpy(q,arglist[1]); cat_in(q);//输入重定向 } if (arglist[num-1]!=NULL) { char q[LEN]; strcpy(q,arglist[num-1]); cat_out(q);//输出重定向 } execute(arglist);//执行 } waitpid(pid,NULL,0); } } return 0; }