mirror of
https://github.com/Ladebeze66/minishell.git
synced 2026-11-09 13:47:17 +01:00
minishell
This commit is contained in:
116
builtins/builtins.c
Executable file
116
builtins/builtins.c
Executable 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
48
builtins/builtins_utils.c
Executable 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
58
builtins/echo.c
Executable 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
29
builtins/env.c
Executable 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
65
builtins/export.c
Executable 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
66
builtins/export_env.c
Executable 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
102
builtins/export_utils.c
Executable 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
42
builtins/unset.c
Executable 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);
|
||||
}
|
||||
Reference in New Issue
Block a user