首页 > 代码库 > Linux_C smsh1

Linux_C smsh1

这是一个模拟shell端的程序。

使用了execvp,fork,wait,malloc,realloc以及strtok()函数。

smsh.h

1 char* next_cmd();2 char** splitline(char* );3 void freelist(char **);4 int execute(char** );

smsh1.c

 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <unistd.h> 4 #include <signal.h> 5 #define DFL_PROMPT ">:" 6 int main(){ 7   char * cmdline, *prompt, **arglist; 8   int i; 9   void setup();10   prompt = DFL_PROMPT;11   setup();12   while((cmdline=next_cmd(prompt, stdin)) != NULL ){13     if((arglist=splitline(cmdline))!=NULL){14       for(i=0; i<2; i++)15     printf("%s  ", arglist[i]);16       printf("\n");17       printf("will execute.\n");18       execute(arglist);19       freelist(arglist);20     }21     free(cmdline);22   }23   24   return 0;25 }26 void setup(){27   /*28    * purpose: initialize shell29    * 在shell中忽略信号SIGINT&SIGQUIT, 但是在子进程中恢复对30    * SIGINT&SIGQUIT的默认操作,允许用户通过按表示结束多文件多Ctrl-D来退出31    */32   signal(SIGINT, SIG_IGN);33   signal(SIGQUIT, SIG_IGN);34 }

splitline.c

 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include "smsh.h" 5  6 char* next_cmd(char* prompt, FILE *fp){ 7   /* 8    * purpose: read next command line from fp 9    * return: dynamically allocated string holding command line10    * note: allocates space in BUFSIZ chunks.其中BUFSIZ是库函数中define过了的11    */12   char* buf;13   int bufspace = 0;14   int pos = 0;15   int c;16   //printf("%s", prompt);17   while((c=getc(fp)) != EOF) {18     if(pos+1>=bufspace) {19       if(bufspace==0)20     buf = malloc(BUFSIZ);21       else 22     buf = realloc(buf, bufspace+BUFSIZ);23       bufspace+=BUFSIZ;24     }25     if(c==\n)26       break;27     buf[pos++]=c;28   }29   if(c==EOF || pos==0)30     return NULL;31   buf[pos]=0;32   //printf("u cin is end.\n");33   return buf;34 }35 36 char** splitline(char* cmdline){37   /*38    * purpose: split a line 39    * note:注意:在最后一次给arglist赋值时,也就是strtok()返回为NULL的时候,也需要给40    *            arglist[i]=malloc(sizeof(char*));一下,即使最后赋的为NULL也需要分配一个指针空间给它。41    */42   char **arglist;43   char *delim=" ";44   char *cmdbuf;45   int i=1;46   cmdbuf=strtok(cmdline,delim);47   //printf("cmdbuf0: %s\n", cmdbuf);48   arglist = malloc(sizeof(char*));49   arglist[0]=malloc(strlen(cmdbuf)*sizeof(char));50   strcpy(arglist[0], cmdbuf);51   while((cmdbuf=strtok(NULL, delim))) {52     arglist = realloc(arglist, (1+i)*sizeof(char*));53     arglist[i]=malloc(strlen(cmdbuf)*sizeof(char));54     strcpy(arglist[i], cmdbuf);55     //printf("cmdbuf%d: %s\n",i,cmdbuf);56     i++;57   }58   arglist[i]=malloc(sizeof(char*));59   arglist[i]=NULL;60   return arglist;61 }

execute.c

 1 /* execute.c- code used by small shell to execute commands 2  */ 3 #include <stdio.h> 4 #include <stdlib.h> 5 #include <unistd.h> 6 #include <signal.h> 7 #include <sys/wait.h> 8  9 int execute(char** arglist){10   /*11    *purpose: run a program passing it arguments;12    *return: status returned via wait, or -1 on error13    *errors: -1 on fork() on wait() errors14    */15   int pid;16   int child_info = -1;17   printf("now its go into the function execute\n");18   if((pid=fork()) == -1)19     perror("fork");20   else if(pid == 0) {21     signal(SIGINT, SIG_DFL);22     signal(SIGQUIT, SIG_DFL);23     execvp(arglist[0], arglist);24     perror("cannot execute command");25     exit(1);26   }27   else {28     if(wait(&child_info) == -1)29       perror("wait");30   }31   return child_info;32 }33 void freelist(char** list) {34   /*35    *purpose: free the list returned by splitline36    *returns: nothing37    *actoin: free all strings in list and then free the list38    */39   char **cp=list;40   while(*cp)41     free(*cp++);42   free(list);43 }

 

Linux_C smsh1