[ADD] redirection '<<'
This commit is contained in:
parent
c86126ec9d
commit
0fac25fd81
1 changed files with 50 additions and 4 deletions
|
@ -6,12 +6,44 @@
|
||||||
/* By: mcolonna <marvin@42.fr> +#+ +:+ +#+ */
|
/* By: mcolonna <marvin@42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2024/04/24 13:47:40 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"
|
#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.
|
// To call when a parse error occurs.
|
||||||
// Always returns 1 (parse error's status).
|
// Always returns 1 (parse error's status).
|
||||||
static int parse_error(const char *msg)
|
static int parse_error(const char *msg)
|
||||||
|
@ -31,6 +63,7 @@ typedef struct s_parsing_args
|
||||||
t_stream stream;
|
t_stream stream;
|
||||||
t_list calls;
|
t_list calls;
|
||||||
bool got_first_call; // got at least the first program call?
|
bool got_first_call; // got at least the first program call?
|
||||||
|
const char *heredoc;
|
||||||
} t_parsing_args;
|
} t_parsing_args;
|
||||||
|
|
||||||
// Skip blank characters
|
// 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)
|
static int get_inputfile(t_parsing_args *args, const char *stop_charset)
|
||||||
{
|
{
|
||||||
const char *str;
|
const char *str;
|
||||||
|
bool heredoc;
|
||||||
|
|
||||||
if (args->r.input_fd != 0)
|
if (args->r.input_fd != 0)
|
||||||
return (parse_error("several input files"));
|
return (parse_error("several input files"));
|
||||||
if (!stream_read(&args->stream))
|
if (!stream_read(&args->stream))
|
||||||
return (parse_error("EOF unexpected"));
|
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);
|
str = get_string(args, stop_charset);
|
||||||
if (!str)
|
if (!str)
|
||||||
return (parse_error("EOF unexpected"));
|
return (parse_error("EOF unexpected"));
|
||||||
|
if (heredoc)
|
||||||
|
args->heredoc = str;
|
||||||
|
else
|
||||||
|
{
|
||||||
args->r.input_fd = open(str, O_RDONLY);
|
args->r.input_fd = open(str, O_RDONLY);
|
||||||
if (args->r.input_fd == -1)
|
if (args->r.input_fd == -1)
|
||||||
return (perror(str), errno);
|
return (perror(str), errno);
|
||||||
|
}
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,6 +251,7 @@ t_parsing_args init_parsing_args(const t_memclass mc)
|
||||||
},
|
},
|
||||||
.calls = list_createempty(mc),
|
.calls = list_createempty(mc),
|
||||||
.got_first_call = false,
|
.got_first_call = false,
|
||||||
|
.heredoc = NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
return (r);
|
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));
|
fatal_error, args.mc, &args.calls, sizeof(t_call));
|
||||||
if (error)
|
if (error)
|
||||||
args.r.error = error;
|
args.r.error = error;
|
||||||
|
if (args.heredoc)
|
||||||
|
heredoc(mc, &args.r.input_fd, args.heredoc);
|
||||||
return (args.r);
|
return (args.r);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue