/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* exec_cmd_line.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/11/16 01:57:38 by lperrey #+# #+# */ /* Updated: 2021/11/18 10:28:00 by hulamy ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" // https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_01_01 // Bien penser à mettre les ptr à NULL aprés free en cas d'erreur (pour ne pas double free si appel à free_exit()) int pipeline(t_all *c); int open_pipes(t_cmd *pipeline[]); int pipeline_access_cmd(t_cmd *pipeline[], char *path[]); pid_t pipeline_exec(t_cmd *pipeline[], t_all *c); int cmd_exec_in_subshell(t_cmd *cmd, t_all *c); int simple_cmd_builtin(t_cmd *cmd, t_all *c); void wait_subshell(pid_t last_cmd_pid, int *last_exit_status); int exec_cmd_line(t_all *c) { if (!pipeline(c)) { free_pipeline(&c->cmd_arr); return (0); } return (1); } int pipeline(t_all *c) { if (!open_pipes(c->cmd_arr)) return (0); if (!pipeline_access_cmd(c->cmd_arr, c->path)) return (0); if (ft_2d_arrlen(pipeline) == 1 && c->cmd_arr[0]->builtin_func) { simple_cmd_builtin(c->cmd_arr[0], c); free_pipeline(&c->cmd_arr); } else { wait_subshell(pipeline_exec(c->cmd_arr, c), &c->last_exit_status); free_pipeline(&c->cmd_arr); } return (1); } int open_pipes(t_cmd *pipeline[]) { int i; int pipes[2]; i = 0; while (pipeline[i] && pipeline[i + 1]) { if (pipe(pipes) == -1) return (ft_reti_perror(0, "pipe()")); if (pipeline[i]->fd_out == STDOUT_FILENO) pipeline[i]->fd_out = pipes[STDOUT_FILENO]; else if (close(pipes[STDOUT_FILENO]) == -1) perror("close()"); if (pipeline[i]->fd_in == STDIN_FILENO) pipeline[i + 1]->fd_in = pipes[STDIN_FILENO]; else if (close(pipes[STDIN_FILENO]) == -1) perror("close()"); i++; } return (1); } int pipeline_access_cmd(t_cmd *pipeline[], char *path[]) { // TODO // Penser à : path = strdup(argv[0]); // et non : path = argv[0]; // pour ne pas double free return (1); } int simple_cmd_builtin(t_cmd *cmd, t_all *c) { // TODO return (1); } // TODO : Change exit status as in documentation : // https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_08_02 pid_t pipeline_exec(t_cmd *pipeline[], t_all *c) { int i; int ret; i = 0; while (pipeline[i]) { if (!pipeline[i]->error) { ret = cmd_exec_in_subshell(pipeline[i], c); if (ret != EXIT_SUCCESS) free_exit(c, ret); } i++; } close_pipeline_fd(c->cmd_arr); i -= 1; if (pipeline[i]->error) c->last_exit_status = pipeline[i]->error; return (pipeline[i]->pid); } int handle_wait_error(void) { if (errno == ECHILD) return (-1); else if (errno == EINTR) return (0); else perror("wait()"); return (-1); } void wait_subshell(pid_t last_cmd_pid, int *last_exit_status) { int wstatus; int ret; //wstatus = 0; if (last_cmd_pid > 0) { if (waitpid(last_cmd_pid, &wstatus, 0) == -1) perror("waitpid()"); if (WIFEXITED(wstatus)) *last_exit_status = WEXITSTATUS(wstatus); } ret = 0; while (ret != -1) { ret = wait(&wstatus); if (ret == -1) ret = handle_wait_error(); } if (WIFSIGNALED(wstatus)) { write(STDIN_FILENO, "\n", 1); *last_exit_status = 128 + WTERMSIG(wstatus); } } int cmd_exec_in_subshell(t_cmd *cmd, t_all *c) { cmd->pid = fork(); if (cmd->pid == -1) perror("fork()"); if (cmd->pid == 0) { c->signal_behaviour.sa_handler = SIG_DFL; sigaction(SIGINT, &c->signal_behaviour, NULL); if (cmd->fd_in != STDIN_FILENO) if (dup2(cmd->fd_in, STDIN_FILENO) == -1) return (ft_reti_perror(EXIT_FAILURE, "dup2()")); if (cmd->fd_out != STDOUT_FILENO) if (dup2(cmd->fd_out, STDOUT_FILENO) == -1) return (ft_reti_perror(EXIT_FAILURE, "dup2()")); close_pipeline_fd(c->cmd_arr); if (cmd->builtin_func) free_exit(c, cmd->builtin_func(ft_2d_arrlen(cmd->argv), cmd->argv, c)); else if (execve("/bin/echo", cmd->argv, c->envp) == -1) // WIP, TEST return (ft_reti_perror_io(EXIT_FAILURE, "execve() ", cmd->argv[0])); //else if (execve(cmd->path, cmd->argv, c->envp) == -1) // return (ft_reti_perror_io(EXIT_FAILURE, "execve() ", cmd->argv[0])); } return (EXIT_SUCCESS); }