From 0fac25fd8154ae5eb20780449ae48019be262994 Mon Sep 17 00:00:00 2001 From: mcolonna Date: Tue, 7 May 2024 14:00:26 +0200 Subject: [PATCH] [ADD] redirection '<<' --- src/parse_command.c | 54 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 4 deletions(-) diff --git a/src/parse_command.c b/src/parse_command.c index 271a47e..2d6dd3b 100644 --- a/src/parse_command.c +++ b/src/parse_command.c @@ -6,12 +6,44 @@ /* By: mcolonna +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/04/24 13:47:40 by mcolonna #+# #+# */ -/* Updated: 2024/05/02 15:15:36 by mcolonna ### ########.fr */ +/* Updated: 2024/05/07 13:59:30 by mcolonna ### ########.fr */ /* */ /* ************************************************************************** */ #include "include.h" +// Ask the user for data and set readfd to the fd which will receive this +// data. +// Returns 'errno' on error. +static int heredoc(t_memclass mc, int *readfd, const char *eof) +{ + const t_memclass mc_in = mem_subclass(fatal_error, mc); + int outpipe[2]; + t_const_string line; + const t_const_string eof_line = str_join(fatal_error, mc_in, eof, "\n"); + + if (pipe(outpipe) == -1) + minishell_error("errno"); + *readfd = outpipe[0]; + while (true) + { + print_str(fatal_error, 1, "\e[38;5;33m( 'o')> \e[0m"); + line = NULL; + while (!line) + line = read_line(fatal_error, mc_in, 0); + if (str_eq(line, eof) || str_eq(line, eof_line)) + break ; + print_str(err_remember, outpipe[1], line); + mem_free((void *)line); + if (err_get()) + return (minishell_error("errno"), errno); + } + mem_freeall(mc_in); + if (close(outpipe[1]) == -1) + return (minishell_error("errno"), errno); + return (0); +} + // To call when a parse error occurs. // Always returns 1 (parse error's status). static int parse_error(const char *msg) @@ -31,6 +63,7 @@ typedef struct s_parsing_args t_stream stream; t_list calls; bool got_first_call; // got at least the first program call? + const char *heredoc; } t_parsing_args; // Skip blank characters @@ -116,17 +149,27 @@ static int get_call(t_parsing_args *args, const char *stop_charset) static int get_inputfile(t_parsing_args *args, const char *stop_charset) { const char *str; + bool heredoc; if (args->r.input_fd != 0) return (parse_error("several input files")); if (!stream_read(&args->stream)) return (parse_error("EOF unexpected")); + heredoc = stream_read(&args->stream) == '<'; + if (heredoc) + stream_pop(&args->stream); + skip_blank(&args->stream); str = get_string(args, stop_charset); if (!str) return (parse_error("EOF unexpected")); - args->r.input_fd = open(str, O_RDONLY); - if (args->r.input_fd == -1) - return (perror(str), errno); + if (heredoc) + args->heredoc = str; + else + { + args->r.input_fd = open(str, O_RDONLY); + if (args->r.input_fd == -1) + return (perror(str), errno); + } return (0); } @@ -208,6 +251,7 @@ t_parsing_args init_parsing_args(const t_memclass mc) }, .calls = list_createempty(mc), .got_first_call = false, + .heredoc = NULL, }; return (r); @@ -237,5 +281,7 @@ t_command parse_command(const t_memclass mc, const char *command) fatal_error, args.mc, &args.calls, sizeof(t_call)); if (error) args.r.error = error; + if (args.heredoc) + heredoc(mc, &args.r.input_fd, args.heredoc); return (args.r); }