Skip to content

Commit 5a3e1a9

Browse files
committed
[FEATURE] Multiple redirections of the same type
Multiple redirections of the same type, like in bash
1 parent a07cd09 commit 5a3e1a9

11 files changed

+141
-82
lines changed

Makefile

+2-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ _OBJ += env.o \
3030

3131
# Parser
3232
_OBJ += parser.o \
33-
parser_utils.o
33+
parser_utils.o \
34+
parser_utils2.o
3435

3536
# Lexer
3637
_OBJ += lexer.o \

include/minishell.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
/* By: gbudau <gbudau@student.42.fr> +#+ +:+ +#+ */
77
/* +#+#+#+#+#+ +#+ */
88
/* Created: 2020/11/08 01:14:41 by gbudau #+# #+# */
9-
/* Updated: 2021/01/14 20:14:42 by gbudau ### ########.fr */
9+
/* Updated: 2021/01/23 23:06:38 by gbudau ### ########.fr */
1010
/* */
1111
/* ************************************************************************** */
1212

@@ -24,7 +24,6 @@
2424
# include "libft.h"
2525
# include "env.h"
2626
# include "command.h"
27-
# include "parser.h"
2827
# include "pipeline.h"
2928
# include "ioredirection.h"
3029
# include "builtins.h"

include/parser.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
/* By: gbudau <gbudau@student.42.fr> +#+ +:+ +#+ */
77
/* +#+#+#+#+#+ +#+ */
88
/* Created: 2020/11/15 15:55:58 by gbudau #+# #+# */
9-
/* Updated: 2021/01/23 01:34:36 by gbudau ### ########.fr */
9+
/* Updated: 2021/01/23 23:02:42 by gbudau ### ########.fr */
1010
/* */
1111
/* ************************************************************************** */
1212

@@ -29,8 +29,10 @@ enum e_parser_errors
2929
};
3030

3131
void clear_command(void *command);
32-
int add_command(t_list **tokens, t_command *cmd);
32+
int add_command(t_list **tokens, t_shell *shell);
3333
int skip_semicolon_token(t_list **tokens, t_command *cmd);
3434
int parse_error_token_type(int token_type);
35+
void *ft_free(void *ptr);
36+
int io_expand_open(char **word, t_shell *shell, int redirect_mode);
3537

3638
#endif

include/wordexp.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
/* By: gbudau <gbudau@student.42.fr> +#+ +:+ +#+ */
77
/* +#+#+#+#+#+ +#+ */
88
/* Created: 2020/12/01 21:15:44 by gbudau #+# #+# */
9-
/* Updated: 2021/01/14 18:03:41 by gbudau ### ########.fr */
9+
/* Updated: 2021/01/23 23:00:49 by gbudau ### ########.fr */
1010
/* */
1111
/* ************************************************************************** */
1212

@@ -30,7 +30,7 @@ char *env_or_last_status(char **words, size_t *i, t_list *environ,
3030
void remove_quotes(t_list *word_token_list);
3131
void variable_expansion(char **words, t_list **word_token_list,
3232
t_list *environ, int *last_status);
33-
int word_exp_io(t_command *cmd, t_list *environ, int *last_status);
3433
void word_exp_argv(t_command *cmd, t_list *environ, int *last_status);
34+
int expand_word(char **word, t_list *environ, int *last_status);
3535

3636
#endif

src/clear.c

+3-1
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@
66
/* By: gbudau <gbudau@student.42.fr> +#+ +:+ +#+ */
77
/* +#+#+#+#+#+ +#+ */
88
/* Created: 2020/12/06 19:28:58 by gbudau #+# #+# */
9-
/* Updated: 2021/01/11 16:11:44 by gbudau ### ########.fr */
9+
/* Updated: 2021/01/23 23:08:57 by gbudau ### ########.fr */
1010
/* */
1111
/* ************************************************************************** */
1212

1313
#include "../include/minishell.h"
14+
#include "../include/command.h"
15+
#include "../include/lexer.h"
1416
#include "../include/clear.h"
1517

1618
void clear_env(void *content)

src/lexer_utils1.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@
66
/* By: gbudau <gbudau@student.42.fr> +#+ +:+ +#+ */
77
/* +#+#+#+#+#+ +#+ */
88
/* Created: 2020/11/08 18:51:27 by gbudau #+# #+# */
9-
/* Updated: 2020/11/09 01:24:19 by gbudau ### ########.fr */
9+
/* Updated: 2021/01/23 23:07:13 by gbudau ### ########.fr */
1010
/* */
1111
/* ************************************************************************** */
1212

1313
#include "../include/minishell.h"
14+
#include "../include/lexer.h"
1415

1516
/*
1617
** Return TRUE if the current pointer is at the end of the string

src/parser.c

+8-16
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
/* By: gbudau <gbudau@student.42.fr> +#+ +:+ +#+ */
77
/* +#+#+#+#+#+ +#+ */
88
/* Created: 2020/11/09 15:01:10 by gbudau #+# #+# */
9-
/* Updated: 2021/01/23 02:19:38 by gbudau ### ########.fr */
9+
/* Updated: 2021/01/23 22:27:43 by gbudau ### ########.fr */
1010
/* */
1111
/* ************************************************************************** */
1212

@@ -61,8 +61,7 @@ static t_command *create_new_command(void)
6161
return (cmd);
6262
}
6363

