• Linux_C smsh2(if,then,else)


    在smsh1的基础上,只是增加了一层process(),以之来处理if,then,else。

    smsh.c 只是更变了一行rv=process();

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

    process.c

     1 /* process.c
     2  * command processing layer
     3  */
     4 #include <stdio.h>
     5 #include "smsh.h"
     6 
     7 int is_control_command(char *);
     8 int do_control_command(char **);
     9 int ok_to_execute();
    10 
    11 int process(char** arglist) {
    12   int rv=1;
    13   if(arglist[0] == NULL)
    14     rv=0;
    15   else if(is_control_command(arglist[0]) )
    16     rv=do_control_command(arglist);
    17   else if(ok_to_execute())
    18     rv=execute(arglist);
    19   return rv;
    20 }

    controlflow.c

      1 /* controlflow.c
      2  * "if"processing is done with two state variables
      3  * if_state and if_result
      4  */
      5 #include <stdio.h>
      6 #include "smsh.h"
      7 
      8 enum states {NEUTRAL, WANT_THEN, THEN_BLOCK, WANT_ELSE, ELSE_BLOCK};
      9 //             0          1          2           3          4
     10 
     11 enum results {SUCCESS, FAIL};
     12 //               0      1
     13 
     14 static int if_state = NEUTRAL;
     15 static int if_result = SUCCESS;
     16 static int last_stat = 0;
     17 
     18 int syn_err(char *);
     19 
     20 int ok_to_execute() {
     21   /* purpose: determine to the shell should execute a command
     22    * returns: 1 for yes, 0 for no
     23    * details: if in THEN_BLOCK and if_result was SUCEESS then yes
     24    *          if in THEN_BLOCK and if_result was FAIL then no
     25    *          if in WANT_THEN then syntax error (sh is different)
     26    */
     27   int rv = 1; //default is possitive 也就是说如果没有if条件判断的,以下几行都不会执行,直接返回rv=1;
     28   if(if_state == WANT_THEN || if_state == WANT_ELSE){
     29     syn_err("then expected");
     30     rv = 0;
     31   }
     32   else if(if_state==THEN_BLOCK && if_result==SUCCESS){
     33     rv = 1;
     34     printf("if_state=THEN_BLOCK  if_result=SUCCESS.
    ");
     35   }
     36   else if(if_state==THEN_BLOCK && if_result==FAIL){
     37     rv = 0;
     38     printf("if_state=WANT_THEN  if_result=SUCCESS.
    ");
     39   }
     40   else if(if_state==ELSE_BLOCK && if_result==SUCCESS){
     41     rv = 0;
     42     printf("if_state=WANT_ELSE  if_result=SUCCESS");
     43   }
     44   else if(if_state==ELSE_BLOCK && if_result==FAIL) {
     45     rv = 1;
     46     printf("if_state=ELSE_BLOCK  if_result=FAIL");
     47   }
     48   printf("rv= %d if_state=%d  if_result=%d.
    ",rv, if_state, if_result);
     49   return rv;
     50 }
     51 
     52 int is_control_command(char *s) {
     53   return (strcmp(s, "if")==0 || strcmp(s,"then")==0 || strcmp(s, "fi")==0 || strcmp(s, "else")==0);
     54 }
     55 
     56 int do_control_command(char ** arglist) {
     57   char *cmd = arglist[0];
     58   int rv = -1;
     59   
     60   printf("****now in do_control_command begin: if_state=%d, if_result=%d.****
    ", if_state, if_result);
     61 
     62   if(strcmp(cmd, "if")==0){
     63     printf("if now.
    ");
     64     if(if_state!=NEUTRAL)
     65       rv = syn_err("if unexpected");
     66     else {
     67       last_stat=process(arglist + 1);
     68       if_result=(last_stat==0?SUCCESS:FAIL);
     69       if(if_result==SUCCESS)
     70     if_state=WANT_THEN;
     71       else 
     72     if_state=WANT_ELSE;
     73       rv=0;
     74     }
     75   }
     76   else if( strcmp(cmd, "then")==0){
     77     printf("then now
    ");
     78     if(if_state!=WANT_THEN && if_state!=WANT_ELSE)
     79       rv=syn_err("then unexpected");
     80     if(if_result==SUCCESS) {
     81       if_state=THEN_BLOCK;
     82       rv=0;
     83     }
     84   }
     85   else if(strcmp(cmd, "else")==0) {
     86     printf("else now.
    ");
     87     if(if_state!=WANT_ELSE)
     88       rv=syn_err("then unexpected");
     89     if(if_result==FAIL){
     90       if_state=ELSE_BLOCK;
     91       rv=0;
     92     }
     93     else if(if_state==SUCCESS) { //这里是说明一下如果if判断语句为真,执行了then后面的命令后,再出现了else,则需要将if_state更改,不然else后命令依然会执行。
     94       if_state=WANT_THEN;
     95       rv=0;
     96     }
     97   }
     98   else if(strcmp(cmd, "fi")==0) {
     99     printf("fi.
    ");
    100     if(if_state != THEN_BLOCK || if_state!=ELSE_BLOCK)
    101       rv=syn_err("fi unexpected");
    102     else {
    103       if_state=NEUTRAL;
    104       rv=0;
    105     }
    106   }
    107   printf("****now in do_control_command end: if_state=%d  if_result=%d****
    ", if_state, if_result);
    108   return rv;
    109 }
    110 
    111 int syn_err(char* msg) {
    112   if_state = NEUTRAL;
    113   fprintf(stderr, "syntax error: %s
    ", msg);
    114   return -1;
    115 }

    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 }
    execute.c

    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 }
    splitline.c

    smsh.h

    1 int process(char**);
    2 char* next_cmd();
    3 char** splitline(char* );
    4 void freelist(char **);
    5 int execute(char** );
    smsh.h
  • 相关阅读:
    FreeSWITCH一些需求应对
    CentOS 7安装Mysql并设置开机自启动
    RTP学习笔记
    SDP学习笔记
    Quartz实用二三事
    Quartz:ERROR threw an unhandled Exception
    CentOS 7一些常用配置
    Java获取音频文件(MP3)的播放时长
    使用Callable和Future接口创建线程
    join() 方法详解及应用场景
  • 原文地址:https://www.cnblogs.com/wizzhangquan/p/4069607.html
Copyright © 2020-2023  润新知