redirections WIP

This commit is contained in:
LuckyLaszlo
2021-11-14 11:05:58 +01:00
parent 1e682f796d
commit 66b48dc99d
10 changed files with 223 additions and 262 deletions

View File

@@ -6,7 +6,7 @@
/* By: lperrey <lperrey@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/10/10 23:53:17 by lperrey #+# #+# */
/* Updated: 2021/11/14 04:48:49 by lperrey ### ########.fr */
/* Updated: 2021/11/14 08:26:32 by lperrey ### ########.fr */
/* */
/* ************************************************************************** */
@@ -21,6 +21,7 @@ int free_exit(t_all *c, int exit_status)
ft_free_cmd_arr(c->cmd_arr);
if (c->termios_changed)
tcsetattr(STDIN_FILENO, TCSANOW, &c->ori_termios);
gnl(STDIN_FILENO, NULL, 1);
rl_clear_history();
exit(exit_status);
}

View File

@@ -6,7 +6,7 @@
/* By: lperrey <lperrey@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/10/08 09:25:35 by lperrey #+# #+# */
/* Updated: 2021/11/13 04:23:54 by lperrey ### ########.fr */
/* Updated: 2021/11/14 08:27:40 by lperrey ### ########.fr */
/* */
/* ************************************************************************** */
@@ -197,3 +197,16 @@ t_list *ft_lstnew_generic(size_t lst_size, size_t content_size)
elem->next = NULL;
return (elem);
}
void ft_perror_io(char *err_str, char *io_file)
{
ft_putstr_fd(err_str, 2);
perror(io_file);
}
int ft_reti_perror_io(int ret, char *err_str, char *io_file)
{
ft_putstr_fd(err_str, 2);
perror(io_file);
return (ret);
}

View File

