/*执行命令*/ void execSimpleCmd(SimpleCmd *cmd){ int i, pid; char *temp; Job *now = NULL; char *match_out; if(strcmp(cmd->args[0], "exit") == 0) { //exit命令 exit(0); } else if (strcmp(cmd->args[0], "history") == 0) { //history命令 if(history.end == -1){ printf("尚未执行任何命令\n"); return; } i = history.start; do { printf("%s\n", history.cmds[i]); i = (i + 1)%HISTORY_LEN; } while(i != (history.end + 1)%HISTORY_LEN); }else if(strcmp(cmd->args[0], "enable") == 0){//enable command enable_exec(); } else if(strcmp(cmd->args[0], "type") == 0){//type command type_exec(cmd); } else if(strcmp(cmd->args[0], "echo") == 0){//echo command echo_exec(cmd); } else if (strcmp(cmd->args[0], "jobs") == 0) { //jobs命令 if(head == NULL){ printf("尚无任何作业\n"); } else { printf("index\tpid\tstate\t\tcommand\n"); for(i = 1, now = head; now != NULL; now = now->next, i++){ printf("%d\t%d\t%s\t\t%s\n", i, now->pid, now->state, now->cmd); } } } else if (strcmp(cmd->args[0], "cd") == 0) { //cd命令 temp = cmd->args[1]; if(temp != NULL){ if(chdir(temp) < 0){ if (match(temp,&match_out)){ chdir(match_out); free(match_out); } else printf("cd; %s 错误的文件名或文件夹名!\n", temp); } } } else if (strcmp(cmd->args[0], "fg") == 0) { //fg命令 temp = cmd->args[1]; if(temp != NULL && temp[0] == '%'){ pid = str2Pid(temp, 1, strlen(temp)); if(pid != -1){ fg_exec(pid); } }else{ printf("fg; 参数不合法,正确格式为:fg %%<int>\n"); } } else if (strcmp(cmd->args[0], "bg") == 0) { //bg命令 temp = cmd->args[1]; if(temp != NULL && temp[0] == '%'){ pid = str2Pid(temp, 1, strlen(temp)); if(pid != -1){ bg_exec(pid); } } else{ printf("bg; 参数不合法,正确格式为:bg %%<int>\n"); } } else{ //外部命令 execOuterCmd(cmd); } //释放结构体空间 for(i = 0; cmd->args[i] != NULL; i++){ free(cmd->args[i]); free(cmd->input); free(cmd->output); } }
/* execution for commands */ static void execute_command(char cmd[MAX_CMD][MAX_CMD_LEN], pid_t wpid[MAX_CMD], int cmd_num) { /* e.g. "ls", "-l" */ char buf[MAX_ARGC][MAX_ARG_LEN]; /* two pipes needed */ int fds[2][2]; int n; int fd; pid_t pid; /* 0: pipe1, 1: pipe2 */ int pipe_flag; COMMAND command; n = 0; pipe_flag = 0; while (n < cmd_num) { command_init(&command); argument_parser(cmd[n], buf, &command); if (!pipe_flag) { /* pipe1 */ /* last command doesn't need to create a pipe */ if(n != cmd_num - 1) { if (pipe(fds[0]) == -1) { fprintf(stderr, "%s: pipe() error: " "%s\n", command.arg[0], strerror(errno)); /* close read end of previous pipe */ if (n != 0) close(fds[1][0]); while (n < cmd_num) { wpid[n] = -1; n++; } break; } } if ((pid = fork()) == -1){ fprintf(stderr, "%s: fork() error: %s\n", command.arg[0], strerror(errno)); close(fds[0][0]); close(fds[0][1]); /* close read end of previous pipe */ if (n != 0) close(fds[1][0]); while (n < cmd_num) { wpid[n] = -1; n++; } break; } else if (pid == 0) { /* child */ /* * Close read end in child process. * Last command doesn't create a pipe. */ if(n != cmd_num - 1) close(fds[0][0]); /* stdin redirection */ if(strcmp(command.input, "") != 0) { if ((fd = open(command.input, O_RDONLY)) == -1) { fprintf(stderr, "%s: %s: open" "() error: %s\n", command.arg[0], command.input, strerror(errno)); exit(DEFAULT_STATUS); } if (dup2(fd, STDIN_FILENO) == -1) { fprintf(stderr, "%s: %s: dup2()" "error: %s\n", command.arg[0], command.input, strerror(errno)); close(fd); exit(DEFAULT_STATUS); } close(fd); } else if(n != 0){ if (dup2(fds[1][0], STDIN_FILENO) == -1) { fprintf(stderr, "%s: dup2()" "error: %s\n", command.arg[0], strerror(errno)); close(fds[1][0]); exit(DEFAULT_STATUS); } } /* close read end of previous pipe */ if(n != 0) close(fds[1][0]); /* stdout redirection */ if(strcmp(command.output,"")!=0) { if(command.append) fd = open(command.output, O_WRONLY | O_APPEND | O_CREAT, S_IWUSR | S_IRUSR); else fd = open(command.output, O_WRONLY | O_TRUNC | O_CREAT, S_IWUSR | S_IRUSR); if (fd == -1) { fprintf(stderr, "%s: %s: open" "() error: %s\n", command.arg[0], command.output, strerror(errno)); exit(DEFAULT_STATUS); } if (dup2(fd, STDOUT_FILENO) == -1) { fprintf(stderr, "%s: %s: dup2()" "error: %s\n", command.arg[0], command.output, strerror(errno)); close(fd); exit(DEFAULT_STATUS); } close(fd); } else if (n != cmd_num - 1){ if (dup2(fds[0][1], STDOUT_FILENO) == -1) { fprintf(stderr, "%s: dup2()" "error: %s\n", command.arg[0], strerror(errno)); close(fds[0][1]); exit(DEFAULT_STATUS); } } if(n != cmd_num - 1) close(fds[0][1]); /* builtin commands */ if (strcmp(command.arg[0], "exit") == 0) { if (exit_syntax_check(command.arg) == -1) { exit_usage(); exit(EXIT_FAILURE); } else exit(ret_val); } else if (strcmp(command.arg[0], "cd") == 0) { if (cd_syntax_check(command.arg) == -1) { cd_usage(); exit(EXIT_FAILURE); } else { exit(cd_exec(command.arg)); } } else if (strcmp(command.arg[0], "echo") == 0) { echo_exec(command.arg); exit(EXIT_SUCCESS); } execvp(command.arg[0], command.arg); fprintf(stderr, "%s: command not found\n", command.arg[0]); exit(DEFAULT_STATUS); } else { /* parent */ wpid[n] = pid; if(n != cmd_num - 1) close(fds[0][1]); if(n != 0) close(fds[1][0]); } pipe_flag = 1; } else { /* pipe2 */ /* last command doesn't need to create a pipe */ if(n != cmd_num - 1) { if (pipe(fds[1]) == -1) { fprintf(stderr, "%s: pipe() error: " "%s\n", command.arg[0], strerror(errno)); /* close read end of previous pipe */ if (n != 0) close(fds[0][0]); while (n < cmd_num) { wpid[n] = -1; n++; } break; } } if ((pid = fork()) == -1){ fprintf(stderr, "%s: fork() error: %s\n", command.arg[0], strerror(errno)); close(fds[1][0]); close(fds[1][1]); /* close read end of previous pipe */ if (n != 0) close(fds[0][0]); while (n < cmd_num) { wpid[n] = -1; n++; } break; } else if (pid == 0) { /* child */ /* * Close read end in child process. * Last command doesn't create a pipe. */ if(n != cmd_num - 1) close(fds[1][0]); /* stdin redirection */ if(strcmp(command.input, "") != 0) { if ((fd = open(command.input, O_RDONLY)) == -1) { fprintf(stderr, "%s: %s: open" "() error: %s\n", command.arg[0], command.input, strerror(errno)); exit(DEFAULT_STATUS); } if (dup2(fd, STDIN_FILENO) == -1) { fprintf(stderr, "%s: %s: dup2()" "error: %s\n", command.arg[0], command.input, strerror(errno)); close(fd); exit(DEFAULT_STATUS); } close(fd); } else if(n != 0){ if (dup2(fds[0][0], STDIN_FILENO) == -1) { fprintf(stderr, "%s: dup2()" "error: %s\n", command.arg[0], strerror(errno)); close(fds[0][0]); exit(DEFAULT_STATUS); } } /* close read end of previous pipe */ if(n != 0) close(fds[0][0]); /* stdout redirection */ if(strcmp(command.output,"")!=0) { if(command.append) fd = open(command.output, O_WRONLY | O_APPEND | O_CREAT, S_IWUSR | S_IRUSR); else fd = open(command.output, O_WRONLY | O_TRUNC | O_CREAT, S_IWUSR | S_IRUSR); if (fd == -1) { fprintf(stderr, "%s: %s: open" "() error: %s\n", command.arg[0], command.output, strerror(errno)); exit(DEFAULT_STATUS); } if (dup2(fd, STDOUT_FILENO) == -1) { fprintf(stderr, "%s: %s: dup2()" "error: %s\n", command.arg[0], command.output, strerror(errno)); close(fd); exit(DEFAULT_STATUS); } close(fd); } else if (n != cmd_num - 1){ if (dup2(fds[1][1], STDOUT_FILENO) == -1) { fprintf(stderr, "%s: dup2()" "error: %s\n", command.arg[0], strerror(errno)); close(fds[1][1]); exit(DEFAULT_STATUS); } } if(n != cmd_num - 1) close(fds[1][1]); /* builtin commands */ if (strcmp(command.arg[0], "exit") == 0) { if (exit_syntax_check(command.arg) == -1) { exit_usage(); exit(EXIT_FAILURE); } else exit(ret_val); } else if (strcmp(command.arg[0], "cd") == 0) { if (cd_syntax_check(command.arg) == -1) { cd_usage(); exit(EXIT_FAILURE); } else { exit(cd_exec(command.arg)); } } else if (strcmp(command.arg[0], "echo") == 0) { echo_exec(command.arg); exit(EXIT_SUCCESS); } execvp(command.arg[0], command.arg); fprintf(stderr, "%s: command not found\n", command.arg[0]); exit(DEFAULT_STATUS); } else { /* parent */ wpid[n] = pid; if(n != cmd_num - 1) close(fds[1][1]); if(n != 0) close(fds[0][0]); } pipe_flag = 0; } n++; } }