saved changes before repartition

This commit is contained in:
2025-09-12 12:41:24 +02:00
parent 8158998fbb
commit 161ac6b69d
26 changed files with 528 additions and 150 deletions

3
.gitignore vendored
View File

@@ -7,6 +7,9 @@ minishell
# Libraries path # Libraries path
/lib /lib
# Todo path
/src/todo
# VSCode # VSCode
/.vscode /.vscode

View File

@@ -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/08/03 23:38:53 by sede-san ### ########.fr # # Updated: 2025/08/20 22:40:43 by sede-san ### ########.fr #
# # # #
# **************************************************************************** # # **************************************************************************** #
@@ -58,17 +58,20 @@ SRC_PATH = src
# Source files # Source files
SRC = \ SRC = \
$(SRC_PATH)/minishell.c \ $(SRC_PATH)/minishell.c \
$(SRC_PATH)/builtins/cd.c \ $(SRC_PATH)/commands/command_utils.c \
$(SRC_PATH)/builtins/echo.c \ $(SRC_PATH)/commands/exec.c \
$(SRC_PATH)/builtins/env.c \ $(SRC_PATH)/commands/parse.c \
$(SRC_PATH)/builtins/exit.c \ $(SRC_PATH)/features/builtins/builtin_utils.c \
$(SRC_PATH)/builtins/export.c \ $(SRC_PATH)/features/builtins/cd.c \
$(SRC_PATH)/builtins/pwd.c \ $(SRC_PATH)/features/builtins/echo.c \
$(SRC_PATH)/builtins/unset.c \ $(SRC_PATH)/features/builtins/exit.c \
$(SRC_PATH)/commands/exec.c \ $(SRC_PATH)/features/builtins/export.c \
$(SRC_PATH)/commands/parse.c \ $(SRC_PATH)/features/builtins/printenv.c \
$(SRC_PATH)/utils/get_hostname.c $(SRC_PATH)/features/builtins/pwd.c \
$(SRC_PATH)/features/builtins/unset.c \
$(SRC_PATH)/utils/get_hostname.c \
$(SRC_PATH)/utils/signals.c
# Include path # Include path
INCLUDE_PATH = ./include INCLUDE_PATH = ./include
@@ -119,6 +122,7 @@ fclean: clean
@echo "$(GREEN)$(EMOJI_CHECK) Binaries cleaned.$(RESET)" @echo "$(GREEN)$(EMOJI_CHECK) Binaries cleaned.$(RESET)"
.PHONY: fclean .PHONY: fclean
# Delete libraries, object files and binaries
update: fclean update: fclean
@echo "$(RED)$(EMOJI_BROOM) Removing libraries...$(RESET)" @echo "$(RED)$(EMOJI_BROOM) Removing libraries...$(RESET)"
@rm -rf $(LIB_PATH) @rm -rf $(LIB_PATH)
@@ -128,6 +132,7 @@ update: fclean
@echo "$(GREEN)$(EMOJI_CHECK) Updated.$(RESET)" @echo "$(GREEN)$(EMOJI_CHECK) Updated.$(RESET)"
@echo "$(YELLOW)$(EMOJI_WRENCH) Recompiling...$(RESET)" @echo "$(YELLOW)$(EMOJI_WRENCH) Recompiling...$(RESET)"
@$(MAKE) @$(MAKE)
.PHONY: update
# Recompile # Recompile
re: fclean all re: fclean all

23
README.md Normal file
View File

@@ -0,0 +1,23 @@
## Dependencies
- Debian/Ubuntu
```
sudo apt-get install make libreadline-dev
```
## How to install
1. Clone the repository
```
git clone https://github.com/sdevsantiago/minishell.git && cd minishell
```
2. Build the project
```
make && make clean
```
3. Execute the program
```
./minishell
```

17
docs/tests.md Normal file
View File

@@ -0,0 +1,17 @@
### Multiple redirections
```
cmd > file1 > file2
```
or
```
cmd >> file1 >> file2
```
Should create both `file1` and `file2` but store the output in `file2`
### Environment variables
#### SHLVL
Must be increased by 1 if executed from any other shell or 1 if executed

View File

