minishell

This commit is contained in:
2023-12-12 17:32:54 +01:00
commit 196e143285
92 changed files with 4905 additions and 0 deletions

116
builtins/builtins.c Executable file
View File

@@ -0,0 +1,116 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* builtins.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/11/12 11:51:11 by fgras-ca #+# #+# */
/* Updated: 2023/12/09 14:06:48 by fgras-ca ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
int builtin_cd(char **args, t_minishell *shell)
{
(void)shell;
if (args[1] == NULL)
{
write(2, RED"minishell: expected argument to \"cd\"\n"RST, 44);
}
else
{
if (chdir(args[1]) != 0)
{
perror(RED"minishell"RST);
}
}
return (0);
}
int builtin_exit(char **args, t_minishell *shell)
{
long exit_code;
char *endptr;
char *error_message;
(void)shell;
if (args[1])
{
errno = 0;
exit_code = strtol(args[1], &endptr, 10);
if ((errno == ERANGE && (exit_code == LONG_MAX
|| exit_code == LONG_MIN)) || (errno != 0 && exit_code == 0)
|| (*endptr != '\0')
|| (exit_code < 0 || exit_code > 255))
{
error_message = "bash: exit: ";
write(STDERR_FILENO, error_message, strlen(error_message));
write(STDERR_FILENO, args[1], strlen(args[1]));
error_message = ": numeric argument required\n";
write(STDERR_FILENO, error_message, strlen(error_message));
return (1);
}
exit((int)exit_code);
}
exit(0);
}
int builtin_pwd(char **args, t_minishell *shell)
{
char cwd[1024];
(void)shell;
(void)args;
if (getcwd(cwd, sizeof(cwd)) != NULL)
{
printf("%s\n", cwd);
}
else
{
perror(RED"minishell"RST);
}
return (0);
}
int num_builtins(t_minishell *shell)
{
int count;
count = 0;
while (shell->builtin_str[count])
{
count++;
}
return (count);
}
int execute_builtin(char **args, t_minishell *shell)
{
int i;
int exit_status;
if (!args || !shell || !shell->builtin_str || !shell->builtin_func)
return (-1);
if (!args[0])
{
write(2, RED"Command not found: No such file or directory\n", 52);
return (-1);
}
i = 0;
while (i < num_builtins(shell))
{
if (shell->builtin_str[i] && ft_strcmp(args[0],
shell->builtin_str[i]) == 0)
{
if (shell->builtin_func[i])
{
exit_status = (*shell->builtin_func[i])(args, shell);
return (exit_status);
}
}
i++;
}
return (-1);
}

48
builtins/builtins_utils.c Executable file
View File

@@ -0,0 +1,48 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* builtins_utils.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/11/27 20:33:11 by fgras-ca #+# #+# */
/* Updated: 2023/12/08 23:02:49 by fgras-ca ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
char *extract_name(char *env_entry)
{
int len;
char *name;
len = 0;
while (env_entry[len] && env_entry[len] != '=')
len++;
name = malloc(len + 1);
if (!name)
return (NULL);
ft_strncpy(name, env_entry, len);
name[len] = '\0';
return (name);
}
char *extract_value(char *env_entry)
{
int i;
char *value;
i = 0;
while (env_entry[i] && env_entry[i] != '=')
i++;
if (!env_entry[i])
return (NULL);
value = ft_strdup(&env_entry[i + 1]);
return (value);
}
int builtin_echo_wrapper(char **args, t_minishell *shell)
{
return (builtin_echo(args, shell, STDOUT_FILENO));
}

58
builtins/echo.c Executable file
View File

@@ -0,0 +1,58 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* echo.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/11/11 18:27:30 by fgras-ca #+# #+# */
/* Updated: 2023/12/09 18:57:20 by fgras-ca ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
static int check_option(char *s)
{
int i;
i = 1;
if (s[0] != '-')
return (0);
while (s[i])
{
if (s[i] != 'n')
return (0);
i++;
}
return (1);
}
int builtin_echo(char **args, t_minishell *shell, int fd)
{
int i;
int newline;
char *output;
i = 1;
newline = 1;
(void)shell;
if (args[i] != NULL && check_option(args[i]))
{
newline = 0;
i++;
}
while (args[i] != NULL)
{
output = args[i];
write(fd, output, ft_strlen(output));
if (args[i + 1] != NULL)
{
write(fd, " ", 1);
}
i++;
}
if (newline)
write(fd, "\n", 1);
return (0);
}

29
builtins/env.c Executable file
View File

@@ -0,0 +1,29 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* env.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/11/15 17:36:35 by fgras-ca #+# #+# */
/* Updated: 2023/12/07 12:10:09 by fgras-ca ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
int builtin_env(char **args, t_minishell *shell)
{
int i;
char *env_var;
(void)args;
i = 0;
while (shell->environ[i])
{
env_var = shell->environ[i];
printf("%s\n", env_var);
i++;
}
return (0);
}

65
builtins/export.c Executable file
View File

@@ -0,0 +1,65 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* export.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/11/11 18:20:32 by fgras-ca #+# #+# */
/* Updated: 2023/12/07 12:11:19 by fgras-ca ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
static void print_env(char **env, int env_size)
{
int i;
char *name;
char *value;
i = 0;
while (i < env_size)
{
name = extract_name(env[i]);
value = extract_value(env[i]);
if (value)
{
printf("declare -x %s=\"%s\"\n", name, value);
free(value);
}
else
{
printf("declare -x %s\n", name);
}
free(name);
i++;
}
}
static void print_sorted_env(t_minishell *shell)
{
int env_size;
char **sorted_env;
env_size = count_env_vars(shell->environ);
sorted_env = copy_env(shell->environ, env_size);
if (!sorted_env)
return ;
sort_env(sorted_env, env_size);
print_env(sorted_env, env_size);
free(sorted_env);
}
int builtin_export(char **args, t_minishell *shell)
{
if (args[1] == NULL)
{
print_sorted_env(shell);
return (0);
}
else
{
return (export_set_env(args, shell));
}
}

66
builtins/export_env.c Executable file
View File

@@ -0,0 +1,66 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* export_env.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/12/01 10:49:41 by fgras-ca #+# #+# */
/* Updated: 2023/12/07 12:19:27 by fgras-ca ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
int count_env_vars(char **environ)
{
int count;
count = 0;
while (environ[count])
count++;
return (count);
}
char **copy_env(char **environ, int env_size)
{
char **env_copy;
int i;
env_copy = malloc((env_size + 1) * sizeof(char *));
if (!env_copy)
return (NULL);
i = 0;
while (i < env_size)
{
env_copy[i] = environ[i];
i++;
}
env_copy[env_size] = NULL;
return (env_copy);
}
void sort_env(char **env, int env_size)
{
int sorted;
int i;
char *temp;
sorted = 0;
while (!sorted)
{
sorted = 1;
i = 0;
while (i < env_size - 1)
{
if (strcmp(env[i], env[i + 1]) > 0)
{
temp = env[i];
env[i] = env[i + 1];
env[i + 1] = temp;
sorted = 0;
}
i++;
}
}
}

102
builtins/export_utils.c Executable file
View File

@@ -0,0 +1,102 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* export_utils.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/11/15 18:26:09 by fgras-ca #+# #+# */
/* Updated: 2023/12/09 15:01:53 by fgras-ca ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
static char *create_env_entry(char **args)
{
char *new_env_entry;
char *name;
char *value;
name = ft_strtok(args[1], "=");
value = ft_strtok(NULL, "");
if (name == NULL || value == NULL)
{
write(2, RED"minishell: invalid format for export. "
"Use NAME=\"value\".\n"RST, 63);
return (NULL);
}
new_env_entry = malloc(strlen(name) + strlen(value) + 2);
if (!new_env_entry)
{
exit(EXIT_FAILURE);
}
ft_strcpy(new_env_entry, name);
ft_strcat(new_env_entry, "=");
ft_strcat(new_env_entry, value);
return (new_env_entry);
}
int add_new_env_entry(t_minishell *shell, char *new_env_entry)
{
int env_size;
size_t oldsize;
env_size = 0;
oldsize = 0;
while (shell->environ[env_size] != NULL)
{
env_size++;
}
oldsize = (env_size + 1) * sizeof(char *);
shell->environ = ft_reallocarray(shell->environ, env_size + 2,
sizeof(char *), oldsize);
if (!shell->environ)
{
perror(RED"minishell: error reallocating environment"RST);
free(new_env_entry);
return (1);
}
shell->environ[env_size] = new_env_entry;
shell->environ[env_size + 1] = NULL;
return (0);
}
int replace_env_entry(t_minishell *shell, char *new_env_entry)
{
int i;
size_t name_length;
i = 0;
name_length = ft_strchr(new_env_entry, '=') - new_env_entry;
while (shell->environ[i] != NULL)
{
if (ft_strncmp(shell->environ[i], new_env_entry, name_length) == 0)
{
free(shell->environ[i]);
shell->environ[i] = new_env_entry;
return (1);
}
i++;
}
return (0);
}
static int update_env(t_minishell *shell, char *new_env_entry)
{
if (replace_env_entry(shell, new_env_entry) == 0)
{
return (add_new_env_entry(shell, new_env_entry));
}
return (0);
}
int export_set_env(char **args, t_minishell *shell)
{
char *new_env_entry;
new_env_entry = create_env_entry(args);
if (new_env_entry == NULL)
return (0);
return (update_env(shell, new_env_entry));
}

42
builtins/unset.c Executable file
View File

@@ -0,0 +1,42 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* unset.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/11/14 21:15:04 by fgras-ca #+# #+# */
/* Updated: 2023/12/07 12:10:47 by fgras-ca ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
int builtin_unset(char **args, t_minishell *shell)
{
int i;
int j;
i = 0;
if (args[1] == NULL)
{
write(2, RED"minishell: expected argument to \"unset\"\n", 48);
return (1);
}
while (shell->environ[i] != NULL)
{
if (ft_strncmp(shell->environ[i], args[1], ft_strlen(args[1]))
== 0 && shell->environ[i][ft_strlen(args[1])] == '=')
{
j = i;
while (shell->environ[j] != NULL)
{
shell->environ[j] = shell->environ[j + 1];
j++;
}
break ;
}
i++;
}
return (0);
}