Browse Source

-fixes: no more doubles signals, -new: added return messages (signals), generalized cmds struct use and included env in

master
narnaud 3 years ago
parent
commit
2c5247fb6a
  1. 7
      README.md
  2. 33
      built-in.c
  3. 40
      caller.c
  4. 25
      env.c
  5. 19
      lexer.c
  6. 24
      minishell.c
  7. 39
      minishell.h
  8. 20
      parser.c
  9. 22
      utils.c

7
README.md

@ -3,17 +3,10 @@
## TODO :
- free stack,
- handle environment,
- finish built-ins,
- handle multiples heredocs,
- better env management
- j'ai oublié ><'
- ... ?
## Notes :
## Issues :
- cat | cat | ls crash on linux ?
- segfault on echo $PATH (g_env bad restaured)
-

33
built-in.c

@ -12,22 +12,19 @@
#include "minishell.h"
int ft_echo(char *argv[])
int ft_echo(t_command *cmd)
{
int no_nl;
no_nl = 0;
if (argv[1])
if (*(++cmd->argv))
{
argv++;
if (ft_strncmp(*argv, "-n", 3) == 0 && argv++)
if (ft_strncmp(*(cmd->argv), "-n", 3) == 0 && cmd->argv++)
no_nl = 1;
while (*argv)
while (*(cmd->argv))
{
ft_putstr_fd(*argv, 1);
argv++;
if (*argv)
ft_putstr_fd(*(cmd->argv), 1);
if (*(++cmd->argv))
ft_putstr_fd(" ", 1);
}
}
@ -36,11 +33,11 @@ int ft_echo(char *argv[])
return (0);
}
int ft_pwd(char **argv)
int ft_pwd(t_command *cmd)
{
char *dir;
(void)argv;
(void)cmd;
dir = ft_calloc(PATHS_MAX_SIZE, sizeof(char));
getcwd(dir, PATHS_MAX_SIZE);
ft_putstr_fd(dir, 1);
@ -49,21 +46,21 @@ int ft_pwd(char **argv)
return (0);
}
int ft_cd(char **argv)
int ft_cd(t_command *cmd)
{
if (argv[1])
if (cmd->argv[1])
{
if (access(argv[1], X_OK))
if (access(cmd->argv[1], X_OK))
{
printf("Minishell: %s: %s: Permission denied\n", argv[0], argv[1]);
printf("Minishell: %s: %s: Permission denied\n", cmd->argv[0], cmd->argv[1]);
return (0);
}
else if (access(argv[1], F_OK))
else if (access(cmd->argv[1], F_OK))
{
printf("Minishell: %s: %s: Not a directory\n", argv[0], argv[1]);
printf("Minishell: %s: %s: Not a directory\n", cmd->argv[0], cmd->argv[1]);
return (0);
}
chdir(argv[1]);
chdir(cmd->argv[1]);
return (1);
}
else

40
caller.c

@ -12,21 +12,21 @@
#include "minishell.h"
int command_call(char *argv[])
int command_call(t_command *cmd)
{
if (ft_strncmp(argv[0], "echo", 5) == 0)
return (ft_echo(argv));
else if (ft_strncmp(argv[0], "pwd", 4) == 0)
return (ft_pwd(argv));
else if (ft_strncmp(argv[0], "cd", 3) == 0)
return (ft_cd(argv));
else if (ft_strncmp(argv[0], "export", 7) == 0)
return (ft_export(argv));
else if (ft_strncmp(argv[0], "unset", 6) == 0)
return (ft_unset(argv));
else if (ft_strncmp(argv[0], "env", 4) == 0)
return (ft_env(argv));
else if (ft_strncmp(argv[0], "exit", 5) == 0)
if (ft_strncmp(cmd->argv[0], "echo", 5) == 0)
return (ft_echo(cmd));
else if (ft_strncmp(cmd->argv[0], "pwd", 4) == 0)
return (ft_pwd(cmd));
else if (ft_strncmp(cmd->argv[0], "cd", 3) == 0)
return (ft_cd(cmd));
else if (ft_strncmp(cmd->argv[0], "export", 7) == 0)
return (ft_export(cmd));
else if (ft_strncmp(cmd->argv[0], "unset", 6) == 0)
return (ft_unset(cmd));
else if (ft_strncmp(cmd->argv[0], "env", 4) == 0)
return (ft_env(cmd));
else if (ft_strncmp(cmd->argv[0], "exit", 5) == 0)
return (close_minishell(0));
else
{
@ -35,25 +35,25 @@ int command_call(char *argv[])
}
}
void exe(char *argv[], char *const envp[])
void exe(t_command *cmd)
{
char **path_dirs;
char *path;
size_t path_length;
if (ft_strchr(argv[0], '/'))
execve(argv[0], argv, envp);
if (ft_strchr(cmd->argv[0], '/'))
execve(cmd->argv[0], cmd->argv, *cmd->envp);
else
{
path_dirs = ft_split(getenv("PATH"), ':');
while (path_dirs)
{
path_length = ft_strlen(*path_dirs) + ft_strlen(argv[0]) + 2;
path_length = ft_strlen(*path_dirs) + ft_strlen(cmd->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]));
execve(path, argv, envp);
ft_memcpy(path + ft_strlen(*path_dirs) + 1, cmd->argv[0], ft_strlen(cmd->argv[0]));
execve(path, cmd->argv, *cmd->envp);
path_dirs++;
}
}

