narnaud
3 years ago
11 changed files with 74 additions and 495 deletions
@ -1,13 +1,19 @@ |
|||||
# Minishell |
#Minishell |
||||
|
--- |
||||
|
|
||||
## TODO : |
## TODO : |
||||
|
- free stack, |
||||
|
- handle environment, |
||||
|
- finish built-ins, |
||||
|
- handle multiples heredocs, |
||||
|
- better env management |
||||
|
- j'ai oublié ><' |
||||
|
- ... ? |
||||
|
|
||||
## Notes : |
## Notes : |
||||
|
|
||||
|
|
||||
|
|
||||
## Issues : |
## Issues : |
||||
|
- cat | cat | ls crash on linux ? |
||||
|
- segfault on echo $PATH (g_env bad restaured) |
||||
|
- |
||||
|
@ -1,102 +0,0 @@ |
|||||
/* ************************************************************************** */ |
|
||||
/* */ |
|
||||
/* ::: :::::::: */ |
|
||||
/* caller.c :+: :+: :+: */ |
|
||||
/* +:+ +:+ +:+ */ |
|
||||
/* By: narnaud <narnaud@student.42.fr> +#+ +:+ +#+ */ |
|
||||
/* +#+#+#+#+#+ +#+ */ |
|
||||
/* Created: 2022/02/16 16:46:53 by narnaud #+# #+# */ |
|
||||
/* Updated: 2022/03/24 17:15:24 by narnaud ### ########.fr */ |
|
||||
/* */ |
|
||||
/* ************************************************************************** */ |
|
||||
|
|
||||
#include "minishell.h" |
|
||||
|
|
||||
int command_call(char *argv[], int input_fd, int output_fd) |
|
||||
{ |
|
||||
if (ft_strncmp(argv[0], "echo", 4) == 0) |
|
||||
return (ft_echo(argv, output_fd)); |
|
||||
else if (ft_strncmp(argv[0], "pwd", 3) == 0) |
|
||||
return (ft_pwd(argv, input_fd, output_fd)); |
|
||||
else if (ft_strncmp(argv[0], "cd", 2) == 0) |
|
||||
return (ft_cd(argv, input_fd, output_fd)); |
|
||||
else if (ft_strncmp(argv[0], "export", 6) == 0) |
|
||||
return (ft_export(argv, input_fd, output_fd)); |
|
||||
else if (ft_strncmp(argv[0], "unset", 5) == 0) |
|
||||
return (ft_unset(argv, input_fd, output_fd)); |
|
||||
else if (ft_strncmp(argv[0], "env", 3) == 0) |
|
||||
return (ft_env(argv, input_fd, output_fd)); |
|
||||
else if (ft_strncmp(argv[0], "exit", 4) == 0) |
|
||||
return (close_minishell(0)); |
|
||||
else |
|
||||
{ |
|
||||
errno = EINVAL; |
|
||||
return (-1); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
void exe(char *argv[], char *const envp[]) |
|
||||
{ |
|
||||
char **path_dirs; |
|
||||
char *path; |
|
||||
size_t path_length; |
|
||||
|
|
||||
|
|
||||
execve(argv[0], argv, envp); |
|
||||
path_dirs = ft_split(getenv("PATH"), ':'); |
|
||||
while (path_dirs) |
|
||||
{ |
|
||||
path_length = ft_strlen(*path_dirs) + ft_strlen(argv[0]) + 2; |
|
||||
path = ft_calloc(path_length, sizeof(char)); |
|
||||
ft_memcpy(path, *path_dirs, ft_strlen(*path_dirs)); |
|
||||
ft_memcpy(path + ft_strlen(*path_dirs),"/", 1); |
|
||||
ft_memcpy(path + ft_strlen(*path_dirs) + 1, argv[0], ft_strlen(argv[0])); |
|
||||
free(path); |
|
||||
execve(path, argv, envp); |
|
||||
path_dirs++; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
int caller(t_command *command, int input_fd, int output_fd) |
|
||||
{ |
|
||||
pid_t pid; |
|
||||
int cmd_ret; |
|
||||
int status; |
|
||||
|
|
||||
if (command->input != 0) |
|
||||
input_fd = command->fd[0]; |
|
||||
if (command->output != 1) |
|
||||
output_fd = command->fd[1]; |
|
||||
else if (!command->next) |
|
||||
output_fd = 1; |
|
||||
cmd_ret = command_call(command->argv, input_fd, output_fd); |
|
||||
if (cmd_ret == -1 && errno == EINVAL) |
|
||||
{ |
|
||||
pid = fork(); |
|
||||
termios(1); |
|
||||
if (pid == 0) |
|
||||
{ |
|
||||
if (command->prev || command->input || command->heredoc) |
|
||||
{ |
|
||||
dup2(input_fd, STDIN_FILENO); |
|
||||
close(input_fd); |
|
||||
} |
|
||||
if (command->next || command->output) |
|
||||
dup2(output_fd, STDOUT_FILENO); |
|
||||
exe(command->argv, command->envp); |
|
||||
} |
|
||||
//signal(SIGINT, NULL);
|
|
||||
//signal(SIGQUIT, NULL);
|
|
||||
waitpid(pid, &status, 0); |
|
||||
//signal(SIGINT, sigs_handler);
|
|
||||
//signal(SIGQUIT, sigs_handler);
|
|
||||
termios(0); |
|
||||
if (command->output) |
|
||||
close(command->output); |
|
||||
if (WIFSIGNALED(status)) |
|
||||
return (-1); |
|
||||
if (!WIFEXITED(status)) |
|
||||
printf("Minishell: command not found: '%s'\n", command->argv[0]); |
|
||||
} |
|
||||
return (0); |
|
||||
} |
|
@ -1,90 +0,0 @@ |
|||||
/* ************************************************************************** */ |
|
||||
/* */ |
|
||||
/* ::: :::::::: */ |
|
||||
/* export.c :+: :+: :+: */ |
|
||||
/* +:+ +:+ +:+ */ |
|
||||
/* By: narnaud <narnaud@student.42.fr> +#+ +:+ +#+ */ |
|
||||
/* +#+#+#+#+#+ +#+ */ |
|
||||
/* Created: 2022/02/16 09:41:29 by narnaud #+# #+# */ |
|
||||
/* Updated: 2022/04/14 07:45:21 by narnaud ### ########.fr */ |
|
||||
/* */ |
|
||||
/* ************************************************************************** */ |
|
||||
|
|
||||
#include "minishell.h" |
|
||||
|
|
||||
int ft_unset(char **argv, int input_fd, int output_fd) |
|
||||
{ |
|
||||
(void)output_fd; |
|
||||
(void)input_fd; |
|
||||
if (!argv[1]) |
|
||||
{ |
|
||||
//read(input_fd, PIPE_MAX_SIZE);
|
|
||||
return (1); |
|
||||
} |
|
||||
return (0); |
|
||||
} |
|
||||
|
|
||||
int ft_env(char **argv, int input_fd, int output_fd) |
|
||||
{ |
|
||||
(void)output_fd; |
|
||||
(void)input_fd; |
|
||||
(void)argv; |
|
||||
int i; |
|
||||
|
|
||||
i = 0; |
|
||||
while (g_env[i]) |
|
||||
{ |
|
||||
printf("%s\n", g_env[i]); |
|
||||
i++; |
|
||||
} |
|
||||
return (0); |
|
||||
} |
|
||||
|
|
||||
int is_valid_identifier(char *ident) |
|
||||
{ |
|
||||
if (ft_isalpha(ident[0]) || ident[0] == '_') |
|
||||
{ |
|
||||
while (*ident) |
|
||||
{ |
|
||||
if (!ft_isalpha(*ident) && !ft_isdigit(*ident) && *ident != '_') |
|
||||
return (0); |
|
||||
ident++; |
|
||||
} |
|
||||
return (1); |
|
||||
} |
|
||||
return (0); |
|
||||
} |
|
||||
|
|
||||
int ft_export(char **argv, int input_fd, int output_fd) |
|
||||
{ |
|
||||
char **new; |
|
||||
char **env; |
|
||||
int i; |
|
||||
|
|
||||
(void)output_fd; |
|
||||
(void)input_fd; |
|
||||
i = 0; |
|
||||
new = ft_split(argv[1], '='); |
|
||||
if (!is_valid_identifier(new[0])) |
|
||||
{ |
|
||||
printf ("export: not an identifier: %s\n", new[0]); |
|
||||
return (0); |
|
||||
} |
|
||||
while (g_env[i]) |
|
||||
{ |
|
||||
env = ft_split(g_env[i], '='); |
|
||||
if (!ft_strncmp(new[0], env[0], ft_strlen(new[0]) + 1)) |
|
||||
{ |
|
||||
g_env[i] = argv[1]; |
|
||||
return (1); |
|
||||
} |
|
||||
i++; |
|
||||
} |
|
||||
g_env[i] = argv[1]; |
|
||||
g_env[i + 1] = NULL; |
|
||||
return (1); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
@ -1,100 +0,0 @@ |
|||||
/* ************************************************************************** */ |
|
||||
/* */ |
|
||||
/* ::: :::::::: */ |
|
||||
/* parser.c :+: :+: :+: */ |
|
||||
/* +:+ +:+ +:+ */ |
|
||||
/* By: narnaud <narnaud@student.42.fr> +#+ +:+ +#+ */ |
|
||||
/* +#+#+#+#+#+ +#+ */ |
|
||||
/* Created: 2022/01/06 07:52:29 by narnaud #+# #+# */ |
|
||||
/* Updated: 2022/04/14 09:19:12 by narnaud ### ########.fr */ |
|
||||
/* */ |
|
||||
/* ************************************************************************** */ |
|
||||
|
|
||||
#include "minishell.h" |
|
||||
|
|
||||
|
|
||||
size_t count_arguments(t_token tok) |
|
||||
{ |
|
||||
size_t ret; |
|
||||
|
|
||||
ret = 0; |
|
||||
while (tok.value) |
|
||||
{ |
|
||||
if (tok.type == 0 && tok.value[0] != '|') |
|
||||
ret++; |
|
||||
if (tok.next) |
|
||||
tok = *(tok.next); |
|
||||
else |
|
||||
break ; |
|
||||
} |
|
||||
return (ret); |
|
||||
} |
|
||||
|
|
||||
void update_redir(t_command *cmd, t_token tok) |
|
||||
{ |
|
||||
if (tok.type == OUT) |
|
||||
{ |
|
||||
if (cmd->fd[1]) |
|
||||
close(cmd->fd[1]); |
|
||||
cmd->output = init_file(tok.value, O_TRUNC | O_WRONLY); |
|
||||
} |
|
||||
else if (tok.type == ADD) |
|
||||
{ |
|
||||
if (cmd->fd[1]) |
|
||||
close(cmd->fd[1]); |
|
||||
cmd->fd[1] = init_file(tok.value, O_APPEND | O_WRONLY); |
|
||||
} |
|
||||
else if (tok.type == IN) |
|
||||
{ |
|
||||
if (cmd->fd[0]) |
|
||||
close(cmd->fd[0]); |
|
||||
cmd->fd[0] = init_file(tok.value, O_RDONLY); |
|
||||
} |
|
||||
else if (tok.type == HD) |
|
||||
{ |
|
||||
if (cmd->fd[0]) |
|
||||
close(cmd->fd[0]); |
|
||||
cmd->fd[0] = 0; |
|
||||
cmd->heredoc = tok.value; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
t_command *parser(t_token tok) |
|
||||
{ |
|
||||
int i; |
|
||||
t_command *cmd; |
|
||||
t_command *ret; |
|
||||
|
|
||||
cmd = ft_calloc(1, sizeof(t_command)); |
|
||||
ret = cmd; |
|
||||
while (tok.value) |
|
||||
{ |
|
||||
i = 0; |
|
||||
cmd->argv = ft_calloc(count_arguments(tok) + 1, sizeof(char *)); |
|
||||
while(tok.value[0] != '|') |
|
||||
{ |
|
||||
if (tok.type) |
|
||||
update_redir(cmd, tok); |
|
||||
else |
|
||||
{ |
|
||||
cmd->argv[i] = tok.value; |
|
||||
i++; |
|
||||
} |
|
||||
if (tok.next) |
|
||||
tok = *(tok.next); |
|
||||
else |
|
||||
break ; |
|
||||
} |
|
||||
//printf("Input : %d\n", cmd->input);
|
|
||||
//printf("Output : %d\n", cmd->output);
|
|
||||
cmd->argv[i] = NULL; |
|
||||
if (tok.next) |
|
||||
tok = *(tok.next); |
|
||||
else |
|
||||
break ; |
|
||||
cmd->next = ft_calloc(1, sizeof(t_command)); |
|
||||
cmd->next->prev = cmd; |
|
||||
cmd = cmd->next; |
|
||||
} |
|
||||
return (ret); |
|
||||
} |
|
@ -1,94 +0,0 @@ |
|||||
/* ************************************************************************** */ |
|
||||
/* */ |
|
||||
/* ::: :::::::: */ |
|
||||
/* utils.c :+: :+: :+: */ |
|
||||
/* +:+ +:+ +:+ */ |
|
||||
/* By: narnaud <narnaud@student.42.fr> +#+ +:+ +#+ */ |
|
||||
/* +#+#+#+#+#+ +#+ */ |
|
||||
/* Created: 2022/01/07 11:54:34 by narnaud #+# #+# */ |
|
||||
/* Updated: 2022/03/22 15:38:08 by narnaud ### ########.fr */ |
|
||||
/* */ |
|
||||
/* ************************************************************************** */ |
|
||||
|
|
||||
#include "minishell.h" |
|
||||
|
|
||||
char **get_commands(char *line) |
|
||||
{ |
|
||||
char **split; |
|
||||
|
|
||||
split = ft_split(line, '|'); |
|
||||
return (split); |
|
||||
} |
|
||||
|
|
||||
int is_empty(char *line) |
|
||||
{ |
|
||||
while (*line) |
|
||||
{ |
|
||||
if (*line <= 9 || (*line >= 13 && *line != 32)) |
|
||||
return (0); |
|
||||
line++; |
|
||||
} |
|
||||
return (1); |
|
||||
} |
|
||||
|
|
||||
int msg_n_ret(char *msg, int ret) |
|
||||
{ |
|
||||
printf("%s", msg); |
|
||||
return (ret); |
|
||||
} |
|
||||
|
|
||||
int init_file(char *filename, int mode) |
|
||||
{ |
|
||||
return (open(filename, mode | O_CREAT, 0644)); |
|
||||
} |
|
||||
|
|
||||
int is_space(char ch) |
|
||||
{ |
|
||||
if (ch == 32 || (ch > 8 && ch < 14)) |
|
||||
return (1); |
|
||||
else |
|
||||
return (0); |
|
||||
} |
|
||||
|
|
||||
void termios(int ctl) |
|
||||
{ |
|
||||
struct termios termios_p; |
|
||||
int tty; |
|
||||
|
|
||||
tty = ttyslot(); |
|
||||
if (tcgetattr(tty, &termios_p) < 0) |
|
||||
{ |
|
||||
perror("stdin"); |
|
||||
exit (EXIT_FAILURE); |
|
||||
} |
|
||||
//termios_p.c_oflag &= CRDLY;
|
|
||||
//termios_p.c_lflag &= ICANON;
|
|
||||
if (ctl) |
|
||||
{ |
|
||||
termios_p.c_lflag |= ECHOCTL; |
|
||||
termios_p.c_cc[VQUIT] = 28; |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
termios_p.c_lflag &= ~(ECHOCTL); |
|
||||
termios_p.c_cc[VQUIT] = 0; |
|
||||
} |
|
||||
tcsetattr(tty, TCSANOW, &termios_p); |
|
||||
} |
|
||||
|
|
||||
void sigs_handler(int sig_num) |
|
||||
{ |
|
||||
if (sig_num == SIGQUIT) |
|
||||
printf("QUIT: 3\n"); |
|
||||
else if (sig_num == SIGINT) |
|
||||
printf("\n"); |
|
||||
rl_on_new_line(); |
|
||||
rl_replace_line("", 0); |
|
||||
rl_redisplay(); |
|
||||
return ; |
|
||||
} |
|
||||
void halt(int ret_code) |
|
||||
{ |
|
||||
printf("exit"); |
|
||||
exit(ret_code); |
|
||||
} |
|
Loading…
Reference in new issue