mirror of
https://github.com/Ladebeze66/minishell.git
synced 2026-11-09 13:47:17 +01:00
minishell
This commit is contained in:
78
parsing/herodoc.c
Executable file
78
parsing/herodoc.c
Executable file
@@ -0,0 +1,78 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* herodoc.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/12/01 15:49:41 by fgras-ca #+# #+# */
|
||||
/* Updated: 2023/12/07 14:16:55 by fgras-ca ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "../minishell.h"
|
||||
|
||||
static void read_and_write_input(int write_end, const char *delimiter)
|
||||
{
|
||||
char buffer[1024];
|
||||
ssize_t num_read;
|
||||
char *newline;
|
||||
|
||||
while (1)
|
||||
{
|
||||
printf("> ");
|
||||
fflush(stdout);
|
||||
num_read = read(STDIN_FILENO, buffer, sizeof(buffer) - 1);
|
||||
if (num_read <= 0)
|
||||
break ;
|
||||
buffer[num_read] = '\0';
|
||||
if (ft_strncmp(buffer, delimiter, ft_strlen(delimiter)) == 0)
|
||||
{
|
||||
newline = ft_strchr(buffer, '\n');
|
||||
if (newline != NULL && newline - buffer
|
||||
== (ptrdiff_t)ft_strlen(delimiter))
|
||||
break ;
|
||||
}
|
||||
write(write_end, buffer, num_read);
|
||||
}
|
||||
}
|
||||
|
||||
static void child_process(int *pipe_fds, const char *delimiter)
|
||||
{
|
||||
close(pipe_fds[0]);
|
||||
read_and_write_input(pipe_fds[1], delimiter);
|
||||
close(pipe_fds[1]);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
static void parent_process(int *pipe_fds)
|
||||
{
|
||||
close(pipe_fds[1]);
|
||||
dup2(pipe_fds[0], STDIN_FILENO);
|
||||
close(pipe_fds[0]);
|
||||
}
|
||||
|
||||
void heredoc_input(const char *delimiter)
|
||||
{
|
||||
int pipe_fds[2];
|
||||
pid_t pid;
|
||||
|
||||
if (pipe(pipe_fds) == -1)
|
||||
{
|
||||
perror("pipe");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
pid = fork();
|
||||
if (pid == -1)
|
||||
{
|
||||
perror("fork");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (pid == 0)
|
||||
child_process(pipe_fds, delimiter);
|
||||
else
|
||||
{
|
||||
parent_process(pipe_fds);
|
||||
waitpid(pid, NULL, 0);
|
||||
}
|
||||
}
|
||||
113
parsing/parse.c
Executable file
113
parsing/parse.c
Executable file
@@ -0,0 +1,113 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* parse.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/11/29 21:03:27 by fgras-ca #+# #+# */
|
||||
/* Updated: 2023/12/10 14:00:23 by fgras-ca ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "../minishell.h"
|
||||
|
||||
static void finalize_command(t_command **current_command, t_command_node **root)
|
||||
{
|
||||
t_command_node *new_node;
|
||||
|
||||
if (*current_command && (*current_command)->command)
|
||||
{
|
||||
new_node = create_command_node(*current_command);
|
||||
add_node_to_tree(root, new_node);
|
||||
}
|
||||
else if (*current_command)
|
||||
{
|
||||
free_command(*current_command);
|
||||
}
|
||||
}
|
||||
|
||||
static bool handle_syntax_error_and_free(t_process_token_params *params,
|
||||
t_minishell *shell)
|
||||
{
|
||||
char *current_token;
|
||||
bool sb;
|
||||
|
||||
current_token = params->tokens[*params->token_index];
|
||||
sb = shell->tokenizer->symbol;
|
||||
if (sb && (is_pipe_token(current_token, shell)
|
||||
|| is_redirection_token(current_token)))
|
||||
{
|
||||
if (check_syntax_error(params->tokens,
|
||||
*params->token_index, shell->tokenizer->in_quotes, shell))
|
||||
{
|
||||
if (*(params->current_command) != NULL)
|
||||
{
|
||||
free_command(*(params->current_command));
|
||||
*(params->current_command) = NULL;
|
||||
}
|
||||
return (true);
|
||||
}
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
|
||||
static void process_single_token(t_process_token_params *params,
|
||||
t_minishell *shell, int fd)
|
||||
{
|
||||
char *current_token;
|
||||
|
||||
current_token = params->tokens[*params->token_index];
|
||||
if (shell->tokenizer->symbol && (is_pipe_token(current_token, shell)
|
||||
|| is_redirection_token(current_token)))
|
||||
{
|
||||
handle_pipe_and_redirection(params, fd);
|
||||
}
|
||||
else
|
||||
{
|
||||
handle_variable_and_other_tokens(params);
|
||||
}
|
||||
}
|
||||
|
||||
static void process_tokens(t_process_token_params *params,
|
||||
t_minishell *shell, int fd)
|
||||
{
|
||||
while (params->tokens[*params->token_index] != NULL)
|
||||
{
|
||||
if (handle_syntax_error_and_free(params, shell))
|
||||
{
|
||||
return ;
|
||||
}
|
||||
process_single_token(params, shell, fd);
|
||||
(*params->token_index)++;
|
||||
}
|
||||
}
|
||||
|
||||
void parse_tokens(char **tokens, t_minishell *shell, int fd)
|
||||
{
|
||||
t_command_node *root;
|
||||
t_command *current_command;
|
||||
int token_index;
|
||||
int error_detected;
|
||||
t_process_token_params params;
|
||||
|
||||
token_index = 0;
|
||||
current_command = NULL;
|
||||
root = NULL;
|
||||
error_detected = 0;
|
||||
params.tokens = tokens;
|
||||
params.token_index = &token_index;
|
||||
params.current_command = ¤t_command;
|
||||
params.root = &root;
|
||||
params.shell = shell;
|
||||
params.command_count = 1;
|
||||
process_tokens(¶ms, shell, fd);
|
||||
if (current_command && current_command->command)
|
||||
{
|
||||
finalize_command(¤t_command, &root);
|
||||
if (!error_detected)
|
||||
execute_and_free_tree(root, shell, params.command_count, fd);
|
||||
}
|
||||
else if (current_command)
|
||||
free_command(current_command);
|
||||
}
|
||||
45
parsing/parse_error.c
Executable file
45
parsing/parse_error.c
Executable file
@@ -0,0 +1,45 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* parse_error.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/12/07 13:00:24 by fgras-ca #+# #+# */
|
||||
/* Updated: 2023/12/09 19:25:39 by fgras-ca ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "../minishell.h"
|
||||
|
||||
void execute_and_free_tree(t_command_node *root,
|
||||
t_minishell *shell, int command_count, int fd)
|
||||
{
|
||||
if (root)
|
||||
{
|
||||
execute_command_tree(root, shell, command_count, fd);
|
||||
free_command_tree(root);
|
||||
}
|
||||
}
|
||||
|
||||
int check_syntax_error(char **tokens, int token_index,
|
||||
bool in_quotes, t_minishell *shell)
|
||||
{
|
||||
if (in_quotes)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
if (is_redirection_token(tokens[token_index])
|
||||
|| is_pipe_token(tokens[token_index], shell))
|
||||
{
|
||||
if (token_index == 0 || tokens[token_index + 1] == NULL)
|
||||
{
|
||||
write(2, RED"bash: erreur de syntaxe près du symbole inattendu "
|
||||
RST, 58);
|
||||
write(2, tokens[token_index], ft_strlen(tokens[token_index]));
|
||||
write(2, "\n", 1);
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
87
parsing/parse_redirections.c
Executable file
87
parsing/parse_redirections.c
Executable file
@@ -0,0 +1,87 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* parse_redirections.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/12/01 15:25:07 by fgras-ca #+# #+# */
|
||||
/* Updated: 2023/12/10 13:55:02 by fgras-ca ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "../minishell.h"
|
||||
|
||||
void handle_pipe_and_redirection(t_process_token_params *params, int fd)
|
||||
{
|
||||
t_command_node *new_node;
|
||||
|
||||
if (is_pipe_token(params->tokens[*params->token_index], params->shell))
|
||||
{
|
||||
if (*params->current_command && (*params->current_command)->command)
|
||||
{
|
||||
new_node = create_command_node(*params->current_command);
|
||||
add_node_to_tree(params->root, new_node);
|
||||
*params->current_command = create_new_command();
|
||||
params->command_count++;
|
||||
}
|
||||
}
|
||||
else if (is_redirection_token(params->tokens[*params->token_index]))
|
||||
{
|
||||
if (*params->current_command && (*params->current_command)->command)
|
||||
{
|
||||
process_redirection
|
||||
(params, *params->current_command, params->shell, fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void resolve_variable_and_add_to_command(t_process_token_params *params,
|
||||
char *token)
|
||||
{
|
||||
char *resolved_value;
|
||||
|
||||
resolved_value = get_variable_value(token, params->shell);
|
||||
add_token_to_command_wrapper(params->current_command, resolved_value);
|
||||
free(resolved_value);
|
||||
}
|
||||
|
||||
static void handle_variable_token(t_process_token_params *params)
|
||||
{
|
||||
char *token;
|
||||
t_State current_state;
|
||||
|
||||
token = params->tokens[*params->token_index];
|
||||
current_state = params->shell->tokenizer->state;
|
||||
if (is_variable_resolvable(token, current_state))
|
||||
{
|
||||
resolve_variable_and_add_to_command(params, token);
|
||||
}
|
||||
else
|
||||
{
|
||||
add_token_to_command_wrapper(params->current_command, token);
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_non_variable_token(t_process_token_params *params)
|
||||
{
|
||||
add_token_to_command_wrapper(params->current_command,
|
||||
params->tokens[*params->token_index]);
|
||||
}
|
||||
|
||||
void handle_variable_and_other_tokens(t_process_token_params *params)
|
||||
{
|
||||
char *current_token;
|
||||
bool variable;
|
||||
|
||||
current_token = params->tokens[*params->token_index];
|
||||
variable = params->shell->tokenizer->variable;
|
||||
if (!variable && is_variable_token(current_token))
|
||||
{
|
||||
handle_variable_token(params);
|
||||
}
|
||||
else
|
||||
{
|
||||
handle_non_variable_token(params);
|
||||
}
|
||||
}
|
||||
54
parsing/parse_utils.c
Executable file
54
parsing/parse_utils.c
Executable file
@@ -0,0 +1,54 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* parse_utils.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/12/07 09:58:11 by fgras-ca #+# #+# */
|
||||
/* Updated: 2023/12/09 19:09:08 by fgras-ca ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "../minishell.h"
|
||||
|
||||
bool is_pipe_token(char *token, t_minishell *shell)
|
||||
{
|
||||
(void)shell;
|
||||
return (strcmp(token, "|") == 0);
|
||||
}
|
||||
|
||||
bool is_redirection_token(char *token)
|
||||
{
|
||||
static const char *redirections[] = {">", "<", ">>", "<<", NULL};
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
while (redirections[i] != NULL)
|
||||
{
|
||||
if (ft_strcmp(token, redirections[i]) == 0)
|
||||
return (true);
|
||||
i++;
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
|
||||
bool is_variable_token(char *token)
|
||||
{
|
||||
return (token[0] == '$' && token[1] != '\0');
|
||||
}
|
||||
|
||||
void add_token_to_command_wrapper(t_command **command, char *token)
|
||||
{
|
||||
if (!*command)
|
||||
{
|
||||
*command = create_new_command();
|
||||
}
|
||||
add_token_to_command(*command, token);
|
||||
}
|
||||
|
||||
int is_variable_resolvable(char *token, t_State current_state)
|
||||
{
|
||||
return ((current_state == DOUBLE_QUOTE || (token[0] == '$'))
|
||||
&& (current_state != SINGLE_QUOTE));
|
||||
}
|
||||
92
parsing/pipe.c
Executable file
92
parsing/pipe.c
Executable file
@@ -0,0 +1,92 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* pipe.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/11/28 19:21:38 by fgras-ca #+# #+# */
|
||||
/* Updated: 2023/12/09 19:21:39 by fgras-ca ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "../minishell.h"
|
||||
|
||||
static void create_and_handle_processes(t_process_params *params)
|
||||
{
|
||||
int i;
|
||||
pid_t pid;
|
||||
t_child_process_params child_params;
|
||||
|
||||
i = 0;
|
||||
while (i < params->command_count)
|
||||
{
|
||||
pid = fork();
|
||||
if (pid == 0)
|
||||
{
|
||||
child_params = (t_child_process_params){i, params->pipe_fds,
|
||||
params->command_count, params->fd,
|
||||
params->commands, params->shell};
|
||||
setup_child_process(&child_params);
|
||||
}
|
||||
else if (pid < 0)
|
||||
{
|
||||
perror("fork");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
static void initialize_pipes(int *pipe_fds, int command_count)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
while (i < command_count - 1)
|
||||
{
|
||||
if (pipe(pipe_fds + i * 2) < 0)
|
||||
{
|
||||
perror("pipe");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
static void wait_for_all_processes(int command_count)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
while (i < command_count)
|
||||
{
|
||||
wait(NULL);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void process_pipe(t_command **commands,
|
||||
t_minishell *shell, int command_count, int fd)
|
||||
{
|
||||
int *pipe_fds;
|
||||
t_process_params params;
|
||||
|
||||
if (command_count == 1)
|
||||
{
|
||||
execute_command(commands[0], shell, fd);
|
||||
return ;
|
||||
}
|
||||
pipe_fds = malloc(2 * (command_count - 1) * sizeof(int));
|
||||
if (!pipe_fds)
|
||||
{
|
||||
perror("malloc");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
initialize_pipes(pipe_fds, command_count);
|
||||
params = (t_process_params){pipe_fds, commands, shell, command_count, fd};
|
||||
create_and_handle_processes(¶ms);
|
||||
close_all_pipes(pipe_fds, 2 * (command_count - 1));
|
||||
wait_for_all_processes(command_count);
|
||||
free(pipe_fds);
|
||||
}
|
||||
40
parsing/pipe_utils.c
Executable file
40
parsing/pipe_utils.c
Executable file
@@ -0,0 +1,40 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* pipe_utils.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/12/09 17:16:52 by fgras-ca #+# #+# */
|
||||
/* Updated: 2023/12/09 18:45:08 by fgras-ca ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "../minishell.h"
|
||||
|
||||
void close_all_pipes(int *pipe_fds, int count)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
while (i < count)
|
||||
{
|
||||
close(pipe_fds[i]);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void setup_child_process(t_child_process_params *params)
|
||||
{
|
||||
if (params->i != 0)
|
||||
{
|
||||
dup2(params->pipe_fds[(params->i - 1) * 2], STDIN_FILENO);
|
||||
}
|
||||
if (params->i != params->command_count - 1)
|
||||
{
|
||||
dup2(params->pipe_fds[params->i * 2 + 1], STDOUT_FILENO);
|
||||
}
|
||||
close_all_pipes(params->pipe_fds, 2 * (params->command_count - 1));
|
||||
execute_command(params->commands[params->i], params->shell, params->fd);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
82
parsing/redirection.c
Executable file
82
parsing/redirection.c
Executable file
@@ -0,0 +1,82 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* redirection.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/11/28 18:42:58 by fgras-ca #+# #+# */
|
||||
/* Updated: 2023/12/10 13:56:12 by fgras-ca ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "../minishell.h"
|
||||
|
||||
void configure_redirection(char *file, int mode)
|
||||
{
|
||||
int fd;
|
||||
|
||||
if (mode == REDIRECT_IN)
|
||||
{
|
||||
fd = open(file, O_RDONLY);
|
||||
dup2(fd, STDIN_FILENO);
|
||||
close(fd);
|
||||
}
|
||||
else if (mode == REDIRECT_OUT)
|
||||
{
|
||||
fd = open(file, O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
||||
dup2(fd, STDOUT_FILENO);
|
||||
close(fd);
|
||||
}
|
||||
else if (mode == REDIRECT_APPEND)
|
||||
{
|
||||
fd = open(file, O_WRONLY | O_CREAT | O_APPEND, 0644);
|
||||
dup2(fd, STDOUT_FILENO);
|
||||
close(fd);
|
||||
}
|
||||
else if (mode == REDIRECT_HEREDOC)
|
||||
{
|
||||
heredoc_input(file);
|
||||
}
|
||||
}
|
||||
|
||||
static t_redirection_mode get_redirection_mode(char *token)
|
||||
{
|
||||
if (ft_strcmp(token, ">") == 0)
|
||||
return (REDIRECT_OUT);
|
||||
if (ft_strcmp(token, "<") == 0)
|
||||
return (REDIRECT_IN);
|
||||
if (ft_strcmp(token, ">>") == 0)
|
||||
return (REDIRECT_APPEND);
|
||||
if (ft_strcmp(token, "<<") == 0)
|
||||
return (REDIRECT_HEREDOC);
|
||||
perror(RED"Redirection non reconnue"RST);
|
||||
return (REDIRECT_UNKNOWN);
|
||||
}
|
||||
|
||||
static void handle_redirection(char *token, t_redirection_mode redirection_mode)
|
||||
{
|
||||
if (redirection_mode == REDIRECT_HEREDOC)
|
||||
heredoc_input(token);
|
||||
else
|
||||
configure_redirection(token, redirection_mode);
|
||||
}
|
||||
|
||||
void process_redirection(t_process_token_params *params, t_command *commands,
|
||||
t_minishell*shell, int fd)
|
||||
{
|
||||
t_redirection redir;
|
||||
t_redirection_mode redirection_mode;
|
||||
|
||||
save_standard_descriptors(&redir);
|
||||
redirection_mode
|
||||
= get_redirection_mode(params->tokens[*(params->token_index)]);
|
||||
if (redirection_mode == REDIRECT_UNKNOWN)
|
||||
return ;
|
||||
(*(params->token_index))++;
|
||||
handle_redirection
|
||||
(params->tokens[*(params->token_index)], redirection_mode);
|
||||
execute_command(commands, shell, fd);
|
||||
restore_standard_descriptors(&redir);
|
||||
reset_command(*params->current_command);
|
||||
}
|
||||
33
parsing/redirection_utils.c
Executable file
33
parsing/redirection_utils.c
Executable file
@@ -0,0 +1,33 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* redirection_utils.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/12/07 12:33:34 by fgras-ca #+# #+# */
|
||||
/* Updated: 2023/12/10 13:29:36 by fgras-ca ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "../minishell.h"
|
||||
|
||||
void save_standard_descriptors(t_redirection *redir)
|
||||
{
|
||||
redir->stdin_backup = dup(STDIN_FILENO);
|
||||
redir->stdout_backup = dup(STDOUT_FILENO);
|
||||
}
|
||||
|
||||
void restore_standard_descriptors(t_redirection *redir)
|
||||
{
|
||||
if (redir->stdin_backup != -1)
|
||||
{
|
||||
dup2(redir->stdin_backup, STDIN_FILENO);
|
||||
close(redir->stdin_backup);
|
||||
}
|
||||
if (redir->stdout_backup != -1)
|
||||
{
|
||||
dup2(redir->stdout_backup, STDOUT_FILENO);
|
||||
close(redir->stdout_backup);
|
||||
}
|
||||
}
|
||||
82
parsing/tree.c
Executable file
82
parsing/tree.c
Executable file
@@ -0,0 +1,82 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* tree.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/11/30 12:03:54 by fgras-ca #+# #+# */
|
||||
/* Updated: 2023/12/10 13:56:39 by fgras-ca ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "../minishell.h"
|
||||
|
||||
t_command_node *create_command_node(t_command *command)
|
||||
{
|
||||
t_command_node *node;
|
||||
|
||||
node = malloc(sizeof(t_command_node));
|
||||
if (node == NULL)
|
||||
{
|
||||
return (NULL);
|
||||
}
|
||||
node->command = command;
|
||||
node->left = NULL;
|
||||
node->right = NULL;
|
||||
return (node);
|
||||
}
|
||||
|
||||
void add_node_to_tree(t_command_node **root, t_command_node *new_node)
|
||||
{
|
||||
t_command_node *current;
|
||||
|
||||
if (*root == NULL)
|
||||
{
|
||||
*root = new_node;
|
||||
}
|
||||
else
|
||||
{
|
||||
current = *root;
|
||||
while (current->right != NULL)
|
||||
{
|
||||
current = current->right;
|
||||
}
|
||||
current->right = new_node;
|
||||
}
|
||||
}
|
||||
|
||||
void execute_command_tree(t_command_node *node, t_minishell *shell,
|
||||
int command_count, int fd)
|
||||
{
|
||||
t_command **commands_array;
|
||||
t_command_node *current_node;
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
current_node = node;
|
||||
commands_array = malloc(sizeof(t_command *) * command_count);
|
||||
while (current_node != NULL && i < command_count)
|
||||
{
|
||||
commands_array[i] = current_node->command;
|
||||
current_node = current_node->right;
|
||||
i++;
|
||||
}
|
||||
process_pipe(commands_array, shell, command_count, fd);
|
||||
free(commands_array);
|
||||
}
|
||||
|
||||
void free_command_tree(t_command_node *node)
|
||||
{
|
||||
if (node == NULL)
|
||||
{
|
||||
return ;
|
||||
}
|
||||
free_command_tree(node->left);
|
||||
free_command_tree(node->right);
|
||||
if (node->command)
|
||||
{
|
||||
free(node->command);
|
||||
}
|
||||
free(node);
|
||||
}
|
||||
105
parsing/variable.c
Executable file
105
parsing/variable.c
Executable file
@@ -0,0 +1,105 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* variable.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/11/29 21:41:34 by fgras-ca #+# #+# */
|
||||
/* Updated: 2023/12/07 14:10:45 by fgras-ca ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "../minishell.h"
|
||||
|
||||
static char *allocate_exit_status_str(void)
|
||||
{
|
||||
char *exit_status_str;
|
||||
|
||||
exit_status_str = malloc(sizeof(char) * 12);
|
||||
if (exit_status_str == NULL)
|
||||
{
|
||||
perror("Erreur d'allocation mémoire $");
|
||||
return (NULL);
|
||||
}
|
||||
return (exit_status_str);
|
||||
}
|
||||
|
||||
static int num_to_str(int num, char *str, int base)
|
||||
{
|
||||
int i;
|
||||
int rem;
|
||||
|
||||
i = 0;
|
||||
if (num == 0)
|
||||
{
|
||||
str[i++] = '0';
|
||||
}
|
||||
else
|
||||
{
|
||||
while (num != 0)
|
||||
{
|
||||
rem = num % base;
|
||||
if (rem > 9)
|
||||
str[i++] = (rem - 10) + 'a';
|
||||
else
|
||||
str[i++] = rem + '0';
|
||||
num /= base;
|
||||
}
|
||||
}
|
||||
str[i] = '\0';
|
||||
return (i);
|
||||
}
|
||||
|
||||
static void int_to_str(int num, char *str, int base)
|
||||
{
|
||||
int isnegative;
|
||||
int length;
|
||||
|
||||
isnegative = 0;
|
||||
if (num == 0)
|
||||
{
|
||||
str[0] = '0';
|
||||
str[1] = '\0';
|
||||
return ;
|
||||
}
|
||||
if (num < 0 && base == 10)
|
||||
{
|
||||
isnegative = 1;
|
||||
num = -num;
|
||||
}
|
||||
length = num_to_str(num, str, base);
|
||||
if (isnegative)
|
||||
{
|
||||
str[length] = '-';
|
||||
str[length + 1] = '\0';
|
||||
length++;
|
||||
}
|
||||
reverse_str(str, length);
|
||||
}
|
||||
|
||||
static char *get_exit_status_str(t_minishell *shell)
|
||||
{
|
||||
char *exit_status_str;
|
||||
|
||||
exit_status_str = allocate_exit_status_str();
|
||||
if (exit_status_str == NULL)
|
||||
return (NULL);
|
||||
int_to_str(shell->last_exit_status, exit_status_str, 10);
|
||||
return (exit_status_str);
|
||||
}
|
||||
|
||||
char *get_variable_value(const char *variable_name, t_minishell *shell)
|
||||
{
|
||||
const char *name_to_search;
|
||||
char *value;
|
||||
|
||||
name_to_search = skip_dollar(variable_name);
|
||||
if (ft_strcmp(name_to_search, "?") == 0)
|
||||
{
|
||||
value = get_exit_status_str(shell);
|
||||
return (value);
|
||||
}
|
||||
value = search_env_variable(name_to_search, shell);
|
||||
return (value);
|
||||
}
|
||||
57
parsing/variable_utils.c
Executable file
57
parsing/variable_utils.c
Executable file
@@ -0,0 +1,57 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* variable_utils.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/12/07 10:46:07 by fgras-ca #+# #+# */
|
||||
/* Updated: 2023/12/07 14:11:44 by fgras-ca ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "../minishell.h"
|
||||
|
||||
const char *skip_dollar(const char *variable_name)
|
||||
{
|
||||
if (variable_name[0] == '$')
|
||||
return (variable_name + 1);
|
||||
return (variable_name);
|
||||
}
|
||||
|
||||
void reverse_str(char *str, int length)
|
||||
{
|
||||
int start;
|
||||
int end;
|
||||
char temp;
|
||||
|
||||
start = 0;
|
||||
end = length - 1;
|
||||
while (start < end)
|
||||
{
|
||||
temp = str[start];
|
||||
str[start] = str[end];
|
||||
str[end] = temp;
|
||||
start++;
|
||||
end--;
|
||||
}
|
||||
}
|
||||
|
||||
char *search_env_variable(const char *name_to_search, t_minishell *shell)
|
||||
{
|
||||
int i;
|
||||
char *env_entry;
|
||||
size_t name_len;
|
||||
|
||||
name_len = ft_strlen(name_to_search);
|
||||
i = 0;
|
||||
while (shell->environ[i])
|
||||
{
|
||||
env_entry = shell->environ[i];
|
||||
if (ft_strncmp(env_entry, name_to_search, name_len) == 0
|
||||
&& env_entry[name_len] == '=')
|
||||
return (ft_strdup(env_entry + name_len + 1));
|
||||
i++;
|
||||
}
|
||||
return (ft_strdup(""));
|
||||
}
|
||||
Reference in New Issue
Block a user