Compare commits
12 Commits
214d7c24d2
...
e983f7fe64
| Author | SHA1 | Date | |
|---|---|---|---|
| e983f7fe64 | |||
| b1cf1d8560 | |||
| dce51960b1 | |||
| e9a07a6bfb | |||
| a9ba8492a2 | |||
| 83d006b40d | |||
| 027fd2ac5e | |||
| 30ce96284a | |||
| 956505c06a | |||
| 212c4e3fee | |||
| 50736d533d | |||
| daad208a00 |
4
Makefile
4
Makefile
@@ -6,7 +6,7 @@
|
|||||||
# By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ #
|
# By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ #
|
||||||
# +#+#+#+#+#+ +#+ #
|
# +#+#+#+#+#+ +#+ #
|
||||||
# Created: 2025/07/30 20:22:21 by sede-san #+# #+# #
|
# Created: 2025/07/30 20:22:21 by sede-san #+# #+# #
|
||||||
# Updated: 2025/11/01 19:30:37 by sede-san ### ########.fr #
|
# Updated: 2025/12/01 14:05:56 by sede-san ### ########.fr #
|
||||||
# #
|
# #
|
||||||
# **************************************************************************** #
|
# **************************************************************************** #
|
||||||
|
|
||||||
@@ -55,7 +55,7 @@ $(OBJS_PATH)/%.o: $(SRC_PATH)/%.c
|
|||||||
all: mandatory
|
all: mandatory
|
||||||
.PHONY: all
|
.PHONY: all
|
||||||
|
|
||||||
mandatory: libft get_next_line ft_printf $(NAME)
|
mandatory: libft get_next_line ft_printf ft_args $(NAME)
|
||||||
.PHONY: mandatory
|
.PHONY: mandatory
|
||||||
|
|
||||||
$(NAME): $(OBJS)
|
$(NAME): $(OBJS)
|
||||||
|
|||||||
@@ -6,33 +6,43 @@
|
|||||||
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
|
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/10/29 22:09:51 by sede-san #+# #+# */
|
/* Created: 2025/10/29 22:09:51 by sede-san #+# #+# */
|
||||||
/* Updated: 2025/11/02 03:13:46 by sede-san ### ########.fr */
|
/* Updated: 2025/12/01 17:53:57 by sede-san ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#ifndef BUILTINS_H
|
#ifndef BUILTINS_H
|
||||||
# define BUILTINS_H
|
# define BUILTINS_H
|
||||||
|
|
||||||
|
# include "libft.h"
|
||||||
# include "minishell.h"
|
# include "minishell.h"
|
||||||
# include "ft_args.h"
|
# include "ft_args.h"
|
||||||
|
|
||||||
|
typedef unsigned char (*t_builtin_func)(t_command cmd, t_minishell *msh);
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/* Functions */
|
/* Functions */
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
// cd.c
|
/* builtins.c */
|
||||||
|
|
||||||
|
extern u_int8_t set_builtins(t_minishell *msh);
|
||||||
|
|
||||||
|
extern u_int8_t is_builtin(const char *command_name, t_minishell *msh);
|
||||||
|
|
||||||
|
/* cd.c */
|
||||||
|
|
||||||
extern u_int8_t builtin_cd(t_command cmd, t_minishell *msh);
|
extern u_int8_t builtin_cd(t_command cmd, t_minishell *msh);
|
||||||
|
|
||||||
// echo.c
|
/* echo.c */
|
||||||
|
|
||||||
extern u_int8_t builtin_echo(t_command cmd);
|
extern u_int8_t builtin_echo(t_command cmd, t_minishell *msh);
|
||||||
|
|
||||||
// exit.c
|
/* exit.c */
|
||||||
|
|
||||||
extern u_int8_t builtin_exit(t_command cmd, t_minishell *msh);
|
extern u_int8_t builtin_exit(t_command cmd, t_minishell *msh);
|
||||||
|
|
||||||
// pwd.c
|
/* pwd.c */
|
||||||
|
|
||||||
extern u_int8_t builtin_pwd(t_command cmd, t_minishell *msh);
|
extern u_int8_t builtin_pwd(t_command cmd, t_minishell *msh);
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
|
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/10/22 19:10:13 by sede-san #+# #+# */
|
/* Created: 2025/10/22 19:10:13 by sede-san #+# #+# */
|
||||||
/* Updated: 2025/10/30 16:05:48 by sede-san ### ########.fr */
|
/* Updated: 2025/12/01 17:02:10 by sede-san ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ typedef struct s_command t_command;
|
|||||||
*/
|
*/
|
||||||
typedef struct s_variables
|
typedef struct s_variables
|
||||||
{
|
{
|
||||||
char **environment;
|
t_hashmap *environment;
|
||||||
// char **internal;
|
// char **internal;
|
||||||
} t_variables;
|
} t_variables;
|
||||||
|
|
||||||
@@ -49,6 +49,7 @@ typedef struct s_variables
|
|||||||
typedef struct s_minishell
|
typedef struct s_minishell
|
||||||
{
|
{
|
||||||
t_variables variables;
|
t_variables variables;
|
||||||
|
t_hashmap *builtins;
|
||||||
u_int8_t exit_status;
|
u_int8_t exit_status;
|
||||||
u_int8_t exit;
|
u_int8_t exit;
|
||||||
} t_minishell;
|
} t_minishell;
|
||||||
@@ -82,4 +83,17 @@ extern u_int8_t minishell_run(t_minishell *minishell);
|
|||||||
|
|
||||||
extern void minishell_clear(t_minishell *minishell);
|
extern void minishell_clear(t_minishell *minishell);
|
||||||
|
|
||||||
|
/* environment.c */
|
||||||
|
|
||||||
|
extern void set_envp(char **envp, t_minishell *msh);
|
||||||
|
|
||||||
|
extern void set_env(const char *env_name, char *env_value,
|
||||||
|
t_minishell *msh);
|
||||||
|
|
||||||
|
extern char **get_envp(t_minishell *msh);
|
||||||
|
|
||||||
|
extern void free_envp(char **envp);
|
||||||
|
|
||||||
|
extern char *get_env(const char *env_name, t_minishell *msh);
|
||||||
|
|
||||||
#endif /* CORE_H */
|
#endif /* CORE_H */
|
||||||
|
|||||||
33
src/builtins/builtins.c
Normal file
33
src/builtins/builtins.c
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* builtins.c :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2025/12/01 17:04:57 by sede-san #+# #+# */
|
||||||
|
/* Updated: 2025/12/01 17:54:26 by sede-san ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include "minishell.h"
|
||||||
|
|
||||||
|
u_int8_t set_builtins(
|
||||||
|
t_minishell *msh
|
||||||
|
) {
|
||||||
|
msh->builtins = ft_hashmap_new(4, ft_hashmap_hashstr, ft_hashmap_strcmp);
|
||||||
|
if (msh->builtins == NULL)
|
||||||
|
return (0);
|
||||||
|
ft_hashmap_put(msh->builtins, ft_strdup("cd"), builtin_cd);
|
||||||
|
ft_hashmap_put(msh->builtins, ft_strdup("echo"), builtin_echo);
|
||||||
|
ft_hashmap_put(msh->builtins, ft_strdup("exit"), builtin_exit);
|
||||||
|
ft_hashmap_put(msh->builtins, ft_strdup("pwd"), builtin_pwd);
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
u_int8_t is_builtin(
|
||||||
|
const char *command_name,
|
||||||
|
t_minishell *msh
|
||||||
|
) {
|
||||||
|
return (ft_hashmap_contains_key(msh->builtins, command_name));
|
||||||
|
}
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
|
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/10/31 00:05:22 by sede-san #+# #+# */
|
/* Created: 2025/10/31 00:05:22 by sede-san #+# #+# */
|
||||||
/* Updated: 2025/10/31 01:38:14 by sede-san ### ########.fr */
|
/* Updated: 2025/12/01 14:11:32 by sede-san ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ u_int8_t builtin_cd(
|
|||||||
return (2);
|
return (2);
|
||||||
}
|
}
|
||||||
else if (cmd.argc == 1)
|
else if (cmd.argc == 1)
|
||||||
path = getenv("HOME");
|
path = get_env("HOME", msh);
|
||||||
else
|
else
|
||||||
path = cmd.argv[1];
|
path = cmd.argv[1];
|
||||||
if (chdir(path) == -1)
|
if (chdir(path) == -1)
|
||||||
@@ -41,6 +41,8 @@ static u_int8_t handle_error(
|
|||||||
){
|
){
|
||||||
u_int8_t exit_code;
|
u_int8_t exit_code;
|
||||||
|
|
||||||
|
(void)msh;
|
||||||
|
exit_code = 0;
|
||||||
if (access(path, F_OK) != -1)
|
if (access(path, F_OK) != -1)
|
||||||
// No such file or directory
|
// No such file or directory
|
||||||
exit_code = 1;
|
exit_code = 1;
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
|
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/10/31 02:41:11 by sede-san #+# #+# */
|
/* Created: 2025/10/31 02:41:11 by sede-san #+# #+# */
|
||||||
/* Updated: 2025/11/02 03:12:00 by sede-san ### ########.fr */
|
/* Updated: 2025/12/01 18:05:51 by sede-san ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@@ -14,11 +14,13 @@
|
|||||||
#include "echo_def.h"
|
#include "echo_def.h"
|
||||||
|
|
||||||
u_int8_t builtin_echo(
|
u_int8_t builtin_echo(
|
||||||
t_command cmd
|
t_command cmd,
|
||||||
|
t_minishell *msh
|
||||||
){
|
){
|
||||||
const t_args args = read_args(cmd);
|
const t_args args = read_args(cmd);
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
|
(void)msh;
|
||||||
i = -1;
|
i = -1;
|
||||||
while (args.strings.data.sp[++i])
|
while (args.strings.data.sp[++i])
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
|
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/10/30 01:20:48 by sede-san #+# #+# */
|
/* Created: 2025/10/30 01:20:48 by sede-san #+# #+# */
|
||||||
/* Updated: 2025/10/30 09:08:02 by sede-san ### ########.fr */
|
/* Updated: 2025/12/01 19:15:08 by sede-san ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@ u_int8_t builtin_exit(
|
|||||||
ft_eputendl("exit");
|
ft_eputendl("exit");
|
||||||
if (cmd.argc == 1)
|
if (cmd.argc == 1)
|
||||||
{
|
{
|
||||||
// msh.exit = 1;
|
msh->exit = 1;
|
||||||
// return the last exit_status, if none 0 is returned
|
// return the last exit_status, if none 0 is returned
|
||||||
return (msh->exit_status);
|
return (msh->exit_status);
|
||||||
}
|
}
|
||||||
@@ -37,7 +37,7 @@ u_int8_t builtin_exit(
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// msh.exit = 1;
|
msh->exit = 1;
|
||||||
// cast to u_int8_t causes to return a value between 0 and 255
|
// cast to u_int8_t causes to return a value between 0 and 255
|
||||||
return ((u_int8_t)ft_atol(cmd.argv[1]));
|
return ((u_int8_t)ft_atol(cmd.argv[1]));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
|
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/10/29 22:08:55 by sede-san #+# #+# */
|
/* Created: 2025/10/29 22:08:55 by sede-san #+# #+# */
|
||||||
/* Updated: 2025/10/30 01:14:09 by sede-san ### ########.fr */
|
/* Updated: 2025/12/01 16:27:08 by sede-san ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ u_int8_t builtin_pwd(
|
|||||||
|
|
||||||
(void)cmd;
|
(void)cmd;
|
||||||
(void)msh;
|
(void)msh;
|
||||||
getcwd(cwd, PATH_MAX);
|
if (getcwd(cwd, PATH_MAX) != NULL)
|
||||||
printf("%s\n", cwd);
|
ft_putendl(cwd);
|
||||||
return (EXIT_SUCCESS);
|
return (EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,37 +6,38 @@
|
|||||||
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
|
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/10/28 13:03:44 by sede-san #+# #+# */
|
/* Created: 2025/10/28 13:03:44 by sede-san #+# #+# */
|
||||||
/* Updated: 2025/10/29 20:37:09 by sede-san ### ########.fr */
|
/* Updated: 2025/12/02 09:07:28 by sede-san ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#include "executor.h"
|
#include "executor.h"
|
||||||
|
#include "builtins.h"
|
||||||
|
|
||||||
static char *solve_path(char *cmd_name, t_minishell *msh);
|
static char *solve_path(char *cmd_name, t_minishell *msh);
|
||||||
static u_int8_t path_is_solved(char *cmd_name);
|
static u_int8_t path_is_solved(char *cmd_name, t_minishell *msh);
|
||||||
static void handle_child(t_command *cmd, t_minishell *msh);
|
static void handle_child(t_command *cmd, t_minishell *msh);
|
||||||
static void handle_parent(pid_t child_pid, t_command *cmd, t_minishell *msh);
|
static void handle_parent(pid_t child_pid, t_command *cmd, t_minishell *msh);
|
||||||
|
|
||||||
u_int8_t execute(
|
u_int8_t execute(
|
||||||
t_command cmd,
|
t_command cmd,
|
||||||
t_minishell *msh
|
t_minishell *msh
|
||||||
){
|
) {
|
||||||
pid_t child_pid;
|
pid_t child_pid;
|
||||||
|
|
||||||
cmd.path = solve_path(cmd.argv[0], msh);
|
cmd.path = solve_path(cmd.argv[0], msh);
|
||||||
if (!cmd.path)
|
if (!cmd.path)
|
||||||
{
|
{
|
||||||
// command not found
|
|
||||||
ft_eprintf("minishell: %s: command not found\n", cmd.argv[0]);
|
ft_eprintf("minishell: %s: command not found\n", cmd.argv[0]);
|
||||||
return (msh->exit_status = 127, msh->exit_status);
|
return (msh->exit_status = 127, msh->exit_status);
|
||||||
}
|
}
|
||||||
if (access(cmd.path, X_OK) != EXIT_SUCCESS)
|
if (!is_builtin(cmd.path, msh) && access(cmd.path, X_OK) != EXIT_SUCCESS)
|
||||||
{
|
{
|
||||||
// permission denied
|
|
||||||
ft_eputstr("minishell: ");
|
ft_eputstr("minishell: ");
|
||||||
perror(cmd.path);
|
perror(cmd.path);
|
||||||
return (msh->exit_status = 126, msh->exit_status);
|
return (msh->exit_status = 126, msh->exit_status);
|
||||||
}
|
}
|
||||||
|
child_pid = 0;
|
||||||
|
if (!is_builtin(cmd.path, msh))
|
||||||
child_pid = fork();
|
child_pid = fork();
|
||||||
if (child_pid == -1)
|
if (child_pid == -1)
|
||||||
perror("minishell");
|
perror("minishell");
|
||||||
@@ -55,14 +56,12 @@ static char *solve_path(
|
|||||||
char **path;
|
char **path;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
if (path_is_solved(cmd_name))
|
if (path_is_solved(cmd_name, msh))
|
||||||
// return a copy to avoid double free on parent
|
// return a copy to avoid double free on parent
|
||||||
return (ft_strdup(cmd_name));
|
return (ft_strdup(cmd_name));
|
||||||
//TODO substitute getenv call for own getenv
|
path = ft_split(get_env("PATH", msh), COLON);
|
||||||
path = ft_split(getenv("PATH"), COLON);
|
|
||||||
if (!path)
|
if (!path)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
(void)msh;
|
|
||||||
cmd_path = NULL;
|
cmd_path = NULL;
|
||||||
i = -1;
|
i = -1;
|
||||||
while (!cmd_path && path[++i])
|
while (!cmd_path && path[++i])
|
||||||
@@ -90,11 +89,13 @@ static char *solve_path(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static u_int8_t path_is_solved(
|
static u_int8_t path_is_solved(
|
||||||
char *cmd_name
|
char *cmd_name,
|
||||||
|
t_minishell *msh
|
||||||
){
|
){
|
||||||
return (ft_strncmp(cmd_name, "/", 1) == 0
|
return (ft_strncmp(cmd_name, "/", 1) == 0
|
||||||
|| (cmd_name[1] && ft_strncmp(cmd_name, "./", 2) == 0)
|
|| (cmd_name[1] && ft_strncmp(cmd_name, "./", 2) == 0)
|
||||||
|| (cmd_name[2] && ft_strncmp(cmd_name, "../", 3) == 0)
|
|| (cmd_name[2] && ft_strncmp(cmd_name, "../", 3) == 0)
|
||||||
|
|| is_builtin(cmd_name, msh)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,7 +103,20 @@ static void handle_child(
|
|||||||
t_command *cmd,
|
t_command *cmd,
|
||||||
t_minishell *msh
|
t_minishell *msh
|
||||||
){
|
){
|
||||||
execve(cmd->path, cmd->argv, msh->variables.environment);
|
char **envp;
|
||||||
|
t_builtin_func builtin;
|
||||||
|
|
||||||
|
if (is_builtin(cmd->argv[0], msh))
|
||||||
|
{
|
||||||
|
builtin = ft_hashmap_get(msh->builtins, cmd->argv[0]);
|
||||||
|
builtin(*cmd, msh);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
envp = get_envp(msh);
|
||||||
|
execve(cmd->path, cmd->argv, envp);
|
||||||
|
free_envp(envp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_parent(
|
static void handle_parent(
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
|
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/10/20 20:51:33 by sede-san #+# #+# */
|
/* Created: 2025/10/20 20:51:33 by sede-san #+# #+# */
|
||||||
/* Updated: 2025/10/30 22:36:03 by sede-san ### ########.fr */
|
/* Updated: 2025/12/01 19:02:18 by sede-san ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@@ -17,7 +17,13 @@ int minishell_init(
|
|||||||
char **envp
|
char **envp
|
||||||
){
|
){
|
||||||
ft_bzero(minishell, sizeof(t_minishell));
|
ft_bzero(minishell, sizeof(t_minishell));
|
||||||
minishell->variables.environment = envp;
|
set_envp(envp, minishell);
|
||||||
|
set_builtins(minishell);
|
||||||
|
if (minishell->variables.environment == NULL || minishell->builtins == NULL)
|
||||||
|
{
|
||||||
|
minishell_clear(minishell);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,7 +34,7 @@ u_int8_t minishell_run(
|
|||||||
t_command command;
|
t_command command;
|
||||||
|
|
||||||
line = NULL;
|
line = NULL;
|
||||||
while (!minishell->exit)
|
while (minishell->exit == 0)
|
||||||
{
|
{
|
||||||
line = readline("minishell > ");
|
line = readline("minishell > ");
|
||||||
if (*line)
|
if (*line)
|
||||||
@@ -46,5 +52,9 @@ void minishell_clear(
|
|||||||
t_minishell *minishell
|
t_minishell *minishell
|
||||||
){
|
){
|
||||||
rl_clear_history();
|
rl_clear_history();
|
||||||
|
if (minishell->variables.environment != NULL)
|
||||||
|
ft_hashmap_clear(&minishell->variables.environment, free);
|
||||||
|
if (minishell->builtins != NULL)
|
||||||
|
ft_hashmap_clear_keys(&minishell->builtins);
|
||||||
ft_bzero(minishell, sizeof(t_minishell));
|
ft_bzero(minishell, sizeof(t_minishell));
|
||||||
}
|
}
|
||||||
|
|||||||
179
src/variables/environment.c
Normal file
179
src/variables/environment.c
Normal file
@@ -0,0 +1,179 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* environment.c :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2025/12/01 09:12:39 by sede-san #+# #+# */
|
||||||
|
/* Updated: 2025/12/01 17:27:57 by sede-san ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include "minishell.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Parses and stores environment variables from envp array into a hashmap
|
||||||
|
*
|
||||||
|
* This function iterates through the environment variables array (envp) and
|
||||||
|
* splits each variable string on the '=' delimiter to separate the variable
|
||||||
|
* name from its value. Each name-value pair is then stored in the minishell's
|
||||||
|
* environment hashmap for later retrieval.
|
||||||
|
*
|
||||||
|
* @param envp Array of environment variable strings in "NAME=value" format
|
||||||
|
* @param msh Pointer to the minishell structure containing the environment
|
||||||
|
* hashmap
|
||||||
|
*
|
||||||
|
* @note The function assumes envp strings are in the standard format
|
||||||
|
* "NAME=value"
|
||||||
|
*/
|
||||||
|
void set_envp(
|
||||||
|
char **envp,
|
||||||
|
t_minishell *msh
|
||||||
|
) {
|
||||||
|
char **splitted_env;
|
||||||
|
|
||||||
|
msh->variables.environment
|
||||||
|
= ft_hashmap_new(32, ft_hashmap_hashstr, ft_hashmap_strcmp);
|
||||||
|
if (msh == NULL)
|
||||||
|
{
|
||||||
|
ft_hashmap_clear(&msh->variables.environment, free);
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
while (*envp != NULL)
|
||||||
|
{
|
||||||
|
splitted_env = ft_split(*envp, '=');
|
||||||
|
if (splitted_env == NULL)
|
||||||
|
{
|
||||||
|
ft_hashmap_clear(&msh->variables.environment, free);
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
ft_hashmap_put(msh->variables.environment,
|
||||||
|
ft_strdup(splitted_env[0]), ft_strdup(splitted_env[1]));
|
||||||
|
ft_free_split(splitted_env);
|
||||||
|
envp++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets an environment variable in the minishell's environment hashmap.
|
||||||
|
*
|
||||||
|
* This function adds a new environment variable or updates an existing one
|
||||||
|
* in the minishell's environment hashmap. If the variable already exists,
|
||||||
|
* the old value is freed to prevent memory leaks. If the variable is new,
|
||||||
|
* a duplicate of the key name is created for storage.
|
||||||
|
*
|
||||||
|
* @param env_name The name of the environment variable to set
|
||||||
|
* @param env_value The value to assign to the environment variable
|
||||||
|
* @param msh Pointer to the minishell structure containing the
|
||||||
|
* environment hashmap
|
||||||
|
*/
|
||||||
|
void set_env(
|
||||||
|
const char *env_name,
|
||||||
|
char *env_value,
|
||||||
|
t_minishell *msh
|
||||||
|
) {
|
||||||
|
t_hashmap *environment;
|
||||||
|
const char *key;
|
||||||
|
char *old_value;
|
||||||
|
|
||||||
|
environment = msh->variables.environment;
|
||||||
|
key = env_name;
|
||||||
|
if (!ft_hashmap_contains_key(environment, key))
|
||||||
|
key = ft_strdup(env_name);
|
||||||
|
old_value = ft_hashmap_put(environment, key, ft_strdup(env_value));
|
||||||
|
if (old_value != NULL)
|
||||||
|
free(old_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Converts the environment variables hashmap to an envp array format.
|
||||||
|
*
|
||||||
|
* This function extracts all environment variables from the minishell's
|
||||||
|
* environment hashmap and converts them into a NULL-terminated array of
|
||||||
|
* strings in the format "KEY=VALUE".
|
||||||
|
*
|
||||||
|
* @param msh Pointer to the minishell structure containing the environment
|
||||||
|
* variables hashmap.
|
||||||
|
*
|
||||||
|
* @return A dynamically allocated array of strings representing environment
|
||||||
|
* variables in "KEY=VALUE" format, terminated by NULL. Returns NULL
|
||||||
|
* if memory allocation fails. The caller is responsible for freeing
|
||||||
|
* the returned array and its individual string elements using
|
||||||
|
* the `free_envp()` function.
|
||||||
|
*
|
||||||
|
* @note The function allocates memory for both the array and individual
|
||||||
|
* strings using malloc and ft_strnjoin respectively.
|
||||||
|
* @note The returned array size is environment->size + 1 to accommodate
|
||||||
|
* the NULL terminator.
|
||||||
|
*/
|
||||||
|
char **get_envp(
|
||||||
|
t_minishell *msh
|
||||||
|
) {
|
||||||
|
char **envp;
|
||||||
|
t_list *env_list;
|
||||||
|
t_list *env;
|
||||||
|
t_map_entry *entry;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
env_list = ft_hashmap_entries(msh->variables.environment);
|
||||||
|
envp = (char **)malloc(
|
||||||
|
(msh->variables.environment->size + 1) * sizeof(char *));
|
||||||
|
if (envp != NULL)
|
||||||
|
{
|
||||||
|
i = 0;
|
||||||
|
env = env_list;
|
||||||
|
while (env != NULL)
|
||||||
|
{
|
||||||
|
entry = env->content;
|
||||||
|
envp[i++] = ft_strnjoin(3, entry->key, "=", entry->value);
|
||||||
|
env = env->next;
|
||||||
|
}
|
||||||
|
envp[i] = NULL;
|
||||||
|
}
|
||||||
|
ft_lstclear_nodes(&env_list);
|
||||||
|
return (envp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Frees a dynamically allocated environment variables array
|
||||||
|
*
|
||||||
|
* This function deallocates memory for an array of strings that was previously
|
||||||
|
* allocated by `get_envp()`. It iterates through each string in the array,
|
||||||
|
* frees the memory for individual strings, and then frees the array itself.
|
||||||
|
*
|
||||||
|
* @param envp Pointer to the array of environment variable strings to be freed.
|
||||||
|
* Each string in the array should be dynamically allocated.
|
||||||
|
* The array must be NULL-terminated.
|
||||||
|
*/
|
||||||
|
void free_envp(
|
||||||
|
char **envp
|
||||||
|
) {
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
i = -1;
|
||||||
|
while (envp[++i] != NULL)
|
||||||
|
free(envp[i]);
|
||||||
|
free(envp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Retrieves the value of an environment variable from the shell's
|
||||||
|
* environment hashmap.
|
||||||
|
*
|
||||||
|
* This function searches for the specified environment variable name in the
|
||||||
|
* minishell's environment variable hashmap and returns its associated value.
|
||||||
|
*
|
||||||
|
* @param env_name The name of the environment variable to retrieve (e.g.,
|
||||||
|
* "PATH", "HOME")
|
||||||
|
* @param msh Pointer to the minishell structure containing the environment
|
||||||
|
* variables hashmap
|
||||||
|
*
|
||||||
|
* @return The value of the environment variable if found, NULL if not found
|
||||||
|
*/
|
||||||
|
char *get_env(
|
||||||
|
const char *env_name,
|
||||||
|
t_minishell *msh
|
||||||
|
) {
|
||||||
|
return (ft_hashmap_get(msh->variables.environment, env_name));
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user