fix: redirection into pipe
This commit is contained in:
parent
1d322cf4d3
commit
867d239d1a
@ -55,7 +55,7 @@ int where(char** args, lst** env)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int builtin_execute(cmd* input, data_t *data, int fd_in, int fd_out)
|
int builtin_execute(cmd_t* input, data_t *data, int fd_in, int fd_out)
|
||||||
{
|
{
|
||||||
if (strcmp(input->executable, "cd") == 0)
|
if (strcmp(input->executable, "cd") == 0)
|
||||||
{
|
{
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
#include "../../lib/bozolib/bozolib.h"
|
#include "../../lib/bozolib/bozolib.h"
|
||||||
|
|
||||||
char* builtin_path(const char* executable);
|
char* builtin_path(const char* executable);
|
||||||
int builtin_execute(cmd* input, data_t* data, int fd_in, int fd_out);
|
int builtin_execute(cmd_t* input, data_t* data, int fd_in, int fd_out);
|
||||||
|
|
||||||
int builtin_alias(int fd_in, int fd_out, lst** aliases, char** args);
|
int builtin_alias(int fd_in, int fd_out, lst** aliases, char** args);
|
||||||
int change_directory(char** args, lst** env);
|
int change_directory(char** args, lst** env);
|
||||||
|
@ -2,9 +2,36 @@
|
|||||||
|
|
||||||
void cmd_del(void *ptr)
|
void cmd_del(void *ptr)
|
||||||
{
|
{
|
||||||
cmd* content = ptr;
|
cmd_t* content = ptr;
|
||||||
|
|
||||||
tab_free((void**)content->args);
|
tab_free((void**)content->args);
|
||||||
free(content->executable);
|
free(content->executable);
|
||||||
free(content);
|
free(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int cmd_init(cmd_t* command)
|
||||||
|
{
|
||||||
|
command->pid = -1;
|
||||||
|
command->input[0] = -1;
|
||||||
|
command->input[1] = -1;
|
||||||
|
command->output[0] = -1;
|
||||||
|
command->output[1] = -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmd_close(void* ptr)
|
||||||
|
{
|
||||||
|
cmd_t* content = ptr;
|
||||||
|
if (content->input[0] > 2)
|
||||||
|
close(content->input[0]);
|
||||||
|
content->input[0] = -1;
|
||||||
|
if (content->input[1] > 2)
|
||||||
|
close(content->input[1]);
|
||||||
|
content->input[1] = -1;
|
||||||
|
if (content->output[0] > 2)
|
||||||
|
close(content->output[0]);
|
||||||
|
content->output[0] = -1;
|
||||||
|
if (content->output[1] > 2)
|
||||||
|
close(content->output[1]);
|
||||||
|
content->output[1] = -1;
|
||||||
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "../../lib/bozolib/bozolib.h"
|
#include "../../lib/bozolib/bozolib.h"
|
||||||
|
|
||||||
@ -9,11 +10,11 @@ typedef struct s_cmd
|
|||||||
{
|
{
|
||||||
char *executable;
|
char *executable;
|
||||||
char **args;
|
char **args;
|
||||||
int fd_in;
|
int input[2];
|
||||||
int fd_out;
|
int output[2];
|
||||||
int pid;
|
int pid;
|
||||||
} cmd;
|
} cmd_t;
|
||||||
|
|
||||||
void cmd_del(void* ptr);
|
void cmd_del(void* ptr);
|
||||||
|
int cmd_init(cmd_t* command);
|
||||||
lst** cmds_init(size_t len);
|
void cmd_close(void* ptr);
|
||||||
|
@ -1,34 +0,0 @@
|
|||||||
#include "./cmd.h"
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
lst** cmds_init(size_t len)
|
|
||||||
{
|
|
||||||
lst** root;
|
|
||||||
lst* current;
|
|
||||||
cmd* content;
|
|
||||||
|
|
||||||
root = calloc(sizeof(lst*), 1);
|
|
||||||
if (root == NULL)
|
|
||||||
return (NULL);
|
|
||||||
for (size_t i = 0; i < len; i++)
|
|
||||||
{
|
|
||||||
current = malloc(sizeof(lst));
|
|
||||||
if (current == NULL)
|
|
||||||
{
|
|
||||||
lst_clear(root, &free);
|
|
||||||
free(root);
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
lst_addback(root, current);
|
|
||||||
content = calloc(sizeof(cmd), 1);
|
|
||||||
if (content == NULL)
|
|
||||||
{
|
|
||||||
lst_clear(root, &free);
|
|
||||||
free(root);
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
current->content = content;
|
|
||||||
}
|
|
||||||
return (root);
|
|
||||||
}
|
|
@ -11,36 +11,36 @@
|
|||||||
#include "../builtin-exec/builtin.h"
|
#include "../builtin-exec/builtin.h"
|
||||||
#include "../data/data.h"
|
#include "../data/data.h"
|
||||||
|
|
||||||
int execute(cmd* input, lst** env)
|
int execute(lst** cmds, cmd_t* cmd, lst** env)
|
||||||
{
|
{
|
||||||
int pid;
|
int pid;
|
||||||
int exitcode;
|
if (cmd->executable != NULL)
|
||||||
if (input->executable != NULL)
|
|
||||||
pid = fork();
|
pid = fork();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dprintf(2, "Executable inconnu\n");
|
dprintf(2, "Executable inconnu\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (pid == 0)
|
if (pid == -1)
|
||||||
|
return 1;
|
||||||
|
else if (pid == 0)
|
||||||
{
|
{
|
||||||
dup2(input->fd_out, 1);
|
char** env_str = get_env_str(env);
|
||||||
dup2(input->fd_in, 0);
|
if (env_str == NULL)
|
||||||
if (input->fd_in > 2)
|
return 1;
|
||||||
close(input->fd_in);
|
dup2(cmd->output[0], 1);
|
||||||
if (input->fd_out > 2)
|
dup2(cmd->input[0], 0);
|
||||||
close(input->fd_out);
|
lst_iter(cmds, &cmd_close);
|
||||||
exitcode = execve(input->executable, input->args, get_env_str(env));
|
execve(cmd->executable, cmd->args, env_str);
|
||||||
|
dprintf(2, "execve failed\n");
|
||||||
|
free((void**)env_str);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (input->fd_in > 2)
|
cmd->pid = pid;
|
||||||
close(input->fd_in);
|
|
||||||
if (input->fd_out > 2)
|
|
||||||
close(input->fd_out);
|
|
||||||
waitpid(pid, &exitcode, 0);
|
|
||||||
}
|
}
|
||||||
return exitcode;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* get_executable_path(const char* executable, lst** env)
|
char* get_executable_path(const char* executable, lst** env)
|
||||||
@ -72,27 +72,42 @@ char* get_executable_path(const char* executable, lst** env)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void add_fd(int fds[2], int fd)
|
||||||
|
{
|
||||||
|
if (fds[0] == -1)
|
||||||
|
fds[0] = fd;
|
||||||
|
else
|
||||||
|
fds[1] = fd;
|
||||||
|
}
|
||||||
|
|
||||||
int cmds_list_exec(lst** cmds, data_t *data)
|
int cmds_list_exec(lst** cmds, data_t *data)
|
||||||
{
|
{
|
||||||
lst* current = *cmds;
|
lst* current = *cmds;
|
||||||
cmd* content;
|
cmd_t* content;
|
||||||
int fds[2];
|
int fds[2];
|
||||||
while (current != NULL)
|
while (current != NULL)
|
||||||
{
|
{
|
||||||
content = current->content;
|
content = current->content;
|
||||||
if (pipe(fds) < 0)
|
|
||||||
return 1;
|
|
||||||
if (current->next != NULL)
|
if (current->next != NULL)
|
||||||
{
|
{
|
||||||
content->fd_out = fds[1];
|
if (pipe(fds) == -1)
|
||||||
((cmd*)current->next->content)->fd_in = fds[0];
|
return 1;
|
||||||
|
add_fd(content->output, fds[1]);
|
||||||
|
add_fd(((cmd_t*)current->next->content)->input, fds[0]);
|
||||||
}
|
}
|
||||||
if (content->args[0] == NULL)
|
if (content->args[0] == NULL)
|
||||||
;
|
;
|
||||||
else if (content->executable == NULL)
|
else if (content->executable == NULL)
|
||||||
dprintf(2, "zzsh: command not found: %s\n", content->args[0]);
|
dprintf(2, "zzsh: command not found: %s\n", content->args[0]);
|
||||||
else if (builtin_execute(content, data, fds[0], fds[1]) == 1)
|
else if (builtin_execute(content, data, fds[0], fds[1]) == 1)
|
||||||
execute(content, data->env);
|
{
|
||||||
|
if (execute(cmds, content, data->env))
|
||||||
|
{
|
||||||
|
cmd_close(content);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
cmd_close(content);
|
||||||
|
}
|
||||||
current = current->next;
|
current = current->next;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -5,6 +5,4 @@
|
|||||||
#include "../data/data.h"
|
#include "../data/data.h"
|
||||||
|
|
||||||
int cmds_list_exec(lst** cmds, data_t *data);
|
int cmds_list_exec(lst** cmds, data_t *data);
|
||||||
int execute(cmd* input, lst** env);
|
|
||||||
int builtin_execute(cmd* input, data_t* data, int fd_int, int fd_out);
|
|
||||||
char* get_executable_path(const char* executable, lst** env);
|
char* get_executable_path(const char* executable, lst** env);
|
||||||
|
@ -51,7 +51,7 @@ int main(int ac, char **av, char **env_str)
|
|||||||
}
|
}
|
||||||
line = get_user_input(&data);
|
line = get_user_input(&data);
|
||||||
}
|
}
|
||||||
lst_clear(data.aliases, alias_del);
|
lst_clear(data.aliases, &alias_del);
|
||||||
lst_clear(data.env, &env_del);
|
lst_clear(data.env, &env_del);
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
|
@ -9,9 +9,11 @@ char* parsing_executable(const char* executable, data_t *data)
|
|||||||
return (get_executable_path(executable, data->env));
|
return (get_executable_path(executable, data->env));
|
||||||
}
|
}
|
||||||
|
|
||||||
int parsing_cmd(char *str, cmd* command, data_t *data)
|
int parsing_cmd(char *str, cmd_t* command, data_t *data)
|
||||||
{
|
{
|
||||||
char* tmp;
|
char* tmp;
|
||||||
|
if (cmd_init(command))
|
||||||
|
return 1;
|
||||||
if (get_redirections(str, command))
|
if (get_redirections(str, command))
|
||||||
return 1;
|
return 1;
|
||||||
command->args = split_quoted_charset(str, "\t ");
|
command->args = split_quoted_charset(str, "\t ");
|
||||||
@ -52,20 +54,56 @@ lst **parsing_pipe(const char *str, data_t *data)
|
|||||||
cmds_str = split_quoted_charset(str, "|");
|
cmds_str = split_quoted_charset(str, "|");
|
||||||
if (cmds_str == NULL)
|
if (cmds_str == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
cmds = cmds_init(tablen((const void**)cmds_str));
|
cmds = malloc(sizeof(lst*));
|
||||||
if (cmds == NULL)
|
if (cmds == NULL)
|
||||||
{
|
{
|
||||||
tab_free((void**)cmds_str);
|
tab_free((void**)cmds_str);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
if (cmds_str[0] != NULL)
|
||||||
|
{
|
||||||
|
*cmds = malloc(sizeof(lst));
|
||||||
|
if (*cmds == NULL)
|
||||||
|
{
|
||||||
|
free(cmds);
|
||||||
|
tab_free((void**)cmds_str);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
current = *cmds;
|
current = *cmds;
|
||||||
|
}
|
||||||
for (size_t i = 0; cmds_str[i] != NULL; i++)
|
for (size_t i = 0; cmds_str[i] != NULL; i++)
|
||||||
{
|
{
|
||||||
|
current->content = malloc(sizeof(cmd_t));
|
||||||
|
if (current->content == NULL)
|
||||||
|
{
|
||||||
|
tab_free((void**)cmds_str);
|
||||||
|
lst_clear(cmds, &cmd_del);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
if (parsing_cmd(cmds_str[i], current->content, data))
|
if (parsing_cmd(cmds_str[i], current->content, data))
|
||||||
{
|
{
|
||||||
tab_free((void**)cmds_str);
|
tab_free((void**)cmds_str);
|
||||||
|
lst_clear(cmds, &cmd_del);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
if (cmds_str[i + 1] != NULL)
|
||||||
|
{
|
||||||
|
current->next = malloc(sizeof(lst));
|
||||||
|
if (current->next == NULL)
|
||||||
|
{
|
||||||
|
tab_free((void**)cmds_str);
|
||||||
|
lst_clear(cmds, &cmd_del);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
current->next = NULL;
|
||||||
|
if (i == 0)
|
||||||
|
if (((cmd_t*) current->content)->input[0] == -1)
|
||||||
|
((cmd_t*) current->content)->input[0] = 0;
|
||||||
|
if (current->next == NULL)
|
||||||
|
if (((cmd_t*) current->content)->output[0] == -1)
|
||||||
|
((cmd_t*) current->content)->output[0] = 1;
|
||||||
current = current->next;
|
current = current->next;
|
||||||
}
|
}
|
||||||
tab_free((void**)cmds_str);
|
tab_free((void**)cmds_str);
|
||||||
|
@ -36,32 +36,35 @@ static size_t get_path_size(const char* str)
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
int redirection_fill(const char* str, size_t nb_symbols, cmd* command, const char *path)
|
int redirection_fill(const char* str, size_t nb_symbols, cmd_t* command, const char *path)
|
||||||
{
|
{
|
||||||
int problem = 0;
|
int fd;
|
||||||
if (str[0] == '>')
|
if (str[0] == '>')
|
||||||
{
|
{
|
||||||
if (command->fd_out > 2)
|
|
||||||
close(command->fd_out);
|
|
||||||
if (nb_symbols == 1)
|
if (nb_symbols == 1)
|
||||||
command->fd_out = open(path, O_TRUNC | O_CREAT | O_WRONLY, 0644);
|
fd = open(path, O_TRUNC | O_CREAT | O_WRONLY, 0644);
|
||||||
else
|
else
|
||||||
command->fd_out = open(path, O_APPEND | O_CREAT | O_WRONLY, 0644);
|
fd = open(path, O_APPEND | O_CREAT | O_WRONLY, 0644);
|
||||||
problem = command->fd_out == -1;
|
if (fd == -1)
|
||||||
|
dprintf(2, "zzsh: \"%s\": file error\n", path);
|
||||||
|
if (command->output[0] > 2)
|
||||||
|
close(command->output[0]);
|
||||||
|
command->output[0] = fd;
|
||||||
|
return (fd == -1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (command->fd_in > 2)
|
|
||||||
close(command->fd_in);
|
|
||||||
if (nb_symbols == 1)
|
if (nb_symbols == 1)
|
||||||
command->fd_in = open(path, O_RDONLY);
|
fd = open(path, O_RDONLY);
|
||||||
else
|
else
|
||||||
command->fd_in = open(path, O_RDONLY);
|
fd = open(path, O_RDONLY);
|
||||||
problem = command->fd_in == -1;
|
if (fd == -1)
|
||||||
}
|
|
||||||
if (problem)
|
|
||||||
dprintf(2, "zzsh: \"%s\": file error\n", path);
|
dprintf(2, "zzsh: \"%s\": file error\n", path);
|
||||||
return problem;
|
if (command->input[0] > 2)
|
||||||
|
close(command->input[0]);
|
||||||
|
command->input[0] = fd;
|
||||||
|
return (fd == -1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t get_concecutive(const char *str)
|
static size_t get_concecutive(const char *str)
|
||||||
@ -71,7 +74,7 @@ static size_t get_concecutive(const char *str)
|
|||||||
return (i);
|
return (i);
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_redirections(char *str, cmd* command)
|
int get_redirections(char *str, cmd_t* command)
|
||||||
{
|
{
|
||||||
char *redirection;
|
char *redirection;
|
||||||
char redirection_symbol[3] = "<>";
|
char redirection_symbol[3] = "<>";
|
||||||
|
@ -8,4 +8,4 @@
|
|||||||
#include "../cmd/cmd.h"
|
#include "../cmd/cmd.h"
|
||||||
#include "../utils/utils.h"
|
#include "../utils/utils.h"
|
||||||
|
|
||||||
int get_redirections(char *str, cmd* command);
|
int get_redirections(char *str, cmd_t* command);
|
||||||
|
Loading…
Reference in New Issue
Block a user