mirror of
https://codeberg.org/la-chouette/minishell.git
synced 2025-12-06 07:28:09 +01:00
feat(redir): fieldsplit redir target, and handle ambiguous redirects
This commit is contained in:
parent
5de82f2940
commit
ce8e06f665
10 changed files with 136 additions and 12 deletions
1
Makefile
1
Makefile
|
|
@ -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 \
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
71
src/postprocess/fieldsplit/redirect_fieldsplit.c
Normal file
71
src/postprocess/fieldsplit/redirect_fieldsplit.c
Normal 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);
|
||||||
|
}
|
||||||
20
src/postprocess/fieldsplit/redirect_fieldsplit.h
Normal file
20
src/postprocess/fieldsplit/redirect_fieldsplit.h
Normal 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
21
test.sh
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue