zoukankan      html  css  js  c++  java
  • 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("
    ");
    17       printf("will execute.
    ");
    18       execute(arglist);
    19       freelist(arglist);
    20     }
    21     free(cmdline);
    22   }
    23   
    24   return 0;
    25 }
    26 void setup(){
    27   /*
    28    * purpose: initialize shell
    29    * 在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 line
    10    * 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=='
    ')
    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.
    ");
    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
    ", 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
    ",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 error
    13    *errors: -1 on fork() on wait() errors
    14    */
    15   int pid;
    16   int child_info = -1;
    17   printf("now its go into the function execute
    ");
    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 splitline
    36    *returns: nothing
    37    *actoin: free all strings in list and then free the list
    38    */
    39   char **cp=list;
    40   while(*cp)
    41     free(*cp++);
    42   free(list);
    43 }

     关于为什么要开一个进程给execvp()使用,是因为unix运行一个程序;1.将指定的程序复制到调用它的进程。2.将指定的字符串数组作为argv[]传给这个程序。3.运行这个程序。

    如果不开进程就来执行execvp(),就会运行完一个命令后就会结束退出。这是因为execvp()用命令指定的程序代码覆盖了shell的程序代码,然后在命令指定的程序结束之后就退出。

  • 相关阅读:
    URAL——DFS找规律——Nudnik Photographer
    URAL1353——DP——Milliard Vasya's Function
    URAL1203——DPor贪心——Scientific Conference
    递推DP HDOJ 5389 Zero Escape
    区间DP UVA 1351 String Compression
    树形DP UVA 1292 Strategic game
    Manacher HDOJ 5371 Hotaru's problem
    同余模定理 HDOJ 5373 The shortest problem
    递推DP HDOJ 5375 Gray code
    最大子序列和 HDOJ 1003 Max Sum
  • 原文地址:https://www.cnblogs.com/wizzhangquan/p/4066079.html
Copyright © 2011-2022 走看看