MiniDevil As beautiful as a shell
executor_redir.c
Go to the documentation of this file.
1 /* ************************************************************************** */
2 /* */
3 /* ::: :::::::: */
4 /* executor_redir.c :+: :+: :+: */
5 /* +:+ +:+ +:+ */
6 /* By: baelgadi <baelgadi@student.42.fr> +#+ +:+ +#+ */
7 /* +#+#+#+#+#+ +#+ */
8 /* Created: 2025/12/17 18:56:14 by zotaj-di #+# #+# */
9 /* Updated: 2026/03/04 04:50:27 by baelgadi ### ########.fr */
10 /* */
11 /* ************************************************************************** */
12 
13 #include <fcntl.h>
14 #include <stdio.h>
15 #include "executor.h"
16 #include "libft.h"
17 
30 int open_redir_file(char *file, t_node_type type)
31 {
32  int fd;
33 
34  fd = -1;
35  if (type == NODE_REDIR_IN)
36  fd = open(file, O_RDONLY);
37  else if (type == NODE_REDIR_OUT)
38  fd = open(file, O_WRONLY | O_CREAT | O_TRUNC, 0644);
39  else if (type == NODE_REDIR_APPEND)
40  fd = open(file, O_WRONLY | O_CREAT | O_APPEND, 0644);
41  if (fd == -1)
42  {
43  ft_putstr_fd("minishell: ", STDERR_FILENO);
44  perror(file);
45  }
46  return (fd);
47 }
48 
59 int setup_redirection(int fd, t_node_type type)
60 {
61  int saved_fd;
62  int target;
63 
64  if (type == NODE_REDIR_IN || type == NODE_REDIR_HEREDOC)
65  target = STDIN_FILENO;
66  else
67  target = STDOUT_FILENO;
68  saved_fd = dup(target);
69  if (saved_fd == -1)
70  {
71  perror("minishell: error on dup");
72  return (-1);
73  }
74  if (dup2(fd, target) == -1)
75  {
76  close(saved_fd);
77  perror("minishell: error on dup2");
78  return (-1);
79  }
80  close(fd);
81  return (saved_fd);
82 }
83 
90 void restore_fd(int saved_fd, t_node_type type)
91 {
92  int target;
93 
94  if (saved_fd == -1)
95  return ;
96  if (type == NODE_REDIR_IN || type == NODE_REDIR_HEREDOC)
97  target = STDIN_FILENO;
98  else
99  target = STDOUT_FILENO;
100  dup2(saved_fd, target);
101  close(saved_fd);
102 }
103 
117 int handle_redir(t_ast *node, t_shell *shell)
118 {
119  t_redir_node *redir;
120  int fd;
121  int saved_fd;
122  int status;
123 
124  redir = &node->data.redir;
125  if (node->type == NODE_REDIR_HEREDOC && redir->heredoc_fd >= 0)
126  {
127  fd = redir->heredoc_fd;
128  redir->heredoc_fd = -1;
129  }
130  else
131  fd = open_redir_file(redir->file, node->type);
132  if (fd == -1)
133  return (1);
134  saved_fd = setup_redirection(fd, node->type);
135  if (saved_fd == -1)
136  {
137  close(fd);
138  return (1);
139  }
140  status = executor(redir->cmd, shell);
141  restore_fd(saved_fd, node->type);
142  return (status);
143 }
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.
int setup_redirection(int fd, t_node_type type)
Redirect STDIN or STDOUT to fd, saving the original.
int open_redir_file(char *file, t_node_type type)
Open a file for redirection (based on the redirection type)
int handle_redir(t_ast *node, t_shell *shell)
Execute a redirection node.
void restore_fd(int saved_fd, t_node_type type)
Restore a previously saved file descriptor.
t_node_type
AST node types.
Definition: structs.h:51
@ NODE_REDIR_HEREDOC
Definition: structs.h:57
@ NODE_REDIR_APPEND
Definition: structs.h:56
@ NODE_REDIR_OUT
Definition: structs.h:55
@ NODE_REDIR_IN
Definition: structs.h:54
AST node (union based ↑)
Definition: structs.h:151
t_ast_data data
cmd, redir or binary data
Definition: structs.h:153
t_node_type type
To determine which union member to pick.
Definition: structs.h:152
Redirection data inside AST node.
Definition: structs.h:111
int heredoc_fd
Heredoc pipe fd (-1 if not used)
Definition: structs.h:116
char * file
Target filename or delimiter.
Definition: structs.h:112
struct s_ast * cmd
Command subtree.
Definition: structs.h:113
Shell state.
Definition: structs.h:164
t_redir_node redir
Definition: structs.h:142