@@ -6,7 +6,7 @@
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */ /* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2025/08/01 17:18:21 by sede-san #+# #+# */ /* Created: 2025/08/01 17:18:21 by sede-san #+# #+# */
/* Updated: 2025/08/02 17:55:22 by sede-san ### ########.fr */ /* Updated: 2025/08/20 22:22:40 by sede-san ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@@ -16,18 +16,12 @@
# include <string.h> # include <string.h>
# include <stdio.h> # include <stdio.h>
typedef int (*t_builtin_func)(int argc, char const *argv[]);
typedef struct s_builtin
{
const char *name;
t_builtin_func function;
} t_builtin;
// cd.c // cd.c
int cd_builtin(int argc, char const *argv[]); int cd_builtin(int argc, char const *argv[]);
# define CD_HELP
// echo.c // echo.c
typedef struct s_echo_flags typedef struct s_echo_flags
@@ -37,24 +31,40 @@ typedef struct s_echo_flags
int echo_builtin(int argc, char const *argv[]); int echo_builtin(int argc, char const *argv[]);
// env.c # define ECHO_HELP
int env_builtin(int argc, char const *argv[]); // // env.c
// int env_builtin(int argc, char const *argv[], char **envp);
// exit.c // exit.c
int exit_builtin(int argc, char const *argv[]); int exit_builtin(int argc, char const *argv[]);
# define EXIT_HELP
// export.c // export.c
int export_builtin(int argc, char const *argv[]); int export_builtin(int argc, char const *argv[], char **envp);
# define EXPORT_HELP
// printenv.c
int printenv_builtin(int argc, char const *argv[], char const *envp[]);
# define PRINTENV_HELP
// pwd.c // pwd.c
int pwd_builtin(int argc, char const *argv[]); int pwd_builtin(int argc, char const *argv[]);
# define PWD_HELP
// unset.c // unset.c
int unset_builtin(int argc, char const *argv[]); int unset_builtin(int argc, char const *argv[], char **envp);
# define UNSET_HELP
#endif #endif

20
include/history.h Normal file
View File

@@ -0,0 +1,20 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* history.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/08/20 22:07:04 by sede-san #+# #+# */
/* Updated: 2025/08/21 14:43:08 by sede-san ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef HISTORY_H
# define HISTORY_H
// history.c
#endif

View File

@@ -6,7 +6,7 @@
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */ /* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2025/07/31 03:42:51 by sede-san #+# #+# */ /* Created: 2025/07/31 03:42:51 by sede-san #+# #+# */
/* Updated: 2025/08/03 22:56:35 by sede-san ### ########.fr */ /* Updated: 2025/08/21 14:55:18 by sede-san ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@@ -14,6 +14,7 @@
# define MINISHELL_H # define MINISHELL_H
# include "builtins.h" # include "builtins.h"
# include "history.h"
# include "libft.h" # include "libft.h"
# include "get_next_line.h" # include "get_next_line.h"
# include <fcntl.h> # include <fcntl.h>
@@ -26,32 +27,61 @@ typedef struct s_cmd
{ {
int argc; int argc;
char **argv; char **argv;
char **envp; } t_cmd;
} t_cmd;
# define HISTORY_FILE "/.minishell_history" typedef struct s_history
{
char *hist_file;
size_t hist_file_size;
t_cdlist hist;
size_t hist_size;
} t_history;
typedef struct s_minishell typedef struct s_minishell
{ {
char *history_file; char **envp;
char **envp; t_history *history;
} t_minishell; char *history_file;
} t_minishell;
/* ******************************** Features ******************************** */
/* History */
// history.c
void ms_add_history(const char *line);
int ms_read_history(const char *hist_file);
void ms_write_history(const char *hist_file);
/* ******************************* Commands ********************************* */ /* ******************************* Commands ********************************* */
typedef int (*t_msh_cmdfunc)(char **args, char **env, t_minishell* minshell); // command_utils.c
int is_absolutepath(char const *cmd);
int is_builtin(t_cmd *cmd);
int is_local(char const *cmd);
// exec.c // exec.c
int exec_cmd(char *cmd, char **args, t_minishell *minishell); int exec_cmd(t_cmd *cmd, char **envp);
int exec_builtin(t_cmd *cmd, char **envp);
// parse.c // parse.c
t_cmd parse_cmd(char *line, t_minishell *minishell); t_cmd parse_cmd(char *line, t_minishell *minishell);
// signals.c
void init_signal(void);
/* ********************************* Utils ********************************** */ /* ********************************* Utils ********************************** */
// get_hostname.c // get_hostname.c
char *get_hostname(void); char *get_hostname(void);
/* ******************************** Builtins ******************************** */
// builtin_utils.c
int is_builtin(t_cmd *cmd);
#endif #endif

