ajout des builtins pwd cd et export
This commit is contained in:
2
Makefile
2
Makefile
@@ -27,7 +27,7 @@ SRCS = main.c init.c free.c generic.c \
|
||||
lexing.c fill_token.c check_operators.c \
|
||||
parsing.c \
|
||||
valid_syntax.c valid_pipeline.c valid_command.c valid_io_redirect.c \
|
||||
env.c exit.c echo.c
|
||||
cd.c pwd.c export.c unset.c exit.c env.c echo.c
|
||||
|
||||
DIR_OBJS = builds
|
||||
OBJS = $(SRCS:%.c=$(DIR_OBJS)/%.o)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
- [get root access using sudo su](https://superuser.com/questions/408990/how-do-i-log-out-of-sudo-su)
|
||||
- [what is a tty](https://www.howtogeek.com/428174/what-is-a-tty-on-linux-and-how-to-use-the-tty-command/)
|
||||
|
||||
```
|
||||
```text
|
||||
| BASH | MINISHELL |
|
||||
-----------------------------------
|
||||
| print | action | print | action |
|
||||
@@ -150,7 +150,7 @@ There are three functions to use to get the value of a capability :
|
||||
- **ttyname** : `char *ttyname(int fd);` returns a pointer to the null-terminated pathname of the terminal device that is open on the file descriptor fd, or NULL on error (for example, if fd is not connected to a terminal)
|
||||
- **ttyslot** : `int ttyslot(void);` returns the index of the current user's entry in some file
|
||||
- **ioctl** : `int ioctl(int fd, unsigned long request, ...);` manipulates the underlying device parameters of special files. In particular, many operating characteristics of character special files (e.g., terminals) may be controlled with ioctl() requests. The argument fd must be an open file descriptor
|
||||
- **getenv** : `char *getenv(const char *name);` searches the environment list to find the environment variable name, and returns a pointer to the corresponding value string
|
||||
- **getenv** : `char *getenv(const char *name);` searches the environment list to find the environment variable name, and returns a pointer to the corresponding value string, or NULL if not found
|
||||
- **tcsetattr** : `int tcsetattr(int fd, int optional_actions, const struct termios *termios_p);` tcsetattr() only works in an environment where either a controlling terminal exists, or stdin and stderr refer to tty devices. Specifically, it does not work in a TSO environment. Changes the attributes associated with a terminal. New attributes are specified with a termios control structure. Programs should always issue a tcgetattr() first, modify the desired fields, and then issue a tcsetattr(). tcsetattr() should never be issued using a termios structure that was not obtained using tcgetattr(). tcsetattr() should use only a termios structure that was obtained by tcgetattr()
|
||||
- **tcgetattr** : `int tcgetattr(int fildes, struct termios *termptr);` Gets a termios structure, which contains control information for a terminal associated with fildes. It stores that information in a memory location that termptr points to. The contents of a termios structure are described in tcsetattr()
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* By: lperrey <lperrey@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2021/10/08 02:59:58 by lperrey #+# #+# */
|
||||
/* Updated: 2021/11/10 13:41:58 by hulamy ### ########.fr */
|
||||
/* Updated: 2021/11/11 09:58:01 by hulamy ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
@@ -15,12 +15,7 @@
|
||||
|
||||
// Init
|
||||
int init(t_all *c, char *envp[]);
|
||||
//int set_signals_handling(struct sigaction *ori_signal_behaviour,
|
||||
// struct sigaction *signal_behaviour);
|
||||
int set_signals_handling(struct sigaction *signal_behaviour);
|
||||
//int set_terminal_attributes(struct termios *ori_termios,
|
||||
// struct termios *interactive_termios,
|
||||
// int *termios_changed);
|
||||
|
||||
// Shell modes
|
||||
void shell_loop(t_all *c);
|
||||
@@ -38,8 +33,12 @@ t_cmd **fill_cmd(t_token *token, char **envp);
|
||||
void cmd_expansion(t_cmd **cmd_arr, char **envp);
|
||||
|
||||
// Builtins
|
||||
int builtin_env(int argc, char *argv[], t_all *c);
|
||||
int builtin_cd(int argc, char *argv[], t_all *c);
|
||||
int builtin_pwd(int argc, char *argv[], t_all *c);
|
||||
int builtin_export(int argc, char *argv[], t_all *c);
|
||||
int builtin_unset(int argc, char *argv[], t_all *c);
|
||||
int builtin_exit(int argc, char *argv[], t_all *c);
|
||||
int builtin_env(int argc, char *argv[], t_all *c);
|
||||
int builtin_echo(int argc, char *argv[], t_all *c);
|
||||
|
||||
// Free
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* By: lperrey <lperrey@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2021/10/08 02:35:52 by lperrey #+# #+# */
|
||||
/* Updated: 2021/10/30 13:31:07 by lperrey ### ########.fr */
|
||||
/* Updated: 2021/11/10 17:33:37 by hulamy ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
@@ -35,7 +35,7 @@ typedef struct s_token
|
||||
enum e_token_id id;
|
||||
} t_token;
|
||||
|
||||
typedef int (*t_builtin_ptr)(int,char **,struct s_all *);
|
||||
typedef int t_builtin_ptr(int,char **,struct s_all *);
|
||||
|
||||
typedef struct s_cmd
|
||||
{
|
||||
@@ -54,10 +54,10 @@ typedef struct s_all
|
||||
char *prompt;
|
||||
t_token *token_list;
|
||||
int last_exit_status;
|
||||
struct termios ori_termios;
|
||||
struct termios interactive_termios;
|
||||
int termios_changed;
|
||||
struct sigaction ori_signal_behaviour;
|
||||
// struct termios ori_termios;
|
||||
// struct termios interactive_termios;
|
||||
// int termios_changed;
|
||||
// struct sigaction ori_signal_behaviour;
|
||||
struct sigaction signal_behaviour;
|
||||
} t_all;
|
||||
|
||||
|
||||
10
srcs/builtins/cd.c
Normal file
10
srcs/builtins/cd.c
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
#include "minishell.h"
|
||||
|
||||
int builtin_cd(int argc, char *argv[], t_all *c)
|
||||
{
|
||||
(void)argc;
|
||||
(void)c;
|
||||
chdir(argv[1]);
|
||||
return (0);
|
||||
}
|
||||
47
srcs/builtins/export.c
Normal file
47
srcs/builtins/export.c
Normal file
@@ -0,0 +1,47 @@
|
||||
|
||||
#include "minishell.h"
|
||||
|
||||
int getenv_position(char **envp, char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
while (envp[i] && ft_strncmp(envp[i], name, ft_strlen(name)))
|
||||
i++;
|
||||
if (!envp[i])
|
||||
return (-1);
|
||||
return (i);
|
||||
}
|
||||
|
||||
int builtin_export(int argc, char *argv[], t_all *c)
|
||||
{
|
||||
char **var;
|
||||
int position;
|
||||
|
||||
(void)argc;
|
||||
var = ft_split(argv[1], '=');
|
||||
position = getenv_position(c->envp, var[0]);
|
||||
if (position == -1 || !ft_strchr(argv[1], '='))
|
||||
return (0);
|
||||
c->envp[position] = ft_strjoin(var[0], "=");
|
||||
if (var[1]) // parce que ft_strjoin return NULL si var[1] est null, pourquoi ?
|
||||
c->envp[position] = ft_strjoin(c->envp[position], var[1]);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
** comportement de bash :
|
||||
** 1. modifier une variable dans bash :
|
||||
** > ca ne la modifie pas dans zsh
|
||||
** > ca ne la garde pas apres exit de bash
|
||||
** 2. ajouter une variable dans bash :
|
||||
** > ca ne la modifie pas dans zsh
|
||||
** > ca ne la garde pas apres exit de bash
|
||||
** 3. ajouter une variable avec erreur :
|
||||
** > 'export VARIABLE' n'exporte rien
|
||||
** > 'export VARIABLE=' exporte une variable vide
|
||||
** 4. ordre d'insertion d'une nouvelle variable :
|
||||
**
|
||||
**
|
||||
*/
|
||||
|
||||
15
srcs/builtins/pwd.c
Normal file
15
srcs/builtins/pwd.c
Normal file
@@ -0,0 +1,15 @@
|
||||
|
||||
#include "minishell.h"
|
||||
|
||||
int builtin_pwd(int argc, char *argv[], t_all *c)
|
||||
{
|
||||
char *pwd;
|
||||
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
(void)c;
|
||||
pwd = getcwd(NULL, 0);
|
||||
write(1, pwd, ft_strlen(pwd));
|
||||
write(1, "\n", 1);
|
||||
return (0);
|
||||
}
|
||||
10
srcs/builtins/unset.c
Normal file
10
srcs/builtins/unset.c
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
#include "minishell.h"
|
||||
|
||||
int builtin_unset(int argc, char *argv[], t_all *c)
|
||||
{
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
(void)c;
|
||||
return (0);
|
||||
}
|
||||
110
srcs/execute.c
110
srcs/execute.c
@@ -1,110 +0,0 @@
|
||||
#include "minishell.h"
|
||||
|
||||
void close_fd(t_cmd *cmd)
|
||||
{
|
||||
if (cmd->fd_in != 0)
|
||||
close(cmd->fd_in);
|
||||
if (cmd->fd_out != 1)
|
||||
close(cmd->fd_out);
|
||||
}
|
||||
|
||||
void exec_cmd(char **envp, t_list *cmd_list)
|
||||
{
|
||||
t_cmd *cmd;
|
||||
pid_t pid;
|
||||
pid_t wpid;
|
||||
int status;
|
||||
|
||||
while(cmd_list)
|
||||
{
|
||||
cmd = cmd_list->content;
|
||||
pid = fork();
|
||||
if (pid == 0)
|
||||
{
|
||||
if (cmd->fd_in != 0)
|
||||
dup2(cmd->fd_in, STDIN_FILENO);
|
||||
if (cmd->fd_out != 1)
|
||||
dup2(cmd->fd_out, STDOUT_FILENO);
|
||||
close_fd(cmd);
|
||||
execve(cmd->argv[0], cmd->argv, envp);
|
||||
}
|
||||
else
|
||||
close_fd(cmd);
|
||||
cmd_list = cmd_list->next;
|
||||
}
|
||||
// waitpid pour la derniere commande (pour '$?')
|
||||
while ((wpid = wait(&status)) > 0);
|
||||
}
|
||||
|
||||
int nbr_pipes(char *input)
|
||||
{
|
||||
int i;
|
||||
int count;
|
||||
|
||||
i = -1;
|
||||
count = 0;
|
||||
while (input[++i])
|
||||
if (input[i] == '|')
|
||||
count++;
|
||||
return (count);
|
||||
}
|
||||
|
||||
int handle_fdd(char *input, int fdin, t_cmd *cmd)
|
||||
{
|
||||
int *pipes_fd;
|
||||
int next_in;
|
||||
char *tmp;
|
||||
|
||||
cmd->fd_in = fdin;
|
||||
cmd->fd_out = 1;
|
||||
next_in = 0;
|
||||
if (input + 1)
|
||||
{
|
||||
pipes_fd = calloc(2, sizeof(int));
|
||||
pipe(pipes_fd);
|
||||
cmd->fd_out = pipes_fd[1];
|
||||
next_in = pipes_fd[0];
|
||||
}
|
||||
tmp = ft_strchr(input, '>');
|
||||
if (tmp)
|
||||
{
|
||||
tmp[0] = '\0';
|
||||
tmp = ft_strtrim(tmp + 2, " "); // +2 for "> "
|
||||
if (cmd->fd_out != 1)
|
||||
close(cmd->fd_out);
|
||||
cmd->fd_out = open(tmp, O_RDWR | O_TRUNC);
|
||||
}
|
||||
tmp = ft_strchr(input, '<');
|
||||
if (tmp)
|
||||
{
|
||||
tmp[0] = '\0';
|
||||
tmp = ft_strtrim(tmp + 2, " "); // +2 for "> "
|
||||
if (cmd->fd_in != 0)
|
||||
close(cmd->fd_in);
|
||||
cmd->fd_in = open(tmp, O_RDONLY);
|
||||
}
|
||||
printf(" handle_fd: %s\n", input);
|
||||
return (next_in);
|
||||
}
|
||||
|
||||
t_cmd *fill_cmd(char *input, char **envp)
|
||||
{
|
||||
t_cmd *cmd;
|
||||
char **input_split;
|
||||
int i;
|
||||
int tmp_fd;
|
||||
|
||||
cmd = calloc(nbr_pipes(input), sizeof(t_cmd));
|
||||
input_split = ft_split(input, '|');
|
||||
tmp_fd = 0;
|
||||
i = 0;
|
||||
while (input_split[i])
|
||||
{
|
||||
tmp_fd = handle_fdd(input_split[i], tmp_fd, &cmd[i]);
|
||||
cmd[i].argv = ft_split(input_split[i], ' ');
|
||||
cmd[i].builtin = cmd_path(cmd[i].argv, envp);
|
||||
i++;
|
||||
}
|
||||
return (cmd);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* By: lperrey <lperrey@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2021/10/10 23:53:17 by lperrey #+# #+# */
|
||||
/* Updated: 2021/10/30 14:18:09 by lperrey ### ########.fr */
|
||||
/* Updated: 2021/11/10 17:15:44 by hulamy ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
@@ -18,8 +18,8 @@ int free_exit(t_all *c, int exit_status)
|
||||
free(c->prompt);
|
||||
ft_lstclear((t_list **)&c->token_list, free); // a voir avec Hugo, il y a un truc qui me semble superflu dans la fonction
|
||||
ft_free_2d_arr(c->envp);
|
||||
if (c->termios_changed)
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &c->ori_termios);
|
||||
// if (c->termios_changed)
|
||||
// tcsetattr(STDIN_FILENO, TCSANOW, &c->ori_termios);
|
||||
rl_clear_history();
|
||||
exit(exit_status);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* By: lperrey <lperrey@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2021/10/24 10:52:40 by lperrey #+# #+# */
|
||||
/* Updated: 2021/11/02 13:49:06 by hulamy ### ########.fr */
|
||||
/* Updated: 2021/11/11 13:11:55 by hulamy ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
@@ -140,26 +140,26 @@ void handle_argv(t_token *token, t_cmd **cmd, size_t cmd_nbr)
|
||||
|
||||
int fill_builtin(t_cmd *cmd, int (*builtin)(int, char **, t_all *))
|
||||
{
|
||||
cmd->builtin_command = &builtin;
|
||||
cmd->builtin_command = builtin;
|
||||
return (1);
|
||||
}
|
||||
|
||||
int handle_builtin(t_cmd *cmd)
|
||||
{
|
||||
if (!ft_strncmp(cmd->argv[0], "echo", 4))
|
||||
return (fill_builtin(cmd, &builtin_echo));
|
||||
// else if (!ft_strncmp(cmd->argv[0], "cd", 2))
|
||||
// return (fill_builtin(cmd, &builtin_cd));
|
||||
// else if (!ft_strncmp(cmd->argv[0], "pwd", 3))
|
||||
// return (fill_builtin(cmd, &builtin_pwd));
|
||||
// else if (!ft_strncmp(cmd->argv[0], "export", 6))
|
||||
// return (fill_builtin(cmd, &builtin_export));
|
||||
// else if (!ft_strncmp(cmd->argv[0], "unset", 5))
|
||||
// return (fill_builtin(cmd, &builtin_unset));
|
||||
return (fill_builtin(cmd, builtin_echo));
|
||||
else if (!ft_strncmp(cmd->argv[0], "cd", 2))
|
||||
return (fill_builtin(cmd, &builtin_cd));
|
||||
else if (!ft_strncmp(cmd->argv[0], "pwd", 3))
|
||||
return (fill_builtin(cmd, builtin_pwd));
|
||||
else if (!ft_strncmp(cmd->argv[0], "export", 6))
|
||||
return (fill_builtin(cmd, &builtin_export));
|
||||
else if (!ft_strncmp(cmd->argv[0], "unset", 5))
|
||||
return (fill_builtin(cmd, &builtin_unset));
|
||||
else if (!ft_strncmp(cmd->argv[0], "env", 3))
|
||||
return (fill_builtin(cmd, &builtin_env));
|
||||
return (fill_builtin(cmd, builtin_env));
|
||||
else if (!ft_strncmp(cmd->argv[0], "exit", 4))
|
||||
return (fill_builtin(cmd, &builtin_exit));
|
||||
return (fill_builtin(cmd, builtin_exit));
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,14 +6,14 @@
|
||||
/* By: lperrey <lperrey@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2021/10/04 05:59:26 by lperrey #+# #+# */
|
||||
/* Updated: 2021/11/10 13:43:10 by hulamy ### ########.fr */
|
||||
/* Updated: 2021/11/11 09:54:40 by hulamy ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "minishell.h"
|
||||
|
||||
void close_fd(t_cmd *cmd);
|
||||
void execute_cmd(char **envp, t_cmd **cmd_arr);
|
||||
void execute_cmd(char **envp, t_cmd **cmd_arr, t_all *c);
|
||||
|
||||
void shell_loop(t_all *c)
|
||||
{
|
||||
@@ -30,7 +30,7 @@ void shell_loop(t_all *c)
|
||||
add_history(line_input);
|
||||
c->token_list = input_to_tokens(line_input);
|
||||
c->cmd_arr = parsing(c->token_list, c->envp);
|
||||
execute_cmd(c->envp, c->cmd_arr);
|
||||
execute_cmd(c->envp, c->cmd_arr, c);
|
||||
ft_lstclear((t_list **)&c->token_list, free);
|
||||
}
|
||||
else if (!line_input)
|
||||
@@ -49,12 +49,13 @@ void close_fd(t_cmd *cmd)
|
||||
close(cmd->fd_out);
|
||||
}
|
||||
|
||||
void execute_cmd(char **envp, t_cmd **cmd_arr)
|
||||
void execute_cmd(char **envp, t_cmd **cmd_arr, t_all *c)
|
||||
{
|
||||
pid_t pid;
|
||||
pid_t wpid;
|
||||
int status;
|
||||
int i;
|
||||
int argc;
|
||||
|
||||
i = 0;
|
||||
while(cmd_arr[i])
|
||||
@@ -67,7 +68,15 @@ void execute_cmd(char **envp, t_cmd **cmd_arr)
|
||||
if (cmd_arr[i]->fd_out != 1)
|
||||
dup2(cmd_arr[i]->fd_out, STDOUT_FILENO);
|
||||
close_fd(cmd_arr[i]);
|
||||
execve(cmd_arr[i]->argv[0], cmd_arr[i]->argv, envp);
|
||||
if (cmd_arr[i]->builtin_command)
|
||||
{
|
||||
argc = 0;
|
||||
while (cmd_arr[i]->argv[argc])
|
||||
argc++;
|
||||
cmd_arr[i]->builtin_command(argc, cmd_arr[i]->argv, c);
|
||||
}
|
||||
else
|
||||
execve(cmd_arr[i]->argv[0], cmd_arr[i]->argv, envp);
|
||||
}
|
||||
else
|
||||
close_fd(cmd_arr[i]);
|
||||
|
||||
Reference in New Issue
Block a user