MiniDevil As beautiful as a shell
heredoc.c
Go to the documentation of this file.
1 /* ************************************************************************** */
2 /* */
3 /* ::: :::::::: */
4 /* heredoc.c :+: :+: :+: */
5 /* +:+ +:+ +:+ */
6 /* By: baelgadi <baelgadi@student.42.fr> +#+ +:+ +#+ */
7 /* +#+#+#+#+#+ +#+ */
8 /* Created: 2025/12/12 21:58:03 by baelgadi #+# #+# */
9 /* Updated: 2026/03/09 23:26:19 by baelgadi ### ########.fr */
10 /* */
11 /* ************************************************************************** */
12 
13 #include <readline/readline.h>
14 #include <stdio.h>
15 #include "executor.h"
16 #include "token.h"
17 #include "env.h"
18 #include "signals.h"
19 #include "libft.h"
20 #include "get_next_line.h"
21 
30 static void write_heredoc_line(int fd, char *line, t_shell *shell, int expand)
31 {
32  char *expanded;
33 
34  if (expand && line)
35  {
36  expanded = expand_variables(line, shell->env, QUOTE_NONE,
37  shell->exit_status);
38  ft_putendl_fd(expanded, fd);
39  free(expanded);
40  }
41  else
42  ft_putendl_fd(line, fd);
43 }
44 
52 static char *read_heredoc_line(void)
53 {
54  char *line;
55  size_t len;
56 
57  if (isatty(STDIN_FILENO))
58  return (readline("> "));
59  line = get_next_line(STDIN_FILENO);
60  if (!line)
61  return (NULL);
62  len = ft_strlen(line);
63  if (len > 0 && line[len - 1] == '\n')
64  line[len - 1] = '\0';
65  return (line);
66 }
67 
73 static void print_heredoc_eof_error(char *delim)
74 {
75  ft_putstr_fd("minishell: warning: here_document delimited by", 2);
76  ft_putstr_fd(" end-of-file (wanted `", 2);
77  ft_putstr_fd(delim, 2);
78  ft_putstr_fd("')\n", 2);
79 }
80 
92 static int read_heredoc_lines(int fd, char *delim, t_shell *shell, int expand)
93 {
94  char *line;
95 
96  while (1)
97  {
98  line = read_heredoc_line();
99  if (g_signal == SIGINT)
100  {
101  free(line);
102  return (1);
103  }
104  if (!line)
105  {
107  return (0);
108  }
109  if (!ft_strncmp(line, delim, -1))
110  {
111  free(line);
112  return (0);
113  }
114  write_heredoc_line(fd, line, shell, expand);
115  free(line);
116  }
117 }
118 
133 int handle_heredoc(char *delimiter, int quoted, t_shell *shell)
134 {
135  int pipe_fd[2];
136  int expand;
137  int interrupted;
138 
139  expand = !quoted;
140  if (pipe(pipe_fd) == -1)
141  return (perror("minishell: pipe"), -1);
143  g_signal = 0;
144  interrupted = read_heredoc_lines(pipe_fd[1], delimiter, shell, expand);
146  close(pipe_fd[1]);
147  if (interrupted)
148  {
149  close(pipe_fd[0]);
150  restore_stdin();
151  return (-1);
152  }
153  return (pipe_fd[0]);
154 }
Environment variable management prototypes.
Executor prototypes for commands, pipes, redirections & heredocs.
char * expand_variables(char *str, t_env *env_list, t_quote_type quote_type, int exit_status)
Expand all $VARIABLE in a string.
Definition: expander.c:111
int handle_heredoc(char *delimiter, int quoted, t_shell *shell)
Execute a heredoc (read input and return a readable fd)
Definition: heredoc.c:133
static void print_heredoc_eof_error(char *delim)
Print an EOF warning for an unterminated heredoc (bash style)
Definition: heredoc.c:73
static char * read_heredoc_line(void)
Read a line from STDIN.
Definition: heredoc.c:52
static void write_heredoc_line(int fd, char *line, t_shell *shell, int expand)
Write one heredoc line (optionally expanding variables)
Definition: heredoc.c:30
static int read_heredoc_lines(int fd, char *delim, t_shell *shell, int expand)
Read the lines until the delimiter or EOF/SIGINT.
Definition: heredoc.c:92
void restore_stdin(void)
Restore STDIN after heredoc SIGINT closed it.
void setup_heredoc_signals(void)
Configure signals for heredoc.
volatile sig_atomic_t g_signal
The single global variable.
Definition: signals.c:17
void setup_interactive_signals(void)
Configure signals for the interactive prompt.
Definition: signals.c:43
Signal handler prototypes.
@ QUOTE_NONE
Definition: structs.h:42
Shell state.
Definition: structs.h:164
t_env * env
Environment linked list.
Definition: structs.h:165
int exit_status
Last command's exit status.
Definition: structs.h:166
Lexer, tokenizer, expander, and quote handling prototypes.