maxishell
Implementation of a shell for Linux-like systems
Loading...
Searching...
No Matches
pipe.c
Go to the documentation of this file.
1/* ************************************************************************** */
2/* */
3/* ::: :::::::: */
4/* pipe.c :+: :+: :+: */
5/* +:+ +:+ +:+ */
6/* By: dmdemirk <dmdemirk@student.42london.c +#+ +:+ +#+ */
7/* +#+#+#+#+#+ +#+ */
8/* Created: 2024/06/17 11:04:39 by dmdemirk #+# #+# */
9/* Updated: 2024/11/07 19:48:14 by dmdemirk ### ########.fr */
10/* */
11/* ************************************************************************** */
12
13#include "shell.h"
14#include <unistd.h>
15#include "libft.h"
16#include "execute.h"
17#include <stdio.h>
18#include <sys/wait.h>
19#include "pipe.h"
20
21int builtin_pipe(t_ast *node, t_ms_data *data);
22pid_t execute_child(t_ast *node, t_ms_data *data, \
23 int fd[2], int direction);
24
25static int setup_pipe_processes(t_ast *node, t_ms_data *data, \
26 pid_t *pid_1, pid_t *pid_2)
27{
28 int fd[2];
29
30 *pid_2 = -1;
31 if (pipe(fd) == -1)
32 return (ft_perror("pipe"));
33 *pid_1 = execute_child(node->left, data, fd, 0);
34 if (node->right != NULL)
35 *pid_2 = execute_child(node->right, data, fd, 1);
36 else
37 {
38 close(fd[1]);
39 data->std_in = fd[0];
40 return (WAIT_NEXT_COMMAND);
41 }
42 close_fds(fd[0], fd[1]);
43 return (EXIT_SUCCESS);
44}
45
46int builtin_pipe(t_ast *node, t_ms_data *data)
47{
48 pid_t pid_1;
49 pid_t pid_2;
50 int status_1;
51 int status_2;
52 int setup_result;
53
54 status_1 = 0;
55 status_2 = 0;
56 setup_result = setup_pipe_processes(node, data, &pid_1, &pid_2);
57 if (setup_result == WAIT_NEXT_COMMAND)
58 return (WAIT_NEXT_COMMAND);
59 if (pid_1 > 0 && waitpid(pid_1, &status_1, 0) == -1)
60 return (ft_perror("waitpid"));
61 if (pid_2 > 0)
62 {
63 if (waitpid(pid_2, &status_2, 0) == -1)
64 return (ft_perror("waitpid"));
65 return (WEXITSTATUS(status_2));
66 }
67 return (WEXITSTATUS(status_1));
68}
69
79pid_t execute_child(t_ast *node, t_ms_data *data, \
80 int fd[2], int direction)
81{
82 pid_t pid;
83 int status;
84
85 pid = fork();
86 if (pid == -1)
87 ft_perror("fork");
88 if (pid == 0)
89 {
90 if (direction == 0)
91 dup2(fd[1], STDOUT_FILENO);
92 else
93 dup2(fd[0], STDIN_FILENO);
94 close_fds(fd[0], fd[1]);
95 status = execute_ast(node, data);
96 exit(status);
97 }
98 return (pid);
99}
int execute_ast(t_ast *node, t_ms_data *data)
execute Abstract Syntax Tree
Definition execute.c:38
void close_fds(int in, int out)
close two file descriptors
Definition utils_0.c:28
int ft_perror(char *str)
#define EXIT_SUCCESS
Definition exit_status.h:16
pid_t execute_child(t_ast *node, t_ms_data *data, int fd[2], int direction)
execute child process in the pipe context
Definition pipe.c:79
int builtin_pipe(t_ast *node, t_ms_data *data)
Definition pipe.c:46
static int setup_pipe_processes(t_ast *node, t_ms_data *data, pid_t *pid_1, pid_t *pid_2)
Definition pipe.c:25
#define WAIT_NEXT_COMMAND
Definition pipe.h:19
Definition tokens.h:50
struct s_ast * right
Definition tokens.h:54
struct s_ast * left
Definition tokens.h:53
int std_in
Definition shell.h:26