@@ -6,7 +6,7 @@
/* By: lperrey <lperrey@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/11/13 04:35:06 by lperrey #+# #+# */
/* Updated: 2021/11/13 10:18:51 by lperrey ### ########.fr */
/* Updated: 2021/11/14 06:01:45 by lperrey ### ########.fr */
/* */
/* ************************************************************************** */
@@ -20,6 +20,7 @@ enum e_in_quote_state
};
static int quote_state_change(int *quote_state, const char *s);
/* Duplicate a string minus the quoting characters ['] and ["]*/
char *ft_strdup_quotes(const char *s)
{
unsigned int i;

View File

@@ -6,7 +6,7 @@
/* By: lperrey <lperrey@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/11/07 02:01:33 by lperrey #+# #+# */
/* Updated: 2021/11/13 21:27:20 by lperrey ### ########.fr */
/* Updated: 2021/11/14 10:13:38 by lperrey ### ########.fr */
/* */
/* ************************************************************************** */
@@ -22,8 +22,6 @@ enum e_in_quote_state
t_list *ft_lstnew_generic(size_t lst_sizse, size_t content_size);
t_list *expand_token(char *content);
char *rejoin_after_expand(t_list *expand_lst);
char **ft_split_quotes(char const *s, char c); // Generic
char *ft_strdup_quotes(const char *s); // Generic
int new_token_for_each_field(char **fields, t_token **t);
// 1 - chaque bout dans un element d'une t_list
@@ -35,39 +33,43 @@ int new_token_for_each_field(char **fields, t_token **t);
// (ft_lstadd_front() sur le token original, puis set le token orignal à :
// t->id = 0 ; free(t->content) ; t->content = NULL ; pour qu'il soit ignoré sur la suite du parsing)
int words_expansions(t_token *t)
int words_expansions(t_token *token_list)
{
void *tmp_expand;
char **tmp_split;
while (t)
while (token_list)
{
if (t->id == T_WORD)
{
// 1
tmp_expand = expand_token(t->content);
if (!tmp_expand)
return (0);
// 2
tmp_expand = rejoin_after_expand(tmp_expand);
if (!tmp_expand)
return (0);
// 3
tmp_split = ft_split_quotes(tmp_expand, ' ');
free(tmp_expand);
if (!tmp_split)
return (0);
// 4
tmp_expand = ft_dup_2d_arr(tmp_split, (t_dup_func)ft_strdup_quotes);
ft_free_2d_arr(tmp_split);
tmp_split = tmp_expand;
if (!tmp_split)
return (0);
// 5
if (!new_token_for_each_field(tmp_split, &t))
return (0);
}
t = t->next;
if (token_list->id == T_WORD)
token_expansions(&token_list);
token_list = token_list->next;
}
return (1);
}
int token_expansions(t_token **t)
{
void *tmp;
char **tmp_split;
// 1
tmp = expand_token((*t)->content);
if (!tmp)
return (0);
// 2
tmp = rejoin_after_expand(tmp);
if (!tmp)
return (0);
// 3
tmp_split = ft_split_quotes(tmp, ' ');
free(tmp);
if (!tmp_split)
return (0);
// 4
tmp = ft_dup_2d_arr(tmp_split, (t_dup_func)ft_strdup_quotes);
ft_free_2d_arr(tmp_split);
tmp_split = tmp;
if (!tmp_split)
return (0);
// 5
if (!new_token_for_each_field(tmp_split, t))
return (0);
return (1);
}

View File

@@ -6,7 +6,7 @@
/* By: lperrey <lperrey@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/10/24 10:52:40 by lperrey #+# #+# */
/* Updated: 2021/11/14 00:35:42 by lperrey ### ########.fr */
/* Updated: 2021/11/14 11:00:39 by lperrey ### ########.fr */
/* */
/* ************************************************************************** */
@@ -69,8 +69,8 @@ t_cmd **parsing(t_token *token_list)
return (NULL);
// 2.9.1 - 3) Redirection
/* if (!redirections(token_list, cmd_arr))
return (ft_retp_free(NULL, cmd_arr, ft_free_cmd_arr)); */
if (!redirections(token_list, cmd_arr))
return (ft_retp_free(NULL, cmd_arr, (void(*)(void *))ft_free_cmd_arr));
// Struct CMD fill

View File

@@ -0,0 +1,102 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* here_doc.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lperrey <lperrey@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/11/11 18:46:43 by lperrey #+# #+# */
/* Updated: 2021/11/14 10:58:37 by lperrey ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
#define TMP_HERE_DOC "/tmp/minishell_here_doc"
static int here_doc_write(char *delimiter, int doc_fd);
int here_doc(char *delimiter)
{
// https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_07_04
// https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_02
/* If any part of word is quoted,
the delimiter shall be formed by performing quote removal on word,
and the here-document lines shall not be expanded.
Otherwise, the delimiter shall be the word itself. */
// TODO : A voir si on fait les expansions de variables dans le here_doc.
// implementer une gestion des signaux pour here_doc (actuellement ça leaks).
// Peut-être remplacer gnl() par readline() pour avoir une gestion correct
// du terminal (actuellement l'affichage lors du changement de ligne est foireux).
int here_doc;
delimiter = ft_strdup_quotes(delimiter);
if (!delimiter)
return (ft_reti_perror(-1, "ft_strdup_quotes()"));
here_doc = open(TMP_HERE_DOC, O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU);
if (here_doc == -1)
return (ft_reti_perror_io(-1, "open() ", TMP_HERE_DOC));
if (!here_doc_write(delimiter, here_doc))
{
gnl(STDIN_FILENO, NULL, 1);
return (0);
}
if (close(here_doc) == -1)
ft_perror_io("close() ", TMP_HERE_DOC);
here_doc = open(TMP_HERE_DOC, O_RDONLY);
if (here_doc == -1)
ft_perror_io("open() ", TMP_HERE_DOC);
if (unlink(TMP_HERE_DOC) == -1)
return (ft_reti_perror_io(-1, "unlink() ", TMP_HERE_DOC));
return (here_doc);
}
static int here_doc_write(char *delimiter, int doc_fd)
{
char *line;
while (1)
{
line = NULL;
if (gnl(STDIN_FILENO, &line, 0) == -1)
return (ft_reti_perror_free(0, line, free, "gnl() STDIN"));
if (ft_strncmp(line, delimiter, ft_strlen(line) + 1) == 0) // Ou ft_strlen(delimiter) + 1 ? Ça devrais être identique et ça peux se calculer une seul fois.
break ;
if (write(doc_fd, line, ft_strlen(line)) == -1)
return (ft_reti_perror_free(0, line, free, "write() "TMP_HERE_DOC));
if (write(doc_fd, "\n", 1) == -1)
return (ft_reti_perror_free(0, line, free, "write() "TMP_HERE_DOC));
free(line);
}
free(line);
gnl(STDIN_FILENO, NULL, 1);
return (1);
}
/*
static int here_doc_write(char *delimiter, int doc_fd)
{
char *line;
int ret;
line = NULL;
ret = 1;
while (ret)
{
ret = gnl(STDIN_FILENO, &line, 0);
if (ret == -1)
return (ft_reti_perror_free(0, line, free, "gnl() STDIN"));
if (ft_strncmp(line, delimiter, ft_strlen(line) + 1) == 0) // Ou ft_strlen(delimiter) + 1 ? Ça devrais être identique et ça peux se calculer une seul fois.
break ;
if (write(doc_fd, line, ft_strlen(line)) == -1)
return (ft_reti_perror_free(0, line, free, "write() "TMP_HERE_DOC));
if (write(doc_fd, "\n", 1) == -1)
return (ft_reti_perror_free(0, line, free, "write() "TMP_HERE_DOC));
free(line);
line = NULL;
}
free(line);
gnl(STDIN_FILENO, NULL, 1);
return (1);
}
*/

View File

