Skip to content

Commit

Permalink
Merge pull request #66 from eguefif/env
Browse files Browse the repository at this point in the history
Env
  • Loading branch information
eguefif authored Nov 22, 2023
2 parents be07f34 + 9fb18a4 commit 2e4486b
Show file tree
Hide file tree
Showing 8 changed files with 159 additions and 33 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ READLINE = $(READLINE_DIR)/libreadline.a

_SRC_LIB_STATIC = parser.c executer.c cleaner.c lexer.c lexer_get_tokens.c error.c parser_get_commands.c parser_clean_commands1.c parser_clean_commands2.c lexer_count_tokens.c lexer_get_token_size.c parser_get_commands_populate.c \
utils.c executer_getpath.c environment.c signals.c

_SRC = main.c $(_SRC_LIB_STATIC)
_OBJ = $(_SRC:.c=.o)
_OBJ_LIB_STATIC = $(_SRC_LIB_STATIC:.c=.o)
Expand Down
7 changes: 6 additions & 1 deletion includes/minishell.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
# define IS_DIR 4
# define OPEN_ERROR 5
# define SIGNAL_ERROR 6
# define EXPORT_ERROR 7

typedef struct s_redirections
{
Expand Down Expand Up @@ -68,8 +69,9 @@ size_t get_env_var_len(char **env_var);
char **get_env_list(char *token, char **env);
size_t get_new_token_size(char *token, char **var_env);

int ms_execute(t_command *commnands, char **env);
int ms_execute(t_command *commnands, char ***env);
char *get_command_path(char *command, char **env);
int set_redirections(t_command command, int *pipe_fd, int last);

// Environment management
char *ms_getenv(char **env, char *var);
Expand All @@ -79,6 +81,9 @@ char **remove_var(char **env, char *var);
char **update_var(char **env, char *var, char *new_content);
int is_var(char **env, char *var);

//Builtin
int exec_builtin(t_command cmd, char ***env);

// Signal management
int ms_init_signals(void);
int ms_reset_signals(void);
Expand Down
91 changes: 91 additions & 0 deletions src/builtin.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* buildin.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maxpelle <[email protected]> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/11/13 12:16:43 by eguefif #+# #+# */
/* Updated: 2023/11/22 10:24:48 by maxpelle ### ########.fr */
/* */
/* ************************************************************************** */

#include "minishell.h"

static char **builtin_unset(t_command cmd, char **env);
static int builtin_export(t_command cmd, char ***env);
static int is_valid_identifier(char *id);

int exec_builtin(t_command cmd, char ***env)
{
if (ft_strcmp(cmd.args[0], "export") == 0)
return (builtin_export(cmd, env));
else if (ft_strcmp(cmd.args[0], "unset") == 0)
{
*env = builtin_unset(cmd, *env);
return (0);
}
return (-1);
}

static char **builtin_unset(t_command cmd, char **env)
{
int i;

i = 1;
while (cmd.args[i])
{
if (is_var(env, cmd.args[i]))
env = remove_var(env, cmd.args[i]);
i++;
}
return (env);
}

static int builtin_export(t_command cmd, char ***env)
{
int i;
int retval;
char **splits;

i = 1;
retval = 0;
while (cmd.args[i])
{
if (is_valid_identifier(cmd.args[i]))
{
splits = ft_split(cmd.args[i], '=');
if (is_var(*env, cmd.args[i]))
*env = update_var(*env, splits[0], splits[1]);
else
*env = add_var(*env, splits[0], splits[1]);
ft_cleansplits(splits);
}
else
{
ft_error_message(cmd.args[i], EXPORT_ERROR);
if (ft_strchr(cmd.args[i], '='))
retval = 1;
}
i++;
}
return (retval);
}

static int is_valid_identifier(char *id)
{
int i;

if (!ft_strchr(id, '='))
return (0);
if (ft_isdigit(id[0]))
return (0);
i = 1;
while (id[i] != '=')
{
if (!(ft_isalnum(id[i]) || id[i] == '_'))
return (0);
i++;
}
return (1);
}
5 changes: 4 additions & 1 deletion src/environment.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,10 +140,13 @@ char **update_var(char **env, char *var, char *new_content)
int is_var(char **env, char *var)
{
int i;
char *tmp;

i = 0;
while (env[i] && ft_strstr(env[i], var) == 0)
tmp = ft_strjoin(var, "=");
while (env[i] && ft_strstr(env[i], tmp) == 0)
i++;
free(tmp);
if (env[i])
return (1);
return (0);
Expand Down
2 changes: 2 additions & 0 deletions src/error.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,6 @@ void ft_error_message(char *s, int error_type)
ft_dprintf(2, "%s: %s: is a directory\n", PROG_NAME, s);
else if (error_type == OPEN_ERROR || error_type == SIGNAL_ERROR)
ft_dprintf(2, "%s: %s: %s\n", PROG_NAME, s, strerror(errno));
else if (error_type == EXPORT_ERROR)
ft_dprintf(2, "%s: export: \'%s\': not a valid identifier\n", PROG_NAME, s);
}
63 changes: 36 additions & 27 deletions src/executer.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,11 @@

#include "minishell.h"

static int run(t_command *commands, char **env);
static int run(t_command *commands, char ***env);
static int handle_child(t_command *commands, char **env);
static int get_exit_code(int status);
static int set_redirections(t_command command, int *pipe_fd, int last);

int ms_execute(t_command *commands, char **env)
int ms_execute(t_command *commands, char ***env)
{
int stdin_save;
int stdout_save;
Expand All @@ -35,46 +34,56 @@ int ms_execute(t_command *commands, char **env)
return (retval);
}

static int run(t_command *commands, char **env)
static int run(t_command *commands, char ***env)
{
int pipe_fd[2];
int retval;
int pid;
int stat_loc;
int i;

i = -1;
pid = -1;
while (!commands[++i].last)
{
if (pipe(pipe_fd) == -1)
return (ft_error());
retval = fork();
if (retval < 0)
return (ft_error());
else if (!retval)
retval = exec_builtin(commands[i], env);
if (retval == -1)
{
if (ms_reset_signals() != 0)
return (1);
if (set_redirections(commands[i], pipe_fd,
commands[i + 1].last))
return (1);
if (!commands[i].args[0])
return (0);
ft_exit_nb(commands, handle_child(&commands[i], env));
if (pipe(pipe_fd) == -1)
return (ft_error());
pid = fork();
if (pid < 0)
return (ft_error());
else if (!pid)
{
if (ms_reset_signals() != 0)
return (1);
if (set_redirections(commands[i], pipe_fd,
commands[i + 1].last))
return (1);
if (!commands[i].args[0])
return (0);
ft_exit_nb(commands, handle_child(&commands[i], *env));
}
if (dup2(pipe_fd[0], 0) == -1)
return (ft_error());
close(pipe_fd[0]);
close(pipe_fd[1]);
}
i++;
}
if (pid >= 0)
{
waitpid(pid, &stat_loc, 0);
retval = get_exit_code(stat_loc);
while (waitpid(-1, &stat_loc, 0) > 0)
;
ms_ignore_signals();
if (dup2(pipe_fd[0], 0) == -1)
return (ft_error());
close(pipe_fd[0]);
close(pipe_fd[1]);
}
waitpid(retval, &stat_loc, 0);
retval = get_exit_code(stat_loc);
while (waitpid(-1, &stat_loc, 0) > 0)
;
return (retval);
}

static int set_redirections(t_command command, int *pipe_fd, int last)
int set_redirections(t_command command, int *pipe_fd, int last)
{
int fd;
int retval;
Expand Down
14 changes: 12 additions & 2 deletions src/executer_getpath.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

#include "minishell.h"

static int is_relative_path(char *command);

char *get_command_path(char *command, char **env)
{
char *path;
Expand All @@ -20,8 +22,9 @@ char *get_command_path(char *command, char **env)
char *retval;
char *tab[3];

if (access(command, F_OK) == 0)
return (ft_strdup(command));
if (is_relative_path(command))
if (access(command, F_OK) == 0)
return (ft_strdup(command));
path = ms_getenv(env, "PATH");
if (!path)
return (0);
Expand All @@ -43,3 +46,10 @@ char *get_command_path(char *command, char **env)
ft_cleansplits(paths);
return (retval);
}

static int is_relative_path(char *command)
{
if (command[0]== '.' && command[1] == '/')
return (1);
return (0);
}
9 changes: 7 additions & 2 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ char **non_interactive_mode(char **env)
break ;
if (commands)
{
retval = ms_execute(commands, env);
retval = ms_execute(commands, &env);
env = handle_exit_code(env, retval);
}
line = get_next_line(0);
Expand Down Expand Up @@ -80,12 +80,17 @@ char **interactive_mode(char **env)
if (check_valid_line_for_history(line))
{
add_history(line);
if (ft_strcmp(line, "exit") == 0)
{
free(line);
break ;
}
commands = ms_parser(line, env);
if (errno == ENOMEM)
break ;
if (commands)
{
retval = ms_execute(commands, env);
retval = ms_execute(commands, &env);
env = handle_exit_code(env, retval);
}
else
Expand Down

0 comments on commit 2e4486b

Please sign in to comment.