MiniDevil As beautiful as a shell
execute.c
Go to the documentation of this file.
1 /* ************************************************************************** */
2 /* */
3 /* ::: :::::::: */
4 /* execute.c :+: :+: :+: */
5 /* +:+ +:+ +:+ */
6 /* By: baelgadi <baelgadi@student.42.fr> +#+ +:+ +#+ */
7 /* +#+#+#+#+#+ +#+ */
8 /* Created: 2026/02/17 17:49:19 by zotaj-di #+# #+# */
9 /* Updated: 2026/03/04 05:02:51 by baelgadi ### ########.fr */
10 /* */
11 /* ************************************************************************** */
12 
13 #include <sys/wait.h>
14 #include <fcntl.h>
15 #include "minishell_ui.h"
16 #include "env.h"
17 #include "get_next_line.h"
18 
29 static int init_pipe_and_fds(int *pipe_fd, int *saved_fds, t_ui *ui)
30 {
31  if (pipe(pipe_fd) == -1)
32  {
33  out_add_line(&ui->out, "Error: pipe creation failed");
34  ui->out.exit_code = 1;
36  return (-1);
37  }
38  saved_fds[0] = dup(STDOUT_FILENO);
39  saved_fds[1] = dup(STDERR_FILENO);
40  return (0);
41 }
42 
50 static void handle_fork_error(t_ui *ui, int *pipe_fd, int *saved_fds)
51 {
52  close(pipe_fd[0]);
53  close(pipe_fd[1]);
54  close(saved_fds[0]);
55  close(saved_fds[1]);
56  out_add_line(&ui->out, "Error: fork failed");
57  ui->out.exit_code = 1;
59 }
60 
71 static void exec_child(int *pipe_fd, int *saved_fds, t_shell *shell)
72 {
73  int status;
74  int dev_null;
75 
76  close(pipe_fd[0]);
77  close(saved_fds[0]);
78  close(saved_fds[1]);
79  dev_null = open("/dev/null", O_RDONLY);
80  if (dev_null >= 0)
81  {
82  dup2(dev_null, STDIN_FILENO);
83  close(dev_null);
84  }
85  dup2(pipe_fd[1], STDOUT_FILENO);
86  dup2(pipe_fd[1], STDERR_FILENO);
87  close(pipe_fd[1]);
88  status = process_ui_input(shell->ui->cmd.buf, shell);
89  out_free(&shell->ui->out);
90  free(shell->ui);
91  free_env_list(&shell->env);
92  get_next_line(-42);
93  exit(status);
94 }
95 
107 static void exec_parent(int *pipe_fd, int *saved_fds, t_shell *sh, pid_t pid)
108 {
109  int status;
110 
111  close(pipe_fd[1]);
112  read_output_from_fd(sh->ui, pipe_fd[0]);
113  close(pipe_fd[0]);
114  dup2(saved_fds[0], STDOUT_FILENO);
115  dup2(saved_fds[1], STDERR_FILENO);
116  close(saved_fds[0]);
117  close(saved_fds[1]);
118  waitpid(pid, &status, 0);
119  if (WIFEXITED(status))
120  sh->ui->out.exit_code = WEXITSTATUS(status);
121  else
122  sh->ui->out.exit_code = 1;
123  if (sh->ui->out.exit_code == 0)
125  else
127 }
128 
138 {
139  int pipe_fd[2];
140  int saved_fds[2];
141  pid_t pid;
142 
143  if (!shell || !shell->ui)
144  return ;
146  if (init_pipe_and_fds(pipe_fd, saved_fds, shell->ui) == -1)
147  return ;
148  pid = fork();
149  if (pid == -1)
150  {
151  handle_fork_error(shell->ui, pipe_fd, saved_fds);
152  return ;
153  }
154  if (pid == 0)
155  exec_child(pipe_fd, saved_fds, shell);
156  else
157  exec_parent(pipe_fd, saved_fds, shell, pid);
158 }
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
static void handle_fork_error(t_ui *ui, int *pipe_fd, int *saved_fds)
Clean up after a failed fork & report the error to the UI.
Definition: execute.c:50
static void exec_child(int *pipe_fd, int *saved_fds, t_shell *shell)
Redirect I/O to the pipe and run the command.
Definition: execute.c:71
static int init_pipe_and_fds(int *pipe_fd, int *saved_fds, t_ui *ui)
Create a pipe and save current STDOUT / STDERR file descriptors.
Definition: execute.c:29
void execute_minishell_cmd(t_shell *shell)
Fork a child to execute a minishell command & capture its output.
Definition: execute.c:137
static void exec_parent(int *pipe_fd, int *saved_fds, t_shell *sh, pid_t pid)
Collect output, restore I/O and wait for child.
Definition: execute.c:107
int process_ui_input(char *input, t_shell *shell)
Full pipeline inside the UI.
Definition: execute_utils.c:88
void read_output_from_fd(t_ui *ui, int fd)
Read all available bytes from fd and split into output lines.
Definition: execute_utils.c:53
UI mode structures, macros & function prototypes.
#define MOOD_HAPPY
Definition: minishell_ui.h:103
#define MOOD_UPSET
Definition: minishell_ui.h:104
#define MOOD_PROUD
Definition: minishell_ui.h:105
void out_free(t_out *out)
Clear all output lines and free the lines pointer array.
Definition: output.c:57
void out_add_line(t_out *out, const char *line)
Append a duplicate of a line to the output buffer.
Definition: output.c:23
int exit_code
Last command exit code.
Definition: minishell_ui.h:151
Shell state.
Definition: structs.h:164
t_env * env
Environment linked list.
Definition: structs.h:165
struct s_ui * ui
UI state (NULL if off)
Definition: structs.h:170
UI state.
Definition: minishell_ui.h:167
t_out out
Output state.
Definition: minishell_ui.h:170
void update_waifu_mood(t_ui *ui, int mood)
Set the waifu mood.
Definition: waifu.c:21