25
env.c

@ -12,9 +12,9 @@
#include "minishell.h"
int ft_unset(char **argv)
int ft_unset(t_command *cmd)
{
if (!argv[1])
if (!cmd->argv[1])
{
//read(input_fd, PIPE_MAX_SIZE);
return (1);
@ -22,15 +22,14 @@ int ft_unset(char **argv)
return (0);
}
int ft_env(char **argv)
int ft_env(t_command *cmd)
{
(void)argv;
int i;
i = 0;
while (g_env[i])
while ((*cmd->envp)[i])
{
printf("%s\n", g_env[i]);
printf("%s\n", (*cmd->envp)[i]);
i++;
}
return (0);
@ -51,31 +50,31 @@ int is_valid_identifier(char *ident)
return (0);
}
int ft_export(char **argv)
int ft_export(t_command *cmd)
{
char **new;
char **env;
int i;
i = 0;
new = ft_split(argv[1], '=');
new = ft_split(cmd->argv[1], '=');
if (!is_valid_identifier(new[0]))
{
printf ("export: not an identifier: %s\n", new[0]);
return (0);
}
while (g_env[i])
while ((*cmd->envp)[i])
{
env = ft_split(g_env[i], '=');
env = ft_split((*cmd->envp)[i], '=');
if (!ft_strncmp(new[0], env[0], ft_strlen(new[0]) + 1))
{
g_env[i] = argv[1];
(*cmd->envp)[i] = cmd->argv[1];
return (1);
}
i++;
}
g_env[i] = argv[1];
g_env[i + 1] = NULL;
(*cmd->envp)[i] = cmd->argv[1];
(*cmd->envp)[i + 1] = NULL;
return (1);
}

19
lexer.c

@ -88,27 +88,22 @@ int check_register(t_lexer *lex, char **line, char *tmp)
int replace_var(char **line, char *tmp, int tmp_i)
{
char **env;
int len;
int i;
char *var_name;
char *value;
// TODO : free split and var_name
i = 1;
env = NULL;
while (ft_isalpha((*line)[i]) || ft_isdigit((*line)[i]) || (*line)[i] == '_')
i++;
var_name = ft_substr(*line, 1, i - 1);
value = getenv(var_name);
len = ft_strlen(value);
i = 0;
while (g_env[i])
{
env = ft_split(g_env[i], '=');
if (!ft_strncmp(var_name, env[0], ft_strlen(var_name) + 1))
break ;
i++;
}
i = 0;
while (env[1][i])
tmp[tmp_i++] = env[1][i++];
while (i < len)
tmp[tmp_i++] = value[i++];
tmp[tmp_i] = 0;
*line += i;
return (tmp_i);

24
minishell.c

@ -12,8 +12,6 @@
# include "minishell.h"
char **g_env;
int caller(t_command *cmd)
{
pid_t pid;
@ -33,21 +31,25 @@ int caller(t_command *cmd)
dup2(cmd->fd[0], STDIN_FILENO);
if (cmd->fd[1])
dup2(cmd->fd[1], STDOUT_FILENO);
if (command_call(cmd->argv) == -1)
exe(cmd->argv, cmd->envp);
if (command_call(cmd) == -1)
exe(cmd);
exit(1);
}
if (cmd->fd[1])
close(cmd->fd[1]);
if (cmd->next)
return (caller(cmd->next));
waitpid(pid, &status, 0);
if (WIFEXITED(status) && WEXITSTATUS(status))
write(1, "\n", 1);
if (WIFSIGNALED(status))
printf("QUIT: %d\n", WTERMSIG(status));
if (cmd->fd[0])
close(cmd->fd[0]);
waitpid(pid, &status, 0);
return (1);
}
t_command *parser(t_token *tok, t_command *prev)
t_command *parser(char ***envp, t_token *tok, t_command *prev)
{
int i;
t_command *cmd;
@ -60,6 +62,7 @@ t_command *parser(t_token *tok, t_command *prev)
i = 0;
cmd->argc = count_arguments(tok);
cmd->argv = ft_calloc(cmd->argc + 1, sizeof(char *));
cmd->envp = envp;
while(tok && tok->type != PIPE)
{
if (tok->type)
@ -73,7 +76,7 @@ t_command *parser(t_token *tok, t_command *prev)
cmd->argv[0], cmd->argc, cmd->fd[0], cmd->fd[1]);
cmd->argv[i] = NULL;
if (tok && tok->type == PIPE)
cmd->next = parser(tok->next, cmd);
cmd->next = parser(envp, tok->next, cmd);
return (cmd);
}
@ -107,14 +110,11 @@ t_token *lexer(char *line)
return (lex->tokens);
}
int main(int argc, char **argv, char**envp)
int main(int argc, char **argv, char **envp)
{
char *line;
if (argc < 2)
(void)argv;
g_env = envp;
signal(SIGINT, sigs_handler);
signal(SIGQUIT, sigs_handler);
while (1)
{
termios(0);
@ -124,7 +124,7 @@ int main(int argc, char **argv, char**envp)
halt(EXIT_FAILURE);
if (is_empty(line))
continue ;
caller(parser(lexer(line), NULL));
caller(parser(&envp, lexer(line), NULL));
add_history(line);
}
clear_history();

39
minishell.h

@ -31,19 +31,28 @@
# include <errno.h>
# include <termios.h>
extern char **g_env;
typedef struct s_command
{
int argc;
char **argv;
char ***envp;
int fd[2];
char *heredoc;
struct s_command *next;
struct s_command *prev;
} t_command;
// ----------------------------------Utils.c
int ft_echo(char **argv);
int ft_pwd(char **argv);
int ft_cd(char **argv);
int ft_echo(t_command *cmd);
int ft_pwd(t_command *cmd);
int ft_cd(t_command *cmd);
int close_minishell(int exit_code);
// ----------------------------------Utils.c
int ft_unset(char **argv);
int ft_env(char **argv);
int ft_unset(t_command *cmd);
int ft_env(t_command *cmd);
int is_valid_identifier(char *ident);
int ft_export(char **argv);
int ft_export(t_command *cmd);
// ----------------------------------Utils.c
@ -53,20 +62,8 @@ void termios(int ctl);
void sigs_handler(int sig_num);
// ----------------------------------Caller.c
typedef struct s_command
{
int argc;
char **argv;
char **envp;
int fd[2];
char *heredoc;
struct s_command *next;
struct s_command *prev;
} t_command;
void exe(char *argv[], char *const envp[]);
int command_call(char *argv[]);
void exe(t_command *cmd);
int command_call(t_command *cmd);
// ----------------------------------Parser.c

20
parser.c

@ -18,15 +18,15 @@ int push_heredoc(char *str)
int pip[2];
pipe(pip);
while(1)
{
line = readline(">");
if (!ft_strncmp(line, str, ft_strlen(str) + 1))
break;
ft_putstr_fd(line, pip[1]);
write(pip[1], "\n", 1);
}
close(pip[1]);
while(1)
{
line = readline(">");
if (!ft_strncmp(line, str, ft_strlen(str) + 1))
break;
ft_putstr_fd(line, pip[1]);
write(pip[1], "\n", 1);
}
close(pip[1]);
return (pip[0]);
}
@ -37,7 +37,7 @@ size_t count_arguments(t_token *tok)
ret = 0;
while (tok && tok->type != PIPE)
{
if (!tok->type)
if (!tok->type == WORD)
ret++;
tok = tok->next;
}

