/*2-2.c: a simple shell*/ /* use command 'leave' to exit*/ #include #include #include #include #include #include #define BUFFERSIZE 80 extern char *get_current_dir_name(void); extern char *getenv(const char *name); extern pid_t waitpid(pid_t pid, int *status, int options); char buffer[BUFFERSIZE+1]; main() { char *path, *arg[10], *input; int li_inputlen, is_bj, is_back, i, j, k, pid, status; char lc_char; while (1){ /* initiations */ is_bj = 0; /*redirection flag*/ is_back = 0; /*background*/ /* shell prompt */ path = get_current_dir_name(); printf("%s>$",path); /*开始获取输入*/ li_inputlen = 0; lc_char = getchar(); while (lc_char !='\n'){ if(li_inputlen < BUFFERSIZE) buffer[li_inputlen++] = lc_char; lc_char = getchar(); } /*命令超长处理*/ if (li_inputlen >= BUFFERSIZE){ printf("Your command is too long! Please re-enter your command!\n"); li_inputlen = 0; /*reset */ continue; } else buffer[li_inputlen] = '\0';/*加上串结束符号,形成字串*/ /*将命令从缓存拷贝到input中*/ input = (char *) malloc(sizeof(char) * (li_inputlen+1)); strcpy(input,buffer); /* 获取命令和参数并保存在arg中*/ for (i = 0,j = 0,k = 0;i <= li_inputlen;i++){ /*管道和重定向单独处理*/ if (input[i] == '<' || input[i] == '>' || input[i] =='|'){ if (input[i] == '|') pipel(input,li_inputlen); else redirect(input,li_inputlen); is_bj = 1; break; } /*处理空格、TAB和结束符。不用处理‘\n',大家如果仔细分析前面的获取输入的程序的话, *不难发现回车符并没有写入buffer*/ if (input[i] == ' ' || input[i] =='\t' || input[i] == '\0'){ if (j == 0) /*这个条件可以略去连在一起的多个空格或者tab*/ continue; else{ buffer[j++] = '\0'; arg[k] = (char *) malloc(sizeof(char)*j); /*将指令或参数从缓存拷贝到arg中*/ strcpy(arg[k],buffer); j = 0; /*准备取下一个参数*/ k++; } } else{ /*如果字串最后是‘&',则置后台运行标记为1*/ if (input[i] == '&' && input[i+1] == '\0'){ is_back = 1; continue; } buffer[j++] = input[i]; } } free(input);/*释放空间*/ /*如果输入的指令是leave则退出while,即退出程序*/ if (strcmp(arg[0],"leave") == 0 ){ printf("bye-bye\n"); break; } if (is_bj == 0){ /*非管道、重定向指令*/ /*在使用xxec执行命令的时候,最后的参数必须是NULL指针, *所以将最后一个参数置成空值*/ arg[k] = (char *) 0; /*判断指令arg[0]是否存在*/ if (is_fileexist(arg[0]) == -1 ){ printf("This command is not found?!\n"); for(i=0;i'){ if (in[i] == '>' || in[i] == '<'){ /*重定向指令最多'<','>'各出现一次,因此num最大为2, *否则认为命令输入错误*/ if (num < 3){ num ++; if (in[i] == '<') is_in = num - 1; else is_out = num - 1; /*处理命令和重定向符号相连的情况,比如ls>a*/ if (j > 0 && num == 1) { buffer[j++] = '\0'; argv[k] = (char *) malloc(sizeof(char)*j); strcpy(argv[k],buffer); k++; j = 0; } } else{ printf("The format is error!\n"); return -1; } } if (j == 0) continue; else{ buffer[j++] = '\0'; /*尚未遇到重定向符号,字符串是命令或参数*/ if (num == 0){ argv[k] = (char *) malloc(sizeof(char)*j); strcpy(argv[k],buffer); k++; } /*是重定向后符号的字符串,是文件名*/ else{ filename[status] = (char *) malloc(sizeof(char)*j); strcpy(filename[status++],buffer); } j = 0; /*initate*/ } } else{ if (in[i] == '&' && in[i+1] == '\0'){ is_back = 1; continue; } buffer[j++] = in[i]; } } argv[k] = (char *) 0; if (is_fileexist(argv[0]) == -1 ){ printf("This command is not founded!\n"); for(i=0;i 0) { buffer[j++] = '\0'; /*因为管道连接的是两个指令,所以用二维数组指针来存放命令和参数, *li_comm是表示第几个指令*/ argv[li_comm][k] = (char *) malloc(sizeof(char)*j); strcpy(argv[li_comm][k++],buffer); } argv[li_comm][k++] = (char *) 0; /*遇到管道符,第一个指令完毕,开始准备接受第二个指令*/ li_comm++; count = k; k=0;j=0; } if (j == 0) continue; else { buffer[j++] = '\0'; argv[li_comm][k] = (char *) malloc(sizeof(char)*j); strcpy(argv[li_comm][k],buffer); k++; } j = 0; /*initate*/ } else{ if (input[i] == '&' && input[i+1] == '\0'){ is_back = 1; continue; } buffer[j++] = input[i]; } } argv[li_comm][k++] = (char *) 0; if (is_fileexist(argv[0][0]) == -1 ){ printf("This first command is not found!\n"); for(i=0;i