MiniDevil As beautiful as a shell
executor_pipe.c
Go to the documentation of this file.
1 /* ************************************************************************** */
2 /* */
3 /* ::: :::::::: */
4 /* executor_pipe.c :+: :+: :+: */
5 /* +:+ +:+ +:+ */
6 /* By: baelgadi <baelgadi@student.42.fr> +#+ +:+ +#+ */
7 /* +#+#+#+#+#+ +#+ */
8 /* Created: 2025/12/16 18:25:03 by zotaj-di #+# #+# */
9 /* Updated: 2026/03/04 07:49:49 by baelgadi ### ########.fr */
10 /* */
11 /* ************************************************************************** */
12 
13 #include <sys/wait.h>
14 #include <signal.h>
15 #include <stdio.h>
16 #include "executor.h"
17 #include "libft.h"
18 #include "ast.h"
19 #include "env.h"
20 #include "signals.h"
21 #include "get_next_line.h"
22 
33 void exec_left_pipe_child(t_ast *left, int pipe_fd[2], t_shell *shell)
34 {
35  int status;
36 
38  close(pipe_fd[0]);
39  dup2(pipe_fd[1], STDOUT_FILENO);
40  close(pipe_fd[1]);
41  shell->is_child = 1;
42  status = executor(left, shell);
43  free(shell->current_input);
44  free_ast(shell->current_ast);
45  free_env_list(&shell->env);
46  get_next_line(-42);
47  exit(status);
48 }
49 
60 void exec_right_pipe_child(t_ast *right, int pipe_fd[2], t_shell *shell)
61 {
62  int status;
63 
65  close(pipe_fd[1]);
66  dup2(pipe_fd[0], STDIN_FILENO);
67  close(pipe_fd[0]);
68  shell->is_child = 1;
69  status = executor(right, shell);
70  free(shell->current_input);
71  free_ast(shell->current_ast);
72  free_env_list(&shell->env);
73  get_next_line(-42);
74  exit(status);
75 }
76 
86 static int wait_for_pipe_children(pid_t left_pid, pid_t right_pid)
87 {
88  int status;
89  int right_status;
90 
91  waitpid(left_pid, &status, 0);
92  waitpid(right_pid, &status, 0);
93  if (WIFEXITED(status))
94  right_status = WEXITSTATUS(status);
95  else if (WIFSIGNALED(status))
96  {
97  if (WTERMSIG(status) == SIGINT)
98  ft_putchar_fd('\n', STDERR_FILENO);
99  else if (WTERMSIG(status) == SIGQUIT)
100  ft_putstr_fd("Quit (core dumped)\n", STDERR_FILENO);
101  right_status = 128 + WTERMSIG(status);
102  }
103  else
104  right_status = 1;
105  return (right_status);
106 }
107 
119 int handle_pipe(t_ast *node, t_shell *shell)
120 {
121  int pipe_fd[2];
122  pid_t left_pid;
123  pid_t right_pid;
124 
125  if (pipe(pipe_fd) == -1)
126  return (perror("minishell: pipe"), 1);
127  left_pid = fork();
128  if (left_pid == -1)
129  return (pipe_fork_error(pipe_fd, 0));
130  if (left_pid == 0)
131  exec_left_pipe_child(node->data.binary.left, pipe_fd, shell);
132  right_pid = fork();
133  if (right_pid == -1)
134  return (pipe_fork_error(pipe_fd, left_pid));
135  if (right_pid == 0)
136  exec_right_pipe_child(node->data.binary.right, pipe_fd, shell);
137  close(pipe_fd[0]);
138  close(pipe_fd[1]);
139  return (wait_for_pipe_children(left_pid, right_pid));
140 }
AST node creation and destruction prototypes.
void free_ast(t_ast *node)
Recursively free an entire AST tree.
Definition: ast_utils.c:46
Environment variable management prototypes.
void free_env_list(t_env **env_list)
Free all nodes in the env linked list.
Definition: env_utils.c:69
int pipe_fork_error(int pipe_fd[2], pid_t left_pid)
Clean up pipe fds and wait for left child on fork failure.
Definition: exec_utils.c:111
int executor(t_ast *node, t_shell *shell)
Main AST executor that dispatches by node type.
Definition: executor.c:42
Executor prototypes for commands, pipes, redirections & heredocs.
static int wait_for_pipe_children(pid_t left_pid, pid_t right_pid)
Wait for both pipe children and return the right one's status.
Definition: executor_pipe.c:86
void exec_left_pipe_child(t_ast *left, int pipe_fd[2], t_shell *shell)
Execute the left side of a pipe in a child process.
Definition: executor_pipe.c:33
int handle_pipe(t_ast *node, t_shell *shell)
Execute a pipe node by forking left and right children.
void exec_right_pipe_child(t_ast *right, int pipe_fd[2], t_shell *shell)
Execute the right side of a pipe in a child process.
Definition: executor_pipe.c:60
void reset_child_signals(void)
Reset signals to default behavior for the child processes.
Definition: signals.c:66
Signal handler prototypes.
AST node (union based ↑)
Definition: structs.h:151
t_ast_data data
cmd, redir or binary data
Definition: structs.h:153
struct s_ast * left
left child (before pipe)
Definition: structs.h:124
struct s_ast * right
right child (after pipe)
Definition: structs.h:125
Shell state.
Definition: structs.h:164
t_env * env
Environment linked list.
Definition: structs.h:165
int is_child
Child flag (to avoid leaks)
Definition: structs.h:173
char * current_input
Current input line.
Definition: structs.h:172
struct s_ast * current_ast
Currently executing AST.
Definition: structs.h:171
t_binary_node binary
Definition: structs.h:143