Make subshell execute in a new process
authorLukáš Jiřiště <jiriste@icpf.cas.cz>
Wed, 28 Aug 2024 07:59:34 +0000 (09:59 +0200)
committerLukáš Jiřiště <jiriste@icpf.cas.cz>
Wed, 28 Aug 2024 08:39:03 +0000 (10:39 +0200)
Because the OS keeps track of CWDs of its processes, subshell is made to
run in its own process not to change the CWD of main shell.
Also make exit the last executed command in a pipeline and in a program.

inc/minishell_structs.h
src/env.c
src/execution.c
src/main.c

index 5c9f5ba8cf1c18639d120fca44a841df9ea12501..e3894c7446463c614443ee83e1a8a6bdf80640c2 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: ljiriste <ljiriste@student.42prague.com>   +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/08/26 09:08:46 by ljiriste          #+#    #+#             */
-/*   Updated: 2024/08/27 16:59:59 by ljiriste         ###   ########.fr       */
+/*   Updated: 2024/08/28 09:36:55 by ljiriste         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -32,6 +32,7 @@ typedef struct s_execution_env
        int             stdout_fd;
        int             ret_val;
        int             exit;
+       int             subshell;
        int             last_was_builtin;
        int             last_builtin_ret_val;
        t_vars  *vars;
index 44d2a3033373dd67a190ba5eeaf7098068e117e0..7f6dac81855edd80eca9909ff3b49914f39a4e46 100644 (file)
--- a/src/env.c
+++ b/src/env.c
@@ -6,7 +6,7 @@
 /*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/07/21 21:24:52 by ljiriste          #+#    #+#             */
-/*   Updated: 2024/08/27 16:37:47 by ljiriste         ###   ########.fr       */
+/*   Updated: 2024/08/28 09:36:37 by ljiriste         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -23,6 +23,7 @@ int   init_env(t_execution_env *env, char **envp)
        env->ret_val = 0;
        env->exit = 0;
        env->last_was_builtin = 0;
+       env->subshell = 0;
        env->vars = malloc(sizeof(t_vars));
        if (!env->vars)
                return (1);
index 9a07f8248c0dbe7ccd382ee46f84f93127808630..a3ba582d5457da80b4aca12051d4b80bb4bf5e89 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: lnikolov <lnikolov@student.42prague.com    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/07/21 08:57:54 by ljiriste          #+#    #+#             */
-/*   Updated: 2024/08/27 16:59:59 by ljiriste         ###   ########.fr       */
+/*   Updated: 2024/08/28 09:54:48 by ljiriste         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -934,45 +934,37 @@ t_ft_stat v_copy_redir(void *v_dest, const void *v_src)
        return (success);
 }
 
-int    copy_env(t_execution_env *copy, const t_execution_env *env)
-{
-       *copy = *env;
-       copy->vars = malloc(sizeof(t_vars));
-       if (!copy->vars)
-               return (1);
-       ft_vec_init(&copy->vars->exported, sizeof(char *));
-       ft_vec_init(&copy->vars->other, sizeof(char *));
-       ft_vec_copy(&copy->vars->exported, &env->vars->exported, v_strcopy, free);
-       ft_vec_copy(&copy->vars->other, &env->vars->other, v_strcopy, free);
-       return (0);
-}
-
-void   free_env(t_execution_env *env)
-{
-       clean_vars(env->vars);
-       free(env->vars);
-       return ;
-}
-
 int    ex_program(t_parse_tree_node *program, t_execution_env *env);
 
 int    subshell(t_parse_tree_node *program, t_execution_env *env)
 {
-       int                                     res;
-       t_execution_env env_copy;
+       int             res;
+       int             status;
+       pid_t   pid;
 
-       if (copy_env(&env_copy, env))
+       pid = fork();
+       if (pid == 0)
+       {
+               env->subshell = 1;
+               res = ex_program(program, env);
+               env->exit = 1;
+               return (res);
+       }
+       else if (pid < 0)
                return (1);
-       res = ex_program(program, &env_copy);
-       env->ret_val = env_copy.ret_val;
-       free_env(&env_copy);
-       return (res);
+       waitpid(pid, &status, 0);
+       if (!WIFEXITED(status))
+               return (1);
+       env->ret_val = WEXITSTATUS(status);
+       return (0);
 }
 
 int    ex_command(t_parse_tree_node *command, t_execution_env *env)
 {
        t_parse_tree_node       *comp_command;
 
+       if (env->exit)
+               return (0);
        if (is_token_type(ft_vec_caccess(&command->children, 0), "simple_command"))
                return (ex_simple_command(ft_vec_access(&command->children, 0), env));
        else
index 72319287e158fbaccf1a5d06e100b105910a3532..337843e6b5bcbbf3aba11c5a3c399f2b17017831 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/04/26 13:11:47 by ljiriste          #+#    #+#             */
-/*   Updated: 2024/08/27 15:08:06 by ljiriste         ###   ########.fr       */
+/*   Updated: 2024/08/28 09:38:51 by ljiriste         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -56,10 +56,11 @@ int main(int argc, __attribute__((unused)) char **argv, char **envp)
                handle_input(&line, &env);
                free(line);
        }
+       if (!env.subshell)
+               ft_printf("exit\n");
        res = env.ret_val;
        clean_env(&env);
        parse(NULL, NULL);
        terminate_input();
-       ft_printf("exit\n");
        return (res);
 }