發一波福利,操作系統的實驗內容,大家可以借鑒一下,不過我的代碼可能也存在一定的問題。
因為在一開始老師是一節一節課教的,當時並不知道后面還會用輸入輸出重定向,管道等一系列問題,我的興趣也不在這個方面也沒有預習,所以一來代碼寫的比較丑,二來沒有對於代碼進行一個合理的規划,寫的也比較亂。
代碼暫時實現到輸入輸出重定向,之后可能會加上管道處理等方面的程序。
如果讓我重新寫這段代碼應該會規划的更好一點吧
/*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; }