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的程序代码,然后在命令指定的程序结束之后就退出。

  • 相关阅读:
    模板template用法
    关联式容器MAP的用法----类似与python中的dict
    迭代器iterator
    c++中的vertor
    Git操作(git reset & get revert)
    代码度量标准
    __attribute__关键字
    Centos7.2部署.Net Core2.0 WebApi
    通过nginx 访问 centos 7 服务器上的.Net Core
    ASP.NET Core部署到CentOS7,使用Nginx代理
  • 原文地址:https://www.cnblogs.com/wizzhangquan/p/4066079.html
Copyright © 2011-2022 走看看