feat(redir): fieldsplit redir target, and handle ambiguous redirects

This commit is contained in:
Khaïs COLIN 2025-04-21 08:25:49 +02:00
parent 5de82f2940
commit ce8e06f665
10 changed files with 136 additions and 12 deletions

View file

@ -96,6 +96,7 @@ srcs = \
src/postprocess/expansion/expand_vars.c \ src/postprocess/expansion/expand_vars.c \
src/postprocess/expansion/expand_wildcard.c \ src/postprocess/expansion/expand_wildcard.c \
src/postprocess/fieldsplit/fieldsplit.c \ src/postprocess/fieldsplit/fieldsplit.c \
src/postprocess/fieldsplit/redirect_fieldsplit.c \
src/sig/sig.c \ src/sig/sig.c \
src/sig/sig_handlers.c \ src/sig/sig_handlers.c \
src/subst/path_split.c \ src/subst/path_split.c \

View file

@ -6,7 +6,7 @@
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */ /* By: khais <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2025/03/27 16:21:56 by khais #+# #+# */ /* Created: 2025/03/27 16:21:56 by khais #+# #+# */
/* Updated: 2025/04/18 14:03:39 by khais ### ########.fr */ /* Updated: 2025/04/21 08:45:05 by khais ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -44,7 +44,10 @@ static t_simple_cmd *post_process_command(t_simple_cmd *cmd, t_minishell *app)
if (simple_cmd_expand_vars(cmd, app) == NULL) if (simple_cmd_expand_vars(cmd, app) == NULL)
return (NULL); return (NULL);
if (simple_cmd_fieldsplit(cmd) == NULL) if (simple_cmd_fieldsplit(cmd) == NULL)
{
app->last_return_value = 1;
return (NULL); return (NULL);
}
if (simple_cmd_expand_wildcards(cmd) == NULL) if (simple_cmd_expand_wildcards(cmd) == NULL)
return (NULL); return (NULL);
if (simple_cmd_remove_quotes(cmd) == NULL) if (simple_cmd_remove_quotes(cmd) == NULL)

View file

@ -6,7 +6,7 @@
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */ /* By: khais <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2025/04/09 14:02:47 by khais #+# #+# */ /* Created: 2025/04/09 14:02:47 by khais #+# #+# */
/* Updated: 2025/04/17 11:08:59 by khais ### ########.fr */ /* Updated: 2025/04/21 10:59:33 by khais ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -43,6 +43,8 @@ typedef struct s_redirect
int open_flags; int open_flags;
int c_flags; // flags for third arg of open (case O_CREAT). int c_flags; // flags for third arg of open (case O_CREAT).
t_redirectee redirectee; // fd or filename where to redirect source. t_redirectee redirectee; // fd or filename where to redirect source.
// used between var expansion and fieldsplit
char *unexpanded_filename;
char *here_doc_eof; // The here-document limiter if relevant. char *here_doc_eof; // The here-document limiter if relevant.
} t_redirect; } t_redirect;

View file

@ -6,7 +6,7 @@
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */ /* By: khais <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2025/04/09 16:53:02 by khais #+# #+# */ /* Created: 2025/04/09 16:53:02 by khais #+# #+# */
/* Updated: 2025/04/17 10:20:38 by khais ### ########.fr */ /* Updated: 2025/04/21 10:55:02 by khais ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -25,6 +25,7 @@ void redirect_destroy(t_redirect *redirect)
free(redirect->here_doc_eof); free(redirect->here_doc_eof);
if (redirect->type != FT_HEREDOC) if (redirect->type != FT_HEREDOC)
worddesc_destroy(redirect->redirectee.filename); worddesc_destroy(redirect->redirectee.filename);
free(redirect->unexpanded_filename);
free(redirect); free(redirect);
redirect = next; redirect = next;
} }

View file

@ -6,7 +6,7 @@
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */ /* By: khais <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2025/04/01 13:34:51 by khais #+# #+# */ /* Created: 2025/04/01 13:34:51 by khais #+# #+# */
/* Updated: 2025/04/21 08:15:45 by khais ### ########.fr */ /* Updated: 2025/04/21 11:09:04 by khais ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -14,23 +14,23 @@
#include "../../ft_errno.h" #include "../../ft_errno.h"
#include "../../subst/subst.h" #include "../../subst/subst.h"
#include "../../parser/redirect/redirect.h" #include "../../parser/redirect/redirect.h"
#include "../../parser/redirect/redirect_debug.h"
#include "../../parser/cmd/cmd_destroy.h" #include "../../parser/cmd/cmd_destroy.h"
static t_redirect *redirection_var_expansion(t_redirect *redirects, static t_redirect *redirection_var_expansion(t_redirect *in_list,
t_minishell *app) t_minishell *app)
{ {
t_redirect *in_list;
t_redirect *out_list; t_redirect *out_list;
t_redirect *current; t_redirect *current;
in_list = redirects;
out_list = NULL; out_list = NULL;
(void)app;
while (in_list) while (in_list)
{ {
current = redirect_pop(&in_list); current = redirect_pop(&in_list);
if (current->type != FT_HEREDOC) if (current->type != FT_HEREDOC)
{ {
current->unexpanded_filename
= ft_strdup(current->redirectee.filename->word);
current->redirectee.filename current->redirectee.filename
= word_var_expansion(current->redirectee.filename, app); = word_var_expansion(current->redirectee.filename, app);
if (current->redirectee.filename == NULL if (current->redirectee.filename == NULL

View file

@ -6,13 +6,14 @@
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */ /* By: khais <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2025/04/03 15:48:52 by khais #+# #+# */ /* Created: 2025/04/03 15:48:52 by khais #+# #+# */
/* Updated: 2025/04/15 11:59:23 by khais ### ########.fr */ /* Updated: 2025/04/21 11:56:26 by khais ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
#include "fieldsplit.h" #include "fieldsplit.h"
#include "../../buffer/buffer.h" #include "../../buffer/buffer.h"
#include "../../parser/matchers/blank.h" #include "../../parser/matchers/blank.h"
#include "redirect_fieldsplit.h"
#include <stdlib.h> #include <stdlib.h>
static bool should_delimit(t_worddesc *original, size_t i) static bool should_delimit(t_worddesc *original, size_t i)
@ -34,7 +35,7 @@ static void fieldsplit_delimit(t_buffer *word, t_buffer *marker,
free(marker); free(marker);
} }
static t_wordlist *minishell_fieldsplit(t_worddesc *original, t_wordlist *minishell_fieldsplit(t_worddesc *original,
t_wordlist **outlist) t_wordlist **outlist)
{ {
size_t i; size_t i;
@ -93,5 +94,7 @@ t_simple_cmd *simple_cmd_fieldsplit(t_simple_cmd *cmd)
return (NULL); return (NULL);
if (wordlist_fieldsplit(&cmd->words) == NULL) if (wordlist_fieldsplit(&cmd->words) == NULL)
return (NULL); return (NULL);
if (redirect_fieldsplit(cmd) == NULL)
return (NULL);
return (cmd); return (cmd);
} }

View file

@ -6,15 +6,17 @@
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */ /* By: khais <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2025/04/03 15:46:56 by khais #+# #+# */ /* Created: 2025/04/03 15:46:56 by khais #+# #+# */
/* Updated: 2025/04/03 16:06:23 by khais ### ########.fr */ /* Updated: 2025/04/21 11:57:40 by khais ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
#ifndef FIELDSPLIT_H #ifndef FIELDSPLIT_H
# define FIELDSPLIT_H # define FIELDSPLIT_H
# include "../../parser/simple_cmd/simple_cmd.h" # include "../../minishell.h"
t_simple_cmd *simple_cmd_fieldsplit(t_simple_cmd *cmd); t_simple_cmd *simple_cmd_fieldsplit(t_simple_cmd *cmd);
t_wordlist *minishell_fieldsplit(t_worddesc *original,
t_wordlist **outlist);
#endif // FIELDSPLIT_H #endif // FIELDSPLIT_H

View file

@ -0,0 +1,71 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* redirect_fieldsplit.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/04/21 11:54:16 by khais #+# #+# */
/* Updated: 2025/04/21 11:57:50 by khais ### ########.fr */
/* */
/* ************************************************************************** */
#include "redirect_fieldsplit.h"
#include "fieldsplit.h"
#include "../../parser/redirect/redirect.h"
#include "../../parser/cmd/cmd_destroy.h"
#include <unistd.h>
static void redirect_fieldsplit_cleanup(t_redirect *in_list,
t_redirect *out_list, t_redirect *current, t_simple_cmd *cmd)
{
redirect_destroy(in_list);
redirect_destroy(out_list);
redirect_destroy(current);
cmd->redirections = NULL;
}
static t_simple_cmd *redirect_fieldsplit_single(t_redirect *in_list,
t_redirect *out_list, t_redirect *current, t_simple_cmd *cmd)
{
t_wordlist *out;
if (minishell_fieldsplit(current->redirectee.filename, &out) == NULL)
{
redirect_fieldsplit_cleanup(in_list, out_list, current, cmd);
return (wordlist_destroy(out), NULL);
}
worddesc_destroy(current->redirectee.filename);
current->redirectee.filename = wordlist_pop(&out);
if (out != NULL)
{
ft_dprintf(STDERR_FILENO, "minishell: %s: ambiguous redirect\n",
current->unexpanded_filename);
redirect_fieldsplit_cleanup(in_list, out_list, current, cmd);
return (wordlist_destroy(out), NULL);
}
return (cmd);
}
t_simple_cmd *redirect_fieldsplit(t_simple_cmd *cmd)
{
t_redirect *in_list;
t_redirect *out_list;
t_redirect *current;
in_list = cmd->redirections;
out_list = NULL;
while (in_list != NULL)
{
current = redirect_pop(&in_list);
if (current->type != FT_HEREDOC)
{
if (redirect_fieldsplit_single(in_list, out_list, current, cmd)
== NULL)
return (NULL);
}
out_list = t_redirect_add_back(&out_list, current);
}
cmd->redirections = out_list;
return (cmd);
}

View file

@ -0,0 +1,20 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* redirect_fieldsplit.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/04/21 11:53:54 by khais #+# #+# */
/* Updated: 2025/04/21 11:54:42 by khais ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef REDIRECT_FIELDSPLIT_H
# define REDIRECT_FIELDSPLIT_H
# include "../../minishell.h"
t_simple_cmd *redirect_fieldsplit(t_simple_cmd *cmd);
#endif // REDIRECT_FIELDSPLIT_H

21
test.sh
View file

@ -820,4 +820,25 @@ outfile
hello there hello there
EOF EOF
when_run <<"EOF" "ambiguous redirect"
export target="outfile1 outfile2"
echo hello > $target
echo $?
echo hi >> $target
echo $?
cat < $target
echo $?
ls
echo $?
EOF
expecting <<"EOF"
minishell: $target: ambiguous redirect
1
minishell: $target: ambiguous redirect
1
minishell: $target: ambiguous redirect
1
0
EOF
finalize finalize