View File

@@ -0,0 +1,36 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* command_utils.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/08/05 19:52:37 by sede-san #+# #+# */
/* Updated: 2025/08/20 22:15:22 by sede-san ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
int is_absolutepath(
char const *cmd)
{
return (cmd[0] == '/');
}
/**
* @brief Checks if the given command string refers to a local executable.
*
* This function determines whether the provided command string starts with
* "./", which is a common convention for executing local files in Unix-like
* systems.
*
* @param cmd The command string to check.
*
* @return 1 if the command starts with "./", 0 otherwise.
*/
int is_local(
char const *cmd)
{
return (cmd[0] == '.' && cmd[1] == '/');
}

View File

@@ -6,15 +6,49 @@
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */ /* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2025/08/01 16:24:47 by sede-san #+# #+# */ /* Created: 2025/08/01 16:24:47 by sede-san #+# #+# */
/* Updated: 2025/08/03 23:39:07 by sede-san ### ########.fr */ /* Updated: 2025/08/05 20:21:27 by sede-san ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
#include "minishell.h" #include "minishell.h"
// int exec_cmd( int exec_builtin(
// t_cmd cmd, t_cmd *cmd,
// t_minishell *minishell) char **envp)
// { {
if (ft_strncmp(cmd->argv[0], "cd\0", 3) == 0)
return (cd_builtin(cmd->argc, (char const **)cmd->argv));
else if (ft_strncmp(cmd->argv[0], "echo\0", 5) == 0)
return (echo_builtin(cmd->argc, (char const **)cmd->argv));
// else if (ft_strncmp(cmd->argv[0], "env\0", 4) == 0)
// return (env_builtin(cmd->argc, (char const **)cmd->argv, envp));
// else if (ft_strncmp(cmd->argv[0], "exit\0", 5) == 0)
// return (exit_builtin(cmd->argc, (char const **)cmd->argv));
else if (ft_strncmp(cmd->argv[0], "export\0", 7) == 0)
return (export_builtin(cmd->argc, (char const **)cmd->argv, envp));
else if ((ft_strncmp(cmd->argv[0], "env\0", 4) == 0 && cmd->argc == 1)
|| ft_strncmp(cmd->argv[0], "printenv\0", 9) == 0)
return (printenv_builtin(
cmd->argc, (char const **)cmd->argv, (char const **)envp));
else if (ft_strncmp(cmd->argv[0], "pwd\0", 4) == 0)
return (pwd_builtin(cmd->argc, (char const **)cmd->argv));
else if (ft_strncmp(cmd->argv[0], "unset\0", 6) == 0)
return (unset_builtin(cmd->argc, (char const **)cmd->argv, envp));
return (1);
}
int exec_cmd(
t_cmd *cmd,
char **envp)
{
int exit_code;
pid_t pid;
exit_code = 0;
pid = fork();
if (pid == 0)
exit_code = execve(cmd->argv[0], cmd->argv, envp);
waitpid(pid, NULL, 0);
return (exit_code);
}
// }

View File

@@ -6,14 +6,12 @@
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */ /* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2025/08/01 16:40:35 by sede-san #+# #+# */ /* Created: 2025/08/01 16:40:35 by sede-san #+# #+# */
/* Updated: 2025/08/04 00:28:53 by sede-san ### ########.fr */ /* Updated: 2025/08/05 19:56:15 by sede-san ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
#include "minishell.h" #include "minishell.h"
static int is_local(char const *cmd);
static int is_builtin(char const *cmd);
static char *resolve_cmd_path(char const *cmd, char const *path); static char *resolve_cmd_path(char const *cmd, char const *path);
/** /**
@@ -29,6 +27,8 @@ static char *resolve_cmd_path(char const *cmd, char const *path);
* @return t_cmd The parsed command structure containing the command path, * @return t_cmd The parsed command structure containing the command path,
* argument vector, and argument count. * argument vector, and argument count.
* *
* @todo Manage double quote
*
* @note The string array cmd.argv must be freed after the command has been * @note The string array cmd.argv must be freed after the command has been
* executed. * executed.
*/ */
@@ -46,7 +46,8 @@ t_cmd parse_cmd(
cmd.argc = 0; cmd.argc = 0;
while (cmd.argv[cmd.argc]) while (cmd.argv[cmd.argc])
cmd.argc++; cmd.argc++;
if (!is_local(cmd.argv[0]) && !is_builtin(cmd.argv[0])) if (!is_local(cmd.argv[0]) && !is_absolutepath(cmd.argv[0])
&& !is_builtin(&cmd))
{ {
abs_path = resolve_cmd_path(cmd.argv[0], getenv("PATH")); abs_path = resolve_cmd_path(cmd.argv[0], getenv("PATH"));
if (abs_path) if (abs_path)
@@ -58,47 +59,6 @@ t_cmd parse_cmd(
return (cmd); return (cmd);
} }
/**
* @brief Checks if the given command string refers to a local executable.
*
* This function determines whether the provided command string starts with
* "./", which is a common convention for executing local files in Unix-like
* systems.
*
* @param cmd The command string to check.
*
* @return 1 if the command starts with "./", 0 otherwise.
*/
static int is_local(
char const *cmd)
{
return (cmd[0] == '.' && cmd[1] == '/');
}
/**
* @brief Checks if the given command is a shell builtin.
*
* This function compares the input command string against a list of known
* shell builtin commands ("cd", "echo", "env", "exit", "export", "pwd",
* "unset"). It returns a non-zero value if the command matches any of these
* builtins, otherwise returns 0.
*
* @param cmd The command string to check.
*
* @return int Non-zero if the command is a builtin, 0 otherwise.
*/
static int is_builtin(
char const *cmd)
{
return (!ft_strncmp(cmd, "cd\0", 3)
|| !ft_strncmp(cmd, "echo\0", 5)
|| !ft_strncmp(cmd, "env\0", 4)
|| !ft_strncmp(cmd, "exit\0", 5)
|| !ft_strncmp(cmd, "export\0", 7)
|| !ft_strncmp(cmd, "pwd\0", 4)
|| !ft_strncmp(cmd, "unset\0", 6));
}
static char *resolve_cmd_path(char const *cmd, char const *path) static char *resolve_cmd_path(char const *cmd, char const *path)
{ {
char *abs_path; char *abs_path;
@@ -111,8 +71,10 @@ static char *resolve_cmd_path(char const *cmd, char const *path)
{ {
abs_path = ft_strjoin_mul( abs_path = ft_strjoin_mul(
3, (char *)path_splitted[i], "/", (char *)cmd); 3, (char *)path_splitted[i], "/", (char *)cmd);
if (access(abs_path, F_OK) != -1) if (access(abs_path, X_OK) != -1)
break ; break ;
free(abs_path);
abs_path = NULL;
i++; i++;
} }
ft_free_split((char **)path_splitted); ft_free_split((char **)path_splitted);

View File

@@ -0,0 +1,38 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* builtin_utils.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/08/20 22:15:23 by sede-san #+# #+# */
/* Updated: 2025/08/20 22:48:11 by sede-san ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
/**
* @brief Checks if the given command is a shell builtin.
*
* This function compares the input command string against a list of known
* shell builtin commands ("cd", "echo", "env", "exit", "export", "pwd",
* "unset"). It returns a non-zero value if the command matches any of these
* builtins, otherwise returns 0.
*
* @param cmd The command string to check.
*
* @return int Non-zero if the command is a builtin, 0 otherwise.
*/
int is_builtin(
t_cmd *cmd)
{
return (ft_strncmp(cmd->argv[0], "cd\0", 3) == 0
|| ft_strncmp(cmd->argv[0], "echo\0", 5) == 0
|| (ft_strncmp(cmd->argv[0], "env\0", 4) == 0 && cmd->argc == 1)
|| ft_strncmp(cmd->argv[0], "exit\0", 5) == 0
|| ft_strncmp(cmd->argv[0], "export\0", 7) == 0
|| ft_strncmp(cmd->argv[0], "printenv\0", 9) == 0
|| ft_strncmp(cmd->argv[0], "pwd\0", 4) == 0
|| ft_strncmp(cmd->argv[0], "unset\0", 6) == 0);
}

View File

@@ -6,7 +6,7 @@
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */ /* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2025/08/01 11:09:13 by sede-san #+# #+# */ /* Created: 2025/08/01 11:09:13 by sede-san #+# #+# */
/* Updated: 2025/08/03 02:11:18 by sede-san ### ########.fr */ /* Updated: 2025/08/05 18:35:36 by sede-san ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@@ -22,7 +22,8 @@ int cd_builtin(
path = getenv("HOME"); path = getenv("HOME");
else else
path = (char *)argv[1]; path = (char *)argv[1];
// be aware of execution permission
if (chdir(path) != 0) if (chdir(path) != 0)
return (fprintf(stderr, "cd: %s\n", path), 1); return (fprintf(stderr, "cd: %s: %s\n", path, strerror(errno)), 1);
return (0); return (0);
} }

View File

@@ -6,7 +6,7 @@
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */ /* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2025/08/01 13:22:11 by sede-san #+# #+# */ /* Created: 2025/08/01 13:22:11 by sede-san #+# #+# */
/* Updated: 2025/08/03 02:15:38 by sede-san ### ########.fr */ /* Updated: 2025/08/05 09:22:15 by sede-san ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@@ -72,6 +72,8 @@ static t_echo_flags set_flags(
set_default_flags(&flags); set_default_flags(&flags);
*i = 1; *i = 1;
if (!argv[1])
return (flags);
while (*argv[*i] == '-') while (*argv[*i] == '-')
{ {
j = 1; j = 1;

View File

@@ -6,31 +6,32 @@
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */ /* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2025/08/01 14:15:09 by sede-san #+# #+# */ /* Created: 2025/08/01 14:15:09 by sede-san #+# #+# */
/* Updated: 2025/08/03 02:33:30 by sede-san ### ########.fr */ /* Updated: 2025/08/07 17:21:24 by sede-san ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
#include "minishell.h" #include "minishell.h"
// static void printenv(char **envp); static void printenv(char **envp);
int env_builtin( int env_builtin(
int argc, int argc,
char const *argv[]) char const *argv[],
char **envp)
{ {
// (void)envp;
(void)argc; (void)argc;
(void)argv; (void)argv;
// if (!argv || !*argv) printenv(envp);
// printenv(envp);
return (0); return (0);
} }
// static void printenv( static void printenv(
// char **envp) char **envp)
// { {
// size_t i; size_t i;
// i = 0; i = 0;
// while (envp[i]) while (envp[i])
// ft_putendl(envp[i++]); ft_putendl(envp[i++]);
// } }

View File

@@ -6,7 +6,7 @@
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */ /* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2025/08/01 14:38:18 by sede-san #+# #+# */ /* Created: 2025/08/01 14:38:18 by sede-san #+# #+# */
/* Updated: 2025/08/05 09:39:25 by sede-san ### ########.fr */ /* Updated: 2025/08/05 18:45:33 by sede-san ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */

View File

@@ -0,0 +1,38 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* export.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/08/04 21:38:45 by sede-san #+# #+# */
/* Updated: 2025/08/05 14:55:31 by sede-san ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
int export_builtin(int argc, char const *argv[], char **envp)
{
size_t i;
char **env;
(void)argv;
if (argc == 2)
{
i = 0;
env = ft_split(argv[1], '=');
while (envp[i]) // ENV=value
{
if (ft_strncmp(envp[i], env[0], ft_strlen(env[0])) == 0)
{
char *line = ft_strjoin_mul(3, env[0], "=", env[1]);
envp[i] = line;
break ;
}
i++;
}
ft_free_split(env);
}
return (0);
}

View File

@@ -0,0 +1,28 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* printenv.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/08/05 19:45:36 by sede-san #+# #+# */
/* Updated: 2025/08/05 20:19:10 by sede-san ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
int printenv_builtin(
int argc,
char const *argv[],
char const *envp[])
{
size_t i;
(void)argc;
(void)argv;
i = 0;
while (envp[i])
ft_putendl((char *)(envp[i++]));
return (0);
}

View File

View File

@@ -0,0 +1,27 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* type.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/08/20 22:12:49 by sede-san #+# #+# */
/* Updated: 2025/08/20 22:27:32 by sede-san ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
int type_builtin(
int argc,
char const *argv[])
{
int exit_code;
if (is_builtin((t_cmd*){argc, argv}))
{
printf("%s is a shell builtin\n", argv[0]);
exit_code = 0;
}
return (exit_code);
}

View File

@@ -0,0 +1,22 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* unset.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/08/04 21:39:35 by sede-san #+# #+# */
/* Updated: 2025/08/05 09:31:22 by sede-san ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
int unset_builtin(int argc, char const *argv[], char **envp)
{
(void)argc;
(void)argv;
(void)envp;
printf("Not yet implemented\n");
return (0);
}

View File

@@ -0,0 +1,40 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* history.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/08/20 22:06:47 by sede-san #+# #+# */
/* Updated: 2025/08/21 14:39:00 by sede-san ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
int ms_read_history(
const char *hist_file)
{
int fd;
char *line;
fd = open(hist_file, O_RDONLY);
if (fd == -1)
return (0);
line = get_next_line(fd);
while (line)
{
add_history(line);
free(&line);
line = get_next_line(fd);
}
if (line)
ft_free(&line);
close(fd);
}
void ms_write_history(
const char *hist_file)
{
}

View File

@@ -6,14 +6,14 @@
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */ /* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2025/07/31 03:42:25 by sede-san #+# #+# */ /* Created: 2025/07/31 03:42:25 by sede-san #+# #+# */
/* Updated: 2025/08/04 00:29:45 by sede-san ### ########.fr */ /* Updated: 2025/08/21 17:31:52 by sede-san ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
#include "minishell.h" #include "minishell.h"
static t_minishell init_minishell(char **envp); static t_minishell init_minishell(char **envp);
static void minishell(t_minishell *minishell, char **envp); static int minishell(t_minishell *minishell);
static void clear_minishell(t_minishell *minishell); static void clear_minishell(t_minishell *minishell);
/** /**
@@ -36,15 +36,19 @@ int main(
char **envp) char **envp)
{ {
t_minishell shell; t_minishell shell;
int exit_code;
(void)argv; (void)argv;
errno = 0; errno = 0;
if (argc != 1) if (argc != 1)
return (errno = EINVAL, errno); return (errno = EINVAL, errno);
init_signal();
shell = init_minishell(envp); shell = init_minishell(envp);
minishell(&shell, envp); if (errno)
fprintf(stderr, "minishell: %s\n" , strerror(errno));
exit_code = minishell(&shell);
clear_minishell(&shell); clear_minishell(&shell);
return (EXIT_SUCCESS); return (exit_code);
} }
/** /**
@@ -61,11 +65,16 @@ static t_minishell init_minishell(
char **envp) char **envp)
{ {
t_minishell minishell; t_minishell minishell;
size_t n_env;
ft_bzero(&minishell, sizeof(t_minishell)); ft_bzero(&minishell, sizeof(t_minishell));
minishell.history_file = ft_strjoin(getenv("HOME"), HISTORY_FILE); n_env = 0;
// minishell.path = ft_split(getenv("PATH"), ':'); while (envp[n_env])
minishell.envp = envp; n_env++;
minishell.envp = (char **)malloc(n_env * sizeof(char *));
if (!minishell.envp && errno == ENOMEM)
return (clear_minishell(&minishell), minishell);
minishell.history_file = ft_strjoin(getenv("HOME"), "/"HISTORY_FILE);
return (minishell); return (minishell);
} }
@@ -95,15 +104,15 @@ static t_minishell init_minishell(
* - Waits for the child process to finish. * - Waits for the child process to finish.
* - Cleans up allocated memory and clears the history on exit. * - Cleans up allocated memory and clears the history on exit.
*/ */
static void minishell(t_minishell *minishell, char **envp) static int minishell(t_minishell *minishell)
{ {
int exit_code;
char *line; char *line;
char *cmd; t_cmd cmd;
char *args[2];
pid_t pid;
exit_code = 0;
line = NULL; line = NULL;
read_history(minishell->history_file); // read_history(minishell->history_file);
while (1) while (1)
{ {
if (line) if (line)
@@ -113,7 +122,7 @@ static void minishell(t_minishell *minishell, char **envp)
if (hostname) if (hostname)
{ {
prompt = ft_strjoin_mul(12, prompt = ft_strjoin_mul(12,
BOLD, BLUE_TEXT, getenv("USER"), "@", hostname, BOLD, BLUE_TEXT, getenv("USERNAME"), "@", hostname,
RESET, ":", RESET, ":",
BOLD, GREEN_TEXT, getenv("PWD"), BOLD, GREEN_TEXT, getenv("PWD"),
RESET, "> "); RESET, "> ");
@@ -126,47 +135,39 @@ static void minishell(t_minishell *minishell, char **envp)
} }
else else
line = readline("minishell> "); line = readline("minishell> ");
if (!line && exit_builtin(1, NULL)) if (!line)
break ; {
write_history(minishell->history_file);
cmd = parse_cmd("exit", minishell);
exit_code = exit_builtin(cmd.argc, (const char **)cmd.argv);
if (exit_code != -1)
break ;
}
if (*line) if (*line)
{ {
add_history(line); add_history(line);
write_history(minishell->history_file); cmd = parse_cmd(line, minishell);
free(line);
t_cmd cmd_parse = parse_cmd(line, minishell); line = NULL;
// exec_cmd(); if (ft_strncmp(cmd.argv[0], "exit\0", 5) == 0)
// builtins
if (ft_strncmp("exit\0", line, 5) == 0 && exit_builtin(1, NULL) != -1)
break ;
else if (ft_strncmp("cd\0", line, 3) == 0)
cd_builtin(1, NULL);
else if (ft_strncmp("pwd\0", line, 4) == 0)
pwd_builtin(1, NULL);
else if (ft_strncmp("env\0", line, 4) == 0)
env_builtin(1, NULL);
else if (ft_strncmp("echo\0", line, 5) == 0)
echo_builtin(0, NULL);
// not builtins
else
{ {
// if string does not start with "./" exit_code = exit_builtin(cmd.argc, (const char **)cmd.argv);
cmd = ft_strjoin("/usr/bin/", line); write_history(minishell->history_file);
args[0] = line; if (exit_code != -1)
args[1] = NULL; break ;
pid = fork();
if (pid == 0)
{
execve(cmd, args, envp);
exit(0);
}
waitpid(pid, NULL, 0);
free(cmd);
} }
else if (is_builtin(&cmd))
exec_builtin(&cmd, minishell->envp);
else
exec_cmd(&cmd, minishell->envp);
} }
} }
write_history(minishell->history_file);
rl_clear_history(); rl_clear_history();
free(line); if (line)
free(line);
return (exit_code);
} }
/** /**
@@ -188,6 +189,5 @@ static void clear_minishell(
ft_bzero(minishell->history_file, ft_bzero(minishell->history_file,
ft_strlen(minishell->history_file) * sizeof(char)); ft_strlen(minishell->history_file) * sizeof(char));
free(minishell->history_file); free(minishell->history_file);
// ft_free_split(minishell->path);
ft_bzero(minishell, sizeof(t_minishell)); ft_bzero(minishell, sizeof(t_minishell));
} }

41
src/utils/signals.c Normal file
View File

@@ -0,0 +1,41 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* signals.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/08/05 19:06:16 by sede-san #+# #+# */
/* Updated: 2025/08/20 19:37:40 by sede-san ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
static void sighandler(int signal, siginfo_t *signal_info, void *context);
void init_signal(void)
{
struct sigaction signal;
signal.sa_sigaction = sighandler;
signal.sa_flags = SA_SIGINFO;
sigemptyset(&signal.sa_mask);
sigaddset(&signal.sa_mask, SIGINT);
sigaction(SIGINT, &signal, NULL);
}
static void sighandler(
int signal,
siginfo_t *signal_info,
void *context)
{
(void)signal_info;
(void)context;
if (signal == SIGINT)
{
rl_on_new_line();
rl_replace_line("", 0);
rl_redisplay();
}
}