176 lines
3.2 KiB
C
176 lines
3.2 KiB
C
#include "minishell.h"
|
|
|
|
static t_command *command_new(void)
|
|
{
|
|
t_command *cmd = (t_command *)calloc(1, sizeof(t_command));
|
|
return cmd;
|
|
}
|
|
|
|
static void command_add_arg(t_command *cmd, const char *text)
|
|
{
|
|
char **new_argv;
|
|
int i;
|
|
|
|
if (!cmd || !text)
|
|
return;
|
|
i = cmd->argc;
|
|
new_argv = (char **)calloc((size_t)i + 2, sizeof(char *));
|
|
if (!new_argv)
|
|
return;
|
|
for (int j = 0; j < i; j++)
|
|
new_argv[j] = cmd->argv[j];
|
|
new_argv[i] = ms_strdup(text);
|
|
new_argv[i + 1] = NULL;
|
|
free(cmd->argv);
|
|
cmd->argv = new_argv;
|
|
cmd->argc += 1;
|
|
}
|
|
|
|
static void command_add_redir(t_command *cmd, t_redirtype type, const char *target)
|
|
{
|
|
t_redir *r = (t_redir *)calloc(1, sizeof(t_redir));
|
|
t_redir *cur;
|
|
if (!r)
|
|
return;
|
|
r->type = type;
|
|
r->target = ms_strdup(target);
|
|
r->fd = -1;
|
|
r->next = NULL;
|
|
if (!cmd->redirs)
|
|
{
|
|
cmd->redirs = r;
|
|
return;
|
|
}
|
|
cur = cmd->redirs;
|
|
while (cur->next)
|
|
cur = cur->next;
|
|
cur->next = r;
|
|
}
|
|
|
|
static void free_redirs(t_redir *r)
|
|
{
|
|
t_redir *n;
|
|
while (r)
|
|
{
|
|
n = r->next;
|
|
if (r->fd != -1)
|
|
close(r->fd);
|
|
free(r->target);
|
|
free(r);
|
|
r = n;
|
|
}
|
|
}
|
|
|
|
void free_pipeline(t_pipeline *p)
|
|
{
|
|
size_t i;
|
|
if (!p)
|
|
return;
|
|
for (i = 0; i < p->count; i++)
|
|
{
|
|
if (p->cmds[i])
|
|
{
|
|
for (int j = 0; p->cmds[i]->argv && p->cmds[i]->argv[j]; j++)
|
|
free(p->cmds[i]->argv[j]);
|
|
free(p->cmds[i]->argv);
|
|
free(p->cmds[i]->path);
|
|
free_redirs(p->cmds[i]->redirs);
|
|
free(p->cmds[i]);
|
|
}
|
|
}
|
|
free(p->cmds);
|
|
free(p);
|
|
}
|
|
|
|
static int pipeline_add_cmd(t_pipeline *p, t_command *cmd)
|
|
{
|
|
t_command **new_cmds;
|
|
size_t i;
|
|
|
|
new_cmds = (t_command **)calloc(p->count + 1, sizeof(t_command *));
|
|
if (!new_cmds)
|
|
return 1;
|
|
for (i = 0; i < p->count; i++)
|
|
new_cmds[i] = p->cmds[i];
|
|
new_cmds[p->count] = cmd;
|
|
free(p->cmds);
|
|
p->cmds = new_cmds;
|
|
p->count += 1;
|
|
return 0;
|
|
}
|
|
|
|
t_pipeline *parse_tokens(t_token *toks, int *error)
|
|
{
|
|
t_pipeline *p;
|
|
t_command *cmd;
|
|
t_token *cur;
|
|
|
|
*error = 0;
|
|
p = (t_pipeline *)calloc(1, sizeof(t_pipeline));
|
|
if (!p)
|
|
return NULL;
|
|
cmd = command_new();
|
|
if (!cmd)
|
|
{
|
|
free(p);
|
|
return NULL;
|
|
}
|
|
cur = toks;
|
|
while (cur)
|
|
{
|
|
if (cur->type == TOK_PIPE)
|
|
{
|
|
if (cmd->argc == 0)
|
|
{
|
|
*error = 1;
|
|
free_pipeline(p);
|
|
free(cmd);
|
|
return NULL;
|
|
}
|
|
pipeline_add_cmd(p, cmd);
|
|
cmd = command_new();
|
|
if (!cmd)
|
|
{
|
|
*error = 1;
|
|
free_pipeline(p);
|
|
return NULL;
|
|
}
|
|
cur = cur->next;
|
|
continue;
|
|
}
|
|
if (cur->type == TOK_REDIR_IN || cur->type == TOK_REDIR_OUT
|
|
|| cur->type == TOK_REDIR_APPEND || cur->type == TOK_HEREDOC)
|
|
{
|
|
if (!cur->next || cur->next->type != TOK_WORD)
|
|
{
|
|
*error = 1;
|
|
free_pipeline(p);
|
|
free(cmd);
|
|
return NULL;
|
|
}
|
|
if (cur->type == TOK_REDIR_IN)
|
|
command_add_redir(cmd, REDIR_IN, cur->next->text);
|
|
else if (cur->type == TOK_REDIR_OUT)
|
|
command_add_redir(cmd, REDIR_OUT, cur->next->text);
|
|
else if (cur->type == TOK_REDIR_APPEND)
|
|
command_add_redir(cmd, REDIR_APPEND, cur->next->text);
|
|
else if (cur->type == TOK_HEREDOC)
|
|
command_add_redir(cmd, REDIR_HEREDOC, cur->next->text);
|
|
cur = cur->next->next;
|
|
continue;
|
|
}
|
|
if (cur->type == TOK_WORD)
|
|
command_add_arg(cmd, cur->text);
|
|
cur = cur->next;
|
|
}
|
|
if (cmd->argc == 0)
|
|
{
|
|
*error = 1;
|
|
free_pipeline(p);
|
|
free(cmd);
|
|
return NULL;
|
|
}
|
|
pipeline_add_cmd(p, cmd);
|
|
return p;
|
|
}
|