22
utils.c

@ -23,6 +23,14 @@ int is_empty(char *line)
return (1);
}
void nothing(int sig_num)
{
(void)sig_num;
//if (sig_num == SIGQUIT)
// write(1, "QUIT: 3\n", 8);
//else if (sig_num == SIGINT)
// write(1, "\n", 1);
}
void termios(int ctl)
{
struct termios termios_p;
@ -34,18 +42,24 @@ void termios(int ctl)
//termios_p.c_oflag &= CRDLY;
//termios_p.c_lflag &= ICANON;
if (ctl)
termios_p.c_lflag |= ECHOCTL;
{
termios_p.c_lflag |= ECHOCTL;
signal(SIGINT, nothing);
signal(SIGQUIT, nothing);
}
else
{
termios_p.c_lflag &= ~(ECHOCTL);
signal(SIGINT, sigs_handler);
signal(SIGQUIT, sigs_handler);
}
termios_p.c_cc[VQUIT] = ctl * 28;
tcsetattr(tty, TCSANOW, &termios_p);
}
void sigs_handler(int sig_num)
{
if (sig_num == SIGQUIT)
printf("QUIT: 3\n");
else if (sig_num == SIGINT)
if (sig_num == SIGINT)
printf("\n");
rl_on_new_line();
rl_replace_line("", 0);

Loading…
Cancel
Save