MiniDevil As beautiful as a shell
heredoc_collect.c
Go to the documentation of this file.
1 /* ************************************************************************** */
2 /* */
3 /* ::: :::::::: */
4 /* heredoc_collect.c :+: :+: :+: */
5 /* +:+ +:+ +:+ */
6 /* By: baelgadi <baelgadi@student.42.fr> +#+ +:+ +#+ */
7 /* +#+#+#+#+#+ +#+ */
8 /* Created: 2026/02/21 07:43:01 by baelgadi #+# #+# */
9 /* Updated: 2026/03/04 07:22:52 by baelgadi ### ########.fr */
10 /* */
11 /* ************************************************************************** */
12 
13 #include "executor.h"
14 #include "libft.h"
15 
26 static int collect_one(t_ast *node, t_shell *shell)
27 {
28  int fd;
29 
30  fd = handle_heredoc(node->data.redir.file, node->data.redir.quote, shell);
31  if (fd == -1)
32  return (-1);
33  node->data.redir.heredoc_fd = fd;
34  return (0);
35 }
36 
47 static int walk_redir(t_ast *node, t_shell *shell)
48 {
49  if (node->type == NODE_REDIR_HEREDOC)
50  {
51  if (collect_one(node, shell) == -1)
52  return (-1);
53  }
54  if (node->data.redir.cmd)
55  return (walk_heredocs(node->data.redir.cmd, shell));
56  return (0);
57 }
58 
64 static void close_heredoc_fds(t_ast *node)
65 {
66  if (!node)
67  return ;
68  if (node->type == NODE_PIPE)
69  {
72  }
73  else if (node->type >= NODE_REDIR_IN && node->type <= NODE_REDIR_HEREDOC)
74  {
75  if (node->type == NODE_REDIR_HEREDOC
76  && node->data.redir.heredoc_fd >= 0)
77  {
78  close(node->data.redir.heredoc_fd);
79  node->data.redir.heredoc_fd = -1;
80  }
82  }
83 }
84 
95 int walk_heredocs(t_ast *node, t_shell *shell)
96 {
97  if (!node)
98  return (0);
99  if (node->type == NODE_PIPE)
100  {
101  if (walk_heredocs(node->data.binary.left, shell) == -1)
102  return (-1);
103  return (walk_heredocs(node->data.binary.right, shell));
104  }
105  if (node->type >= NODE_REDIR_IN && node->type <= NODE_REDIR_HEREDOC)
106  return (walk_redir(node, shell));
107  return (0);
108 }
109 
120 int collect_heredocs(t_ast *node, t_shell *shell)
121 {
122  if (walk_heredocs(node, shell) == -1)
123  {
124  close_heredoc_fds(node);
125  return (-1);
126  }
127  return (0);
128 }
Executor prototypes for commands, pipes, redirections & heredocs.
int handle_heredoc(char *delimiter, int quoted, t_shell *shell)
Execute a heredoc (read input and return a readable fd)
Definition: heredoc.c:133
int walk_heredocs(t_ast *node, t_shell *shell)
Recursively walk the AST collecting all heredocs.
static int collect_one(t_ast *node, t_shell *shell)
Collect a single heredoc content into a pipe fd.
static int walk_redir(t_ast *node, t_shell *shell)
Process a redirection node (and collecting heredoc if applicable)
int collect_heredocs(t_ast *node, t_shell *shell)
Pre collect all heredocs in the AST before the execution phase.
static void close_heredoc_fds(t_ast *node)
Recursively close cached heredoc file descriptors in the AST.
@ NODE_REDIR_HEREDOC
Definition: structs.h:57
@ NODE_PIPE
Definition: structs.h:53
@ 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
struct s_ast * left
left child (before pipe)
Definition: structs.h:124
struct s_ast * right
right child (after pipe)
Definition: structs.h:125
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
int quote
1 if delimiter was quoted
Definition: structs.h:115
Shell state.
Definition: structs.h:164
t_binary_node binary
Definition: structs.h:143
t_redir_node redir
Definition: structs.h:142