/* Executes a set of commands that are piped together. * If it's a single command, it simply calls `exec_command`. */ int exec_commands(struct commands *cmds) { int exec_ret; /* single command? run it */ if (cmds->cmd_count == 1) { cmds->cmds[0]->fds[STDIN_FILENO] = STDIN_FILENO; cmds->cmds[0]->fds[STDOUT_FILENO] = STDOUT_FILENO; exec_ret = exec(cmds, cmds->cmds[0], NULL); wait(NULL); } else { /* execute a pipeline */ int pipe_count = cmds->cmd_count - 1; /* if any command in the pipeline is a built-in, raise error */ int i; for (i = 0; i < cmds->cmd_count; i++) { if (check_built_in(cmds->cmds[i])) { fprintf(stderr, "error: no builtins in pipe\n"); return 0; } } /* allocate an array of pipes. Each member is array[2] */ int (*pipes)[2] = calloc(pipe_count * sizeof(int[2]), 1); if (pipes == NULL) { fprintf(stderr, "error: memory alloc error\n"); return 0; } /* create pipes and set file descriptors on commands */ cmds->cmds[0]->fds[STDIN_FILENO] = STDIN_FILENO; for (i = 1; i < cmds->cmd_count; i++) { pipe(pipes[i-1]); cmds->cmds[i-1]->fds[STDOUT_FILENO] = pipes[i-1][1]; cmds->cmds[i]->fds[STDIN_FILENO] = pipes[i-1][0]; } cmds->cmds[pipe_count]->fds[STDOUT_FILENO] = STDOUT_FILENO; /* execute the commands */ for (i = 0; i < cmds->cmd_count; i++) exec_ret = exec(cmds, cmds->cmds[i], pipes); close_pipes(pipes, pipe_count); /* wait for children to finish */ for (i = 0; i < cmds->cmd_count; ++i) wait(NULL); free(pipes); } return exec_ret; }
int exec(struct commands *cmds, struct command *cmd, int (*pipes)[2]) { if (check_built_in(cmd) == 1) return handle_built_in(cmds, cmd); pid_t child_pid = fork(); if (child_pid == -1) { fprintf(stderr, "error: fork error\n"); return 0; } /* in the child */ if (child_pid == 0) { int input_fd = cmd->fds[0]; int output_fd = cmd->fds[1]; // change input/output file descriptors if they aren't standard if (input_fd != -1 && input_fd != STDIN_FILENO) dup2(input_fd, STDIN_FILENO); if (output_fd != -1 && output_fd != STDOUT_FILENO) dup2(output_fd, STDOUT_FILENO); if (pipes != NULL) { int pipe_count = cmds->cmd_count - 1; close_pipes(pipes, pipe_count); } /* execute the command */ execv(cmd->name, cmd->argv); /* execv returns only if an error occurs */ fprintf(stderr, "error: %s\n", strerror(errno)); /* cleanup in the child to avoid memory leaks */ clear(); free(history); free(pipes); free(input); cleanup_commands(cmds); if (parent_cmd != NULL) { free(parent_cmd); free(temp_line); free(parent_cmds); } /* exit from child so that the parent can handle the scenario*/ _exit(EXIT_FAILURE); } /* parent continues here */ return child_pid; }
void execute_son(int fd_in, int fd_out, t_list_p *item, char **envp) { st_exec_test(fd_in, fd_out); if (item->in) process_redir_r(item, envp); else if (item->out) process_redir_w(item, envp); else if (item->app) process_redir_a(item, envp); if (!is_built_in(item->str)) process_command(item->str, envp); else if (ft_is_env_i(item->str) > 0) process_command((item->str + ft_is_env_i(item->str)), NULL); else check_built_in(item->str); exit(0); }
int main(int argc, char *argv[]) { //Checks that only ./whoosh is entered to invoke shell if(argc != 1) { error_msg(); exit(1); } int CHAR_LIMIT = 129; int BUFFER_LIMIT = 1024; char buffer[BUFFER_LIMIT]; int path_num = 1; char* s_path[BUFFER_LIMIT]; s_path[0] = "/bin"; while(1) { printf("whoosh> "); fflush(stdout); fgets(buffer, sizeof(buffer), stdin); get_line(buffer); int line_size = strlen(buffer); if(line_size > CHAR_LIMIT) { error_msg(); continue; } //Get num of args in command int num_args = count_args(buffer); if(num_args != 0) { char* myargv[num_args + 1]; int r_count = 0; int last_r = 0; char* r_path = NULL; int i; char buf[PATH_MAX + 1]; char *cwd; char *r_output; //Put each argument in myargv array get_args(buffer, myargv, num_args); //Check for redirect check_redirect(myargv, num_args, &r_count, &last_r); //Redirect error handling if(r_count > 1) { error_msg(); continue; } else if (r_count == 1) { if(last_r != num_args - 2) { error_msg(); continue; } if(myargv[num_args - 1][0] == '/') { if(chdir(myargv[num_args - 1]) == 0) { r_path = strdup(myargv[num_args - 1]); } else { error_msg(); continue; } } r_output = malloc(strlen(myargv[num_args - 1]) + strlen(".out")); sprintf(r_output, "%s", myargv[num_args - 1]); //Take off > and path from arguments num_args = num_args - 2; } //Set last element in myargv array to NULL myargv[num_args] = NULL; //Check if exit was entered check_exit(myargv); //Check if any built-in commands were called if(check_built_in(myargv, num_args, s_path, &path_num) == 0) { continue; } else{ int file_exist = 0; cwd = getcwd(buf, PATH_MAX + 1); for(i=0; i<path_num; i++) { chdir(s_path[i]); struct stat path_buff; if(stat(myargv[0], &path_buff) == 0) { file_exist = 1; char *exec_path = malloc(strlen(s_path[i]) + strlen("/") + strlen(myargv[0]) + 1); sprintf(exec_path, "%s/%s", s_path[i], myargv[i]); myargv[0] = exec_path; chdir(cwd); break; } } if(file_exist == 0) { error_msg(); continue; } else { exec_cmd(myargv, r_output, r_path, r_count); } } } } }