diff --git a/src/execution/execution.c b/src/execution/execution.c index fff9be2..28726e5 100644 --- a/src/execution/execution.c +++ b/src/execution/execution.c @@ -46,6 +46,9 @@ int execution(struct ast *ast, struct hash_map *vars) case AST_LOOP: res = exec_ast_loop(ast_get_loop(ast), vars); break; + case AST_SUBSHELL: + res = exec_ast_subshell(ast_get_subshell(ast), vars); + break; default: res = 127; break; diff --git a/src/execution/execution_helpers.c b/src/execution/execution_helpers.c index 59580e8..65054df 100644 --- a/src/execution/execution_helpers.c +++ b/src/execution/execution_helpers.c @@ -249,6 +249,33 @@ int exec_ast_if(struct ast_if *if_node, struct hash_map *vars) } } +int exec_ast_subshell(struct ast_subshell *subshell_node, + struct hash_map *vars) +{ + pid_t pid = fork(); + if (pid < 0) + { + perror("fork"); + return 1; + } + + if (pid == 0) + { + int res = execution(subshell_node->child, vars); + _exit(res); + } + + int status = 0; + waitpid(pid, &status, 0); + + if (WIFEXITED(status)) + { + return WEXITSTATUS(status); + } + + return 1; +} + int exec_ast_list(struct ast_list *list_node, struct hash_map *vars) { struct list *cur = list_node->children; diff --git a/src/execution/execution_helpers.h b/src/execution/execution_helpers.h index ee28c3d..8a56e18 100644 --- a/src/execution/execution_helpers.h +++ b/src/execution/execution_helpers.h @@ -14,6 +14,8 @@ 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_and_or(struct ast_and_or *ao_node, struct hash_map *vars); int exec_ast_loop(struct ast_loop *loop_node, struct hash_map *vars); +int exec_ast_subshell(struct ast_subshell *subshell_node, + struct hash_map *vars); void unset_all_redir(struct list *redir_list); #endif // EXECUTION_HELPERS_H diff --git a/src/utils/ast/ast.c b/src/utils/ast/ast.c index 5baaf6a..d16a9cb 100644 --- a/src/utils/ast/ast.c +++ b/src/utils/ast/ast.c @@ -11,8 +11,7 @@ void ast_free(struct ast **node) { if (node == NULL || *node == NULL) { - fprintf( - stderr, + fprintf(stderr, "WARNING: Internal error: failed to free AST node (NULL argument)"); return; } @@ -52,14 +51,16 @@ void ast_free(struct ast **node) case AST_FUNCTION: ast_free_function(ast_get_function(*node)); break; + case AST_SUBSHELL: + ast_free_subshell(ast_get_subshell(*node)); + break; case AST_VOID: case AST_END: break; default: - fprintf(stderr, - "WARNING: Internal error: failed to free an AST node (Unknown " - "type)"); + fprintf(stderr, "WARNING: Internal error:" + " failed to free an AST node (Unknown type)"); return; } @@ -170,4 +171,4 @@ void ast_print_dot(struct ast *ast) fprintf(dot_pipe, "}\n"); pclose(dot_pipe); } - */ \ No newline at end of file + */