fix(execution): Reimplemented the redirection logic
This commit is contained in:
parent
a98161d885
commit
ec63be42e5
4 changed files with 75 additions and 32 deletions
|
|
@ -14,8 +14,6 @@
|
||||||
#include "../utils/ast/ast.h"
|
#include "../utils/ast/ast.h"
|
||||||
#include "../utils/hash_map/hash_map.h"
|
#include "../utils/hash_map/hash_map.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Refactored: delegates to helpers in execution_helpers.c
|
// Refactored: delegates to helpers in execution_helpers.c
|
||||||
#include "execution_helpers.h"
|
#include "execution_helpers.h"
|
||||||
|
|
||||||
|
|
@ -33,6 +31,7 @@ int execution(struct ast *ast, struct hash_map *vars)
|
||||||
struct ast_command *command = ast_get_command(ast);
|
struct ast_command *command = ast_get_command(ast);
|
||||||
if (!expand(command, vars))
|
if (!expand(command, vars))
|
||||||
fprintf(stderr, "Error: Variable expansion failed\n");
|
fprintf(stderr, "Error: Variable expansion failed\n");
|
||||||
|
|
||||||
return exec_ast_command(command, vars);
|
return exec_ast_command(command, vars);
|
||||||
}
|
}
|
||||||
case AST_IF:
|
case AST_IF:
|
||||||
|
|
@ -41,8 +40,6 @@ int execution(struct ast *ast, struct hash_map *vars)
|
||||||
return exec_ast_list(ast_get_list(ast), vars);
|
return exec_ast_list(ast_get_list(ast), vars);
|
||||||
case AST_AND_OR:
|
case AST_AND_OR:
|
||||||
return exec_ast_and_or(ast_get_and_or(ast), vars);
|
return exec_ast_and_or(ast_get_and_or(ast), vars);
|
||||||
case AST_REDIR:
|
|
||||||
return exec_ast_redir(ast_get_redir(ast), vars);
|
|
||||||
default:
|
default:
|
||||||
return 127;
|
return 127;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@
|
||||||
#include "../expansion/expansion.h"
|
#include "../expansion/expansion.h"
|
||||||
#include "../utils/ast/ast.h"
|
#include "../utils/ast/ast.h"
|
||||||
#include "../utils/hash_map/hash_map.h"
|
#include "../utils/hash_map/hash_map.h"
|
||||||
|
#include "../utils/lists/lists.h"
|
||||||
#include "../utils/vars/vars.h"
|
#include "../utils/vars/vars.h"
|
||||||
#include "execution.h"
|
#include "execution.h"
|
||||||
|
|
||||||
|
|
@ -42,40 +43,56 @@ static int try_builtin(char **argv, struct hash_map *vars);
|
||||||
int exec_ast_command(struct ast_command *command, struct hash_map *vars)
|
int exec_ast_command(struct ast_command *command, struct hash_map *vars)
|
||||||
{
|
{
|
||||||
(void)vars;
|
(void)vars;
|
||||||
|
set_all_redir(command->redirections);
|
||||||
|
|
||||||
if (!command || !(command->command))
|
if (!command || !(command->command))
|
||||||
|
{
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
char **argv = list_to_argv(command->command);
|
char **argv = list_to_argv(command->command);
|
||||||
if (!argv || !(argv[0]))
|
if (!argv || !(argv[0]))
|
||||||
{
|
{
|
||||||
free(argv);
|
free(argv);
|
||||||
|
unset_all_redir();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int builtin_ret = try_builtin(argv, vars);
|
int builtin_ret = try_builtin(argv, vars);
|
||||||
if (builtin_ret != -1)
|
if (builtin_ret != -1)
|
||||||
{
|
{
|
||||||
free(argv);
|
free(argv);
|
||||||
|
unset_all_redir();
|
||||||
return builtin_ret;
|
return builtin_ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
pid_t pid = fork();
|
pid_t pid = fork();
|
||||||
if (pid < 0)
|
if (pid < 0)
|
||||||
{
|
{
|
||||||
perror("fork");
|
perror("fork");
|
||||||
free(argv);
|
free(argv);
|
||||||
|
unset_all_redir();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pid == 0)
|
if (pid == 0)
|
||||||
{
|
{
|
||||||
execvp(argv[0], argv);
|
execvp(argv[0], argv);
|
||||||
perror("execvp");
|
perror("execvp");
|
||||||
|
unset_all_redir();
|
||||||
_exit(127);
|
_exit(127);
|
||||||
}
|
}
|
||||||
|
|
||||||
int status = 0;
|
int status = 0;
|
||||||
waitpid(pid, &status, 0);
|
waitpid(pid, &status, 0);
|
||||||
free(argv);
|
free(argv);
|
||||||
|
unset_all_redir();
|
||||||
|
|
||||||
if (WIFEXITED(status))
|
if (WIFEXITED(status))
|
||||||
{
|
{
|
||||||
return WEXITSTATUS(status);
|
return WEXITSTATUS(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -166,42 +183,71 @@ static int handle_and_restore_fd(int saved_fd, int fd_target)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static int set_all_redir(struct list *redir_list)
|
||||||
|
|
||||||
static open_all_redir(const struct ast_list redir_list)
|
|
||||||
{
|
{
|
||||||
while (redir_list){
|
while (redir_list)
|
||||||
struct ast_redir *redir = (struct ast_redir*)redir_list->data;
|
{
|
||||||
|
struct ast_redir *redir = (struct ast_redir *)redir_list->data;
|
||||||
int target_fd;
|
int target_fd;
|
||||||
|
|
||||||
if (redir->io_number != -1)
|
if (redir->io_number != -1)
|
||||||
{
|
{
|
||||||
target_fd = redir->io_number;
|
target_fd = redir->io_number;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// assign target_fd depending on redir type
|
||||||
|
if (redir->type == AST_REDIR_TYPE_LESS
|
||||||
|
|| redir->type == AST_REDIR_TYPE_LESSGREAT
|
||||||
|
|| redir->type == AST_REDIR_TYPE_LESSAND)
|
||||||
|
{
|
||||||
|
target_fd = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
target_fd = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
// assign target_fd depending on redir type
|
|
||||||
}
|
|
||||||
|
|
||||||
int saved_fd = dup(target_fd);
|
redir->saved_fd = dup(target_fd);
|
||||||
|
int new_fd = -1;
|
||||||
// if redir type is not with '&'
|
int flags = 0;
|
||||||
// then we open("filename")
|
int mode = 0644;
|
||||||
// else, no need to open, just new_fd = atoi(filename)
|
if (redir->type == AST_REDIR_TYPE_GREAT
|
||||||
|
|| redir->type == AST_REDIR_TYPE_CLOBBER
|
||||||
open();
|
|| redir->type == AST_REDIR_TYPE_DGREAT
|
||||||
|
|| redir->type == AST_REDIR_TYPE_LESS)
|
||||||
dup2(target_fd, new_fd);
|
{
|
||||||
|
new_fd = open_redir_file(redir, &flags, &mode);
|
||||||
close(new_fd);
|
if (new_fd == -1)
|
||||||
|
{
|
||||||
// append target_fd and saved_fd to a list
|
perror("open");
|
||||||
// in order to be able to restore all the fds
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (redir->type == AST_REDIR_TYPE_GREATAND
|
||||||
|
|| redir->type == AST_REDIR_TYPE_LESSAND)
|
||||||
|
{
|
||||||
|
new_fd = atoi(redir->filename);
|
||||||
|
}
|
||||||
|
if (dup2(new_fd, target_fd) == -1)
|
||||||
|
{
|
||||||
|
perror("dup2");
|
||||||
|
if (new_fd != -1)
|
||||||
|
{
|
||||||
|
close(new_fd);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (new_fd != -1)
|
||||||
|
{
|
||||||
|
close(new_fd);
|
||||||
|
}
|
||||||
|
redir_list = redir_list->next;
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
*/
|
|
||||||
/*
|
/*
|
||||||
int exec_ast_redir(struct ast_redir *redir, struct hash_map *vars)
|
int exec_ast_redir(struct ast_redir *redir, struct hash_map *vars)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,5 @@ int exec_ast_command(struct ast_command *command, struct hash_map *vars);
|
||||||
int exec_ast_if(struct ast_if *if_node, struct hash_map *vars);
|
int exec_ast_if(struct ast_if *if_node, struct hash_map *vars);
|
||||||
int exec_ast_list(struct ast_list *list_node, struct hash_map *vars);
|
int exec_ast_list(struct ast_list *list_node, struct hash_map *vars);
|
||||||
int exec_ast_and_or(struct ast_and_or *ao_node, struct hash_map *vars);
|
int exec_ast_and_or(struct ast_and_or *ao_node, struct hash_map *vars);
|
||||||
int exec_ast_redir(struct ast_redir *redir, struct hash_map *vars);
|
|
||||||
|
|
||||||
#endif // EXECUTION_HELPERS_H
|
#endif // EXECUTION_HELPERS_H
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ struct ast_redir
|
||||||
int io_number; // The FD being redirected (default -1 if not specified,
|
int io_number; // The FD being redirected (default -1 if not specified,
|
||||||
// implies 0 or 1 based on type)
|
// implies 0 or 1 based on type)
|
||||||
enum ast_redir_type type;
|
enum ast_redir_type type;
|
||||||
|
int saved_fd; // To store the original FD for restoration (-1 before save)
|
||||||
};
|
};
|
||||||
|
|
||||||
bool ast_is_redir(struct ast *node);
|
bool ast_is_redir(struct ast *node);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue