Browse Source

bonus add: handle operators and parenthesis

master
narnaud 3 years ago
parent
commit
93889251a8
  1. 8
      README.md
  2. 37
      caller.c
  3. 11
      lexer.c
  4. 30
      minishell.c
  5. 8
      minishell.h
  6. 12
      parser.c
  7. 15
      utils.c

8
README.md

@ -5,12 +5,10 @@
- Protect mallocs,
- verify exits codes
https://wiki.bash-hackers.org/scripting/basics?s[]=variables#exit_codes
- do the `(...)` -> `./minishell ...` conversion
- finish && and ||
## Issues :
- deeply test bonus
-
## Issues :
- cat | ls ; cat | cat | ls ...
## Notes :

37
caller.c

@ -6,7 +6,7 @@
/* By: mea <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/05/03 11:48:16 by narnaud #+# #+# */
/* Updated: 2022/05/10 09:56:53 by mea ### ########.fr */
/* Updated: 2022/05/11 01:15:39 by narnaud@stude ### ########.fr */
/* */
/* ************************************************************************** */
@ -55,25 +55,36 @@ int builtin_call(t_datas *datas, t_command *cmd)
int piper(t_datas *datas, t_command *cmd)
{
int pip[2];
int status;
pid_t pid;
int status;
int exit_code;
if (cmd->fd[1] == 0 && cmd->next && cmd->next->fd[0] == 0)
if (cmd->ope == PIPE)
{
pipe(pip);
cmd->fd[1] = pip[1];
cmd->next->fd[0] = pip[0];
if (!cmd->fd[1])
cmd->fd[1] = pip[1];
if (!cmd->fd[0])
cmd->next->fd[0] = pip[0];
}
pid = caller(datas, cmd);
if (cmd->fd[1])
close(cmd->fd[1]);
if (cmd->next)
piper(datas, cmd->next);
waitpid(pid, &status, 0);
if (!cmd->next)
handle_status(datas, status);
if (cmd->fd[0])
close(cmd->fd[0]);
printf("%s -ope: %d, pid: %d, fdin: %d, fdout: %d\n", cmd->argv[0], cmd->ope, pid, cmd->fd[0], cmd->fd[1]);
if (cmd->ope == PIPE)
pid = piper(datas, cmd->next);
else
{
waitpid(pid, &status, 0);
exit_code = handle_status(datas, status);
if (!cmd->next)
datas->exit_code = exit_code;
else if (cmd->next && ((cmd->ope == AND && !exit_code) \
|| (cmd->ope == OR && exit_code)))
piper(datas, cmd->next);
}
return (1);
}
@ -113,9 +124,15 @@ static pid_t caller(t_datas *datas, t_command *cmd)
if (builtin_call(datas, cmd) == -1)
{
if (cmd->fd[0])
{
dup2(cmd->fd[0], STDIN_FILENO);
close(cmd->fd[0]);
}
if (cmd->fd[1])
{
dup2(cmd->fd[1], STDOUT_FILENO);
close(cmd->fd[1]);
}
exe(datas, cmd);
}
exit(EXIT_SUCCESS);

11
lexer.c

@ -6,7 +6,7 @@
/* By: mea <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/05/02 13:44:57 by narnaud #+# #+# */
/* Updated: 2022/05/10 10:12:58 by mea ### ########.fr */
/* Updated: 2022/05/11 01:17:45 by narnaud@stude ### ########.fr */
/* */
/* ************************************************************************** */
@ -147,7 +147,12 @@ static int check_register(t_lexer *lex, char **line, char *tmp)
return (create_token(lex, tmp));
if (check_ope(lex, line, tmp))
return (1);
if ((**line == '(' || spaces) && (*tmp || lex->empty))
return (create_token(lex, tmp));
if (**line == '(' || spaces)
{
if (**line == '(')
lex->deep++;
if (*tmp || lex->empty)
return (create_token(lex, tmp));
}
return (0);
}

30
minishell.c

@ -6,7 +6,7 @@
/* By: mea <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/05/02 12:14:09 by narnaud #+# #+# */
/* Updated: 2022/05/07 23:08:05 by narnaud@stude ### ########.fr */
/* Updated: 2022/05/11 00:45:01 by narnaud@stude ### ########.fr */
/* */
/* ************************************************************************** */
@ -52,16 +52,16 @@ void free_cmd(t_command *cmd)
free(cmd);
}
void prompt(t_datas *datas)
void prompt(t_datas *datas, char *line)
{
char *line;
t_command *cmd;
termios(0);
line = readline("$ ");
if (!line)
line = readline("$ ");
termios(1);
if (line == NULL)
halt(datas, EXIT_SUCCESS);
halt(datas, EXIT_SUCCESS, datas->silent);
if (is_empty(line))
return ;
cmd = parser(datas, lexer(datas, line), NULL);
@ -78,13 +78,23 @@ int main(int argc, char **argv, char **envp)
static t_datas datas;
static int i = 0;
datas.silent = argc > 1;
(void)argc;
datas.envp = ft_calloc(ENVP_MAX_SIZE, sizeof(char *));
while (*envp)
datas.envp[i++] = ft_strdup(*(envp++));
datas.exit_code = 0;
if (argc < 2)
(void)argv;
while (1)
prompt(&datas);
halt(&datas, EXIT_SUCCESS);
if (datas.silent)
{
i = 1;
while (i < argc)
{
prompt(&datas, argv[i]);
i++;
}
}
else
while (1)
prompt(&datas, NULL);
halt(&datas, EXIT_SUCCESS, datas.silent);
}

8
minishell.h

@ -6,7 +6,7 @@
/* By: mea <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/05/02 13:50:44 by narnaud #+# #+# */
/* Updated: 2022/05/10 10:20:04 by mea ### ########.fr */
/* Updated: 2022/05/11 00:24:26 by narnaud@stude ### ########.fr */
/* */
/* ************************************************************************** */
@ -34,6 +34,7 @@ typedef struct s_command
{
char **argv;
int argc;
int ope;
int fd[2];
struct s_command *next;
struct s_command *prev;
@ -43,14 +44,15 @@ typedef struct s_datas
{
char **envp;
int exit_code;
int silent;
} t_datas;
// ----------------------------------Utils.c
int is_empty(char *line);
void handle_status(t_datas *datas, int status);
int handle_status(t_datas *datas, int status);
void nothing(int sig_num);
void sigs_handler(int sig_num);
void halt(t_datas *datas, int ret_code);
void halt(t_datas *datas, int ret_code, int silent);
typedef struct s_lex t_lexer;
// ----------------------------------Utils_2.c

12
parser.c

@ -6,7 +6,7 @@
/* By: mea <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/05/02 16:09:25 by narnaud #+# #+# */
/* Updated: 2022/05/09 09:56:29 by narnaud ### ########.fr */
/* Updated: 2022/05/11 01:13:20 by narnaud@stude ### ########.fr */
/* */
/* ************************************************************************** */
@ -30,6 +30,7 @@ t_command *parser(t_datas *datas, t_token *tok, t_command *prev)
tok = parse_cmd(datas, tok, cmd);
if (tok)
{
cmd->ope = tok->type;
cmd->next = parser(datas, tok->next, cmd);
free(tok->value);
free(tok);
@ -46,6 +47,8 @@ static size_t count_arguments(t_token *tok)
{
if (tok->type == WORD)
ret++;
if (tok->value[0] == '(')
ret++;
tok = tok->next;
}
return (ret);
@ -57,7 +60,12 @@ static t_token *parse_cmd(t_datas *datas, t_token *tok, t_command *cmd)
{
t_token *prev_tok;
if (tok->type)
if (tok->value[0] == '(')
{
cmd->argv[cmd->argc++] = ft_strdup("./minishell");
cmd->argv[cmd->argc++] = ft_substr(tok->value, 1, ft_strlen(tok->value) - 2);
}
else if (tok->type)
update_redir(datas, cmd, tok);
else
cmd->argv[cmd->argc++] = ft_strdup(tok->value);

15
utils.c

@ -6,7 +6,7 @@
/* By: mea <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/05/03 08:57:53 by narnaud #+# #+# */
/* Updated: 2022/05/06 13:15:33 by narnaud ### ########.fr */
/* Updated: 2022/05/11 00:22:13 by narnaud@stude ### ########.fr */
/* */
/* ************************************************************************** */
@ -23,16 +23,18 @@ int is_empty(char *line)
return (1);
}
void handle_status(t_datas *datas, int status)
int handle_status(t_datas *datas, int status)
{
int ret;
if (WIFSIGNALED(status))
{
datas->exit_code = 128 + WTERMSIG(status);
ret = 128 + WTERMSIG(status);
if (datas->exit_code == 131)
printf("Quit: 3\n");
}
else
datas->exit_code = WEXITSTATUS(status);
ret = WEXITSTATUS(status);
return ret;
}
void nothing(int sig_num)
@ -50,7 +52,7 @@ void sigs_handler(int sig_num)
return ;
}
void halt(t_datas *datas, int ret_code)
void halt(t_datas *datas, int ret_code, int silent)
{
int i;
@ -62,6 +64,7 @@ void halt(t_datas *datas, int ret_code)
}
free(datas->envp);
clear_history();
printf("exit\n");
if (!silent)
printf("exit\n");
exit(ret_code);
}

Loading…
Cancel
Save