@@ -6,74 +6,16 @@
/* By: lperrey <lperrey@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/11/11 18:46:43 by lperrey #+# #+# */
/* Updated: 2021/11/12 20:17:09 by lperrey ### ########.fr */
/* Updated: 2021/11/14 10:04:21 by lperrey ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
int ft_reti_perror_io(int ret, char *err_str, char *io_file) // generic
{
ft_putstr_fd(err_str, 2);
perror(io_file);
return (ret);
}
int here_doc(char *delimiter);
int here_doc_handle_PLACEHOLDER(char *delimiter)
{
// https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_07_04
// https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_02
/* If any part of word is quoted,
the delimiter shall be formed by performing quote removal on word,
and the here-document lines shall not be expanded.
Otherwise, the delimiter shall be the word itself. */
// Pas d'expansion sur le delimiter, mais quote removal tout de même.
// TODO : quote removal sur le delimiter.
QUOTE_REMOVAL_PLACEHOLDER();
}
int redirect_cmd_input(t_token *t, t_cmd *cmd)
{
if (cmd->fd_in != STDIN_FILENO && cmd->fd_in > 0)
if (close(cmd->fd_in) == -1)
perror("close()");
if (t->id == '<')
{
// TODO : Expansion + quote removal sur le word t->next->content.
// si plus d'un champ ou aucun champ aprés expansion,
// message d'erreur comme bash "bash: $VAR: ambiguous redirect"
// OU prise en compte seulement du premier champ.
EXPAND_AND_QUOTE_REMOVAL_PLACEHOLDER();
cmd->fd_in = open(t->next->content, O_RDONLY);
if (cmd->fd_in == -1)
ft_reti_perror_io(0, "open() ", t->next->content);
}
else if (t->id == T_DLESS)
cmd->fd_in = here_doc_handle_PLACEHOLDER(t->next->content); // TODO
return (1);
}
int redirect_cmd_output(t_token *t, t_cmd *cmd)
{
int flags;
if (cmd->fd_out != STDOUT_FILENO && cmd->fd_out > 0)
if (close(cmd->fd_out) == -1)
perror("close()");
// TODO : Expansion + quote removal sur le word t->next->content.
// si plus d'un champ ou aucun champ aprés expansion,
// message d'erreur comme bash "bash: $VAR: ambiguous redirect"
// OU prise en compte seulement du premier champ.
EXPAND_AND_QUOTE_REMOVAL_PLACEHOLDER();
if (t->id == '>')
flags = O_WRONLY | O_CREAT | O_TRUNC;
else if (t->id == T_DGREAT)
flags = O_WRONLY | O_CREAT | O_APPEND;
cmd->fd_out = open(t->next->content, flags, S_IRWXU);
if (cmd->fd_out == -1)
return (ft_reti_perror_io(0, "open() ", t->next->content));
return (1);
}
static int redirect_cmd_input(t_token *t, t_cmd *cmd);
static int redirect_cmd_output(t_token *t, t_cmd *cmd);
int redirections(t_token *t, t_cmd **cmd_arr)
{
@@ -98,3 +40,51 @@ int redirections(t_token *t, t_cmd **cmd_arr)
}
return (1);
}
static int redirect_cmd_input(t_token *t, t_cmd *cmd)
{
if (cmd->fd_in != STDIN_FILENO && cmd->fd_in > 0)
if (close(cmd->fd_in) == -1)
perror("close()");
if (t->id == '<')
{
// TODO : Expansion + quote removal sur le word t->next->content.
// si plus d'un champ ou aucun champ aprés expansion,
// message d'erreur comme bash "bash: $VAR: ambiguous redirect"
// OU prise en compte seulement du premier champ.
//EXPAND_AND_QUOTE_REMOVAL_PLACEHOLDER();
cmd->fd_in = open(t->next->content, O_RDONLY);
if (cmd->fd_in == -1)
ft_perror_io("open() ", t->next->content);
}
else if (t->id == T_DLESS)
{
cmd->fd_in = here_doc(t->next->content);
if (cmd->fd_in == -1)
return (ft_reti_print(0, "minishell: heredoc error\n", 2));
}
return (1);
}
static int redirect_cmd_output(t_token *t, t_cmd *cmd)
{
int flags;
if (cmd->fd_out != STDOUT_FILENO && cmd->fd_out > 0)
if (close(cmd->fd_out) == -1)
perror("close()");
// TODO : Expansion + quote removal sur le word t->next->content.
// si plus d'un champ ou aucun champ aprés expansion,
// message d'erreur comme bash "bash: $VAR: ambiguous redirect"
// OU prise en compte seulement du premier champ.
//EXPAND_AND_QUOTE_REMOVAL_PLACEHOLDER();
flags = O_WRONLY | O_CREAT;
if (t->id == '>')
flags = flags | O_TRUNC;
else if (t->id == T_DGREAT)
flags = flags | O_APPEND;
cmd->fd_out = open(t->next->content, flags, S_IRWXU);
if (cmd->fd_out == -1)
return (ft_reti_perror_io(0, "open() ", t->next->content));
return (1);
}