首页 > 代码库 > Linux_C smsh2(if,then,else)
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 shell26 * 在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.\n"); 35 } 36 else if(if_state==THEN_BLOCK && if_result==FAIL){ 37 rv = 0; 38 printf("if_state=WANT_THEN if_result=SUCCESS.\n"); 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.\n",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.****\n", if_state, if_result); 61 62 if(strcmp(cmd, "if")==0){ 63 printf("if now.\n"); 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\n"); 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.\n"); 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.\n");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****\n", 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\n", 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 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 }
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 }
smsh.h
1 int process(char**);2 char* next_cmd();3 char** splitline(char* );4 void freelist(char **);5 int execute(char** );
Linux_C smsh2(if,then,else)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。