64-
static void create_commands(t_list *tokens, t_list **commands,
65-
int *last_status)
64+
static void create_commands(t_list *tokens, t_shell *shell)
6665
{
6766
t_command *cmd;
6867
t_list *node;
@@ -76,31 +75,24 @@ static void create_commands(t_list *tokens, t_list **commands,
7675
node = ft_lstnew(cmd);
7776
if (node == NULL)
7877
error_exit();
79-
error = add_command(&tokens, node->content);
78+
ft_lstadd_front(&shell->commands, node);
79+
error = add_command(&tokens, shell);
8080
if (error && error != ERR_REDIRECTION)
8181
{
8282
error_unexpected_token(error);
83-
ft_lstclear(&node, clear_command);
84-
ft_lstclear(commands, clear_command);
85-
*last_status = 2;
83+
ft_lstclear(&shell->commands, clear_command);
84+
shell->last_status = 2;
8685
return ;
8786
}
88-
else if (error && error == ERR_REDIRECTION)
89-
{
90-
ft_lstclear(&node, clear_command);
91-
*last_status = 1;
92-
}
93-
else
94-
ft_lstadd_front(commands, node);
9587
}
96-
ft_lstrev(commands);
88+
ft_lstrev(&shell->commands);
9789
}
9890

9991
void parse(t_shell *shell, char *input)
10092
{
10193
t_list *tokens;
10294

10395
tokens = tokenize(input, &shell->last_status);
104-
create_commands(tokens, &shell->commands, &shell->last_status);
96+
create_commands(tokens, shell);
10597
ft_lstclear(&tokens, clear_token);
10698
}

src/parser_utils.c

+37-44
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
/* By: gbudau <gbudau@student.42.fr> +#+ +:+ +#+ */
77
/* +#+#+#+#+#+ +#+ */
88
/* Created: 2020/12/15 23:16:30 by gbudau #+# #+# */
9-
/* Updated: 2021/01/23 02:21:36 by gbudau ### ########.fr */
9+
/* Updated: 2021/01/23 23:18:22 by gbudau ### ########.fr */
1010
/* */
1111
/* ************************************************************************** */
1212

@@ -15,7 +15,6 @@
1515
#include "../include/lexer.h"
1616
#include "../include/wordexp.h"
1717
#include "../include/command.h"
18-
#include "../include/ioredirection.h"
1918

2019
static void add_argument(t_list **tokens, t_command *cmd)
2120
{
@@ -61,11 +60,12 @@ static int add_pipe(t_list **tokens, t_command *cmd)
6160
return (NO_PARSER_ERROR);
6261
}
6362

64-
static int add_input_redirection(t_list **tokens, t_command *cmd)
63+
static int add_input_redirection(t_list **tokens, t_shell *shell)
6564
{
66-
t_token *token;
67-
int fd;
65+
t_token *token;
66+
t_command *cmd;
6867

68+
cmd = shell->commands->content;
6969
*tokens = (*tokens)->next;
7070
if (*tokens == NULL)
7171
return (ERR_UNEXPECTED_NEWLINE);
@@ -74,64 +74,57 @@ static int add_input_redirection(t_list **tokens, t_command *cmd)
7474
return (parse_error_token_type(token->type));
7575
if (cmd->redirection_error == FALSE)
7676
{
77-
if (cmd->input != NULL)
78-
{
79-
free(cmd->input);
80-
cmd->input = NULL;
81-
}
8277
if (cmd->output == NULL)
8378
cmd->redirection_order = REDIRECT_INPUT_FIRST;
84-
if ((fd = open(token->str, O_RDONLY)) == -1)
85-
{
86-
cmd->redirection_error = TRUE;
87-
print_error_io(token->str);
88-
}
89-
if (fd != -1)
90-
close(fd);
91-
if (cmd->redirection_error == FALSE)
92-
{
93-
cmd->input = ft_strdup(token->str);
94-
if (cmd->input == NULL)
95-
error_exit();
96-
}
79+
if (cmd->input != NULL)
80+
cmd->input = ft_free(cmd->input);
81+
cmd->redirection_error = io_expand_open(&token->str, shell,
82+
REDIRECTION_INPUT);
83+
if (cmd->redirection_error == FALSE &&
84+
(cmd->input = ft_strdup(token->str)) == NULL)
85+
error_exit();
9786
}
9887
*tokens = (*tokens)->next;
9988
return (NO_PARSER_ERROR);
10089
}
10190

102-
static int add_output_redirection(t_list **tokens, t_command *cmd,
91+
static int add_output_redirection(t_list **tokens, t_shell *shell,
10392
int redirect_type)
10493
{
105-
t_token *token;
94+
t_token *token;
95+
t_command *cmd;
10696

97+
cmd = shell->commands->content;
10798
*tokens = (*tokens)->next;
10899
if (*tokens == NULL)
109100
return (ERR_UNEXPECTED_NEWLINE);
110-
if (cmd->output != NULL)
111-
{
112-
if (redirect_type == REDIRECTION_OUTPUT)
113-
return (ERR_UNEXPECTED_TOKEN_GREAT);
114-
else if (redirect_type == REDIRECTION_APPEND)
115-
return (ERR_UNEXPECTED_TOKEN_DGREAT);
116-
}
117-
if (cmd->input == NULL)
118-
cmd->redirection_order = REDIRECT_OUTPUT_FIRST;
119101
token = (*tokens)->content;
120102
if (token->type != TOKEN_WORD)
121103
return (parse_error_token_type(token->type));
122-
cmd->output = ft_strdup(token->str);
123-
if (cmd->output == NULL)
124-
error_exit();
125-
cmd->redirect_type = redirect_type;
104+
if (cmd->redirection_error == FALSE)
105+
{
106+
if (cmd->input == NULL)
107+
cmd->redirection_order = REDIRECT_OUTPUT_FIRST;
108+
if (cmd->output != NULL)
109+
cmd->output = ft_free(cmd->output);
110+
cmd->redirection_error = io_expand_open(&token->str, shell,
111+
redirect_type);
112+
if (cmd->redirection_error == FALSE &&
113+
(cmd->output = ft_strdup(token->str)) == NULL)
114+
error_exit();
115+
cmd->redirect_type = redirect_type;
116+
}
126117
*tokens = (*tokens)->next;
127118
return (NO_PARSER_ERROR);
128119
}
129120

130-
int add_command(t_list **tokens, t_command *cmd)
121+
int add_command(t_list **tokens, t_shell *shell)
131122
{
132-
t_token *token;
133-
int error;
123+
t_token *token;
124+
int error;
125+
t_command *cmd;
134126

127+
cmd = shell->commands->content;
135128
error = NO_PARSER_ERROR;
136129
while (*tokens != NULL && !error)
137130
{
@@ -143,11 +136,11 @@ int add_command(t_list **tokens, t_command *cmd)
143136
else if (token->type == TOKEN_WORD)
144137
add_argument(tokens, cmd);
145138
else if (token->type == TOKEN_LESS)
146-
error = add_input_redirection(tokens, cmd);
139+
error = add_input_redirection(tokens, shell);
147140
else if (token->type == TOKEN_GREAT)
148-
error = add_output_redirection(tokens, cmd, REDIRECTION_OUTPUT);
141+
error = add_output_redirection(tokens, shell, REDIRECTION_OUTPUT);
149142
else if (token->type == TOKEN_DGREAT)
150-
error = add_output_redirection(tokens, cmd, REDIRECTION_APPEND);
143+
error = add_output_redirection(tokens, shell, REDIRECTION_APPEND);
151144
}
152145
if (cmd->redirection_error)
153146
error = ERR_REDIRECTION;

src/parser_utils2.c

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/* ************************************************************************** */
2+
/* */
3+
/* ::: :::::::: */
4+
/* parser_utils2.c :+: :+: :+: */
5+
/* +:+ +:+ +:+ */
6+
/* By: gbudau <gbudau@student.42.fr> +#+ +:+ +#+ */
7+
/* +#+#+#+#+#+ +#+ */
8+
/* Created: 2021/01/23 14:38:31 by gbudau #+# #+# */
9+
/* Updated: 2021/01/23 23:14:58 by gbudau ### ########.fr */
10+
/* */
11+
/* ************************************************************************** */
12+
13+
#include "../include/minishell.h"
14+
#include "../include/parser.h"
15+
#include "../include/lexer.h"
16+
#include "../include/wordexp.h"
17+
#include "../include/command.h"
18+
19+
void *ft_free(void *ptr)
20+
{
21+
free(ptr);
22+
return (NULL);
23+
}
24+
25+
/*
26+
** Checks if there is an error while opening a file
27+
** pathname = path to the file
28+
** redirect_mode = open the file in one of the following mode
29+
** REDIRECTION_INPUT = open in read mode
30+
** REDIRECTION_OUTPUT = open in write truncate mode
31+
** REDIRECTION_APPEND = open in write append mode
32+
** Returns TRUE and prints an error if there was an error or FALSE otherwise
33+
*/
34+
35+
static int open_error(char *pathname, int redirect_mode)
36+
{
37+
int fd;
38+
int flags;
39+
mode_t mode;
40+
41+
mode = 0;
42+
if (redirect_mode == REDIRECTION_INPUT)
43+
flags = O_RDONLY;
44+
else
45+
{
46+
mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH;
47+
if (redirect_mode == REDIRECTION_OUTPUT)
48+
flags = O_WRONLY | O_CREAT | O_TRUNC;
49+
else
50+
flags = O_WRONLY | O_CREAT | O_APPEND;
51+
}
52+
if (!mode)
53+
fd = open(pathname, flags);
54+
else
55+
fd = open(pathname, flags, mode);
56+
if (fd == -1 || close(fd) == -1)
57+
{
58+
print_error_io(pathname);
59+
return (TRUE);
60+
}
61+
return (FALSE);
62+
}
63+
64+
int io_expand_open(char **word, t_shell *shell, int redirect_mode)
65+
{
66+
int error;
67+
68+
error = expand_word(word, shell->environ, &shell->last_status);
69+
if (error)
70+
return (TRUE);
71+
error = open_error(*word, redirect_mode);
72+
if (error)
73+
return (TRUE);
74+
return (FALSE);
75+
}

src/word_exp.c

+5-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
/* By: gbudau <gbudau@student.42.fr> +#+ +:+ +#+ */
77
/* +#+#+#+#+#+ +#+ */
88
/* Created: 2020/12/04 19:35:25 by gbudau #+# #+# */
9-
/* Updated: 2021/01/19 19:26:39 by gbudau ### ########.fr */
9+
/* Updated: 2021/01/23 22:21:38 by gbudau ### ########.fr */
1010
/* */
1111
/* ************************************************************************** */
1212

@@ -92,8 +92,11 @@ void variable_expansion(char **words, t_list **word_list,
9292

9393
int word_expansion(t_command *cmd, t_list *environ, int *last_status)
9494
{
95-
if (word_exp_io(cmd, environ, last_status) == -1)
95+
if (cmd->redirection_error == TRUE)
96+
{
97+
*last_status = 1;
9698
return (-1);
99+
}
97100
word_exp_argv(cmd, environ, last_status);
98101
return (0);
99102
}

0 commit comments

Comments
 (0)