mirror of
https://codeberg.org/la-chouette/minishell.git
synced 2025-12-06 07:28:09 +01:00
fix(exec): prevent leak when calling exit() in a subprocess
This was because at the point at which exit is called, we can only free a t_simple_cmd, but not the whole t_cmd tree. This commit introduces a convention of returning a t_subprocess enum from each function in exec. If the current thread is a subprocess, SUBPROCESS is returned, else PARENTPROCESS. We also no longer call exit in subproceses. This way, all processes bubble up to main, where if SUBPROCESS is returned, all memory is freed and the program exits. This also removes the previous should_exit convention. Still TODO: handling of the exit builtin, which should also bubble up in the same way.
This commit is contained in:
parent
3c350af411
commit
93f3ea7c66
16 changed files with 111 additions and 89 deletions
|
|
@ -6,7 +6,7 @@
|
|||
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2025/03/27 16:21:56 by khais #+# #+# */
|
||||
/* Updated: 2025/04/28 15:57:23 by khais ### ########.fr */
|
||||
/* Updated: 2025/04/29 15:10:35 by khais ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
|
|
@ -72,47 +72,46 @@ static t_simple_cmd *post_process_command(t_simple_cmd *cmd, t_minishell *app)
|
|||
return (cmd);
|
||||
}
|
||||
|
||||
static void exec_external_cmd(t_simple_cmd *cmd, t_minishell *app,
|
||||
static t_subprocess exec_external_cmd(t_simple_cmd *cmd, t_minishell *app,
|
||||
t_std_fds *fds)
|
||||
{
|
||||
char *exe;
|
||||
int pid;
|
||||
|
||||
if (cmd->words == NULL)
|
||||
return (restore_std_fds(fds));
|
||||
return (restore_std_fds(fds), PARENTPROCESS);
|
||||
exe = get_cmdpath(cmd->words->word->word, app);
|
||||
if (exe != NULL)
|
||||
{
|
||||
pid = fork();
|
||||
if (pid == 0)
|
||||
execute_subprocess(exe, cmd, app, fds);
|
||||
return (execute_subprocess(exe, cmd, app, fds));
|
||||
free(exe);
|
||||
do_waitpid(app, pid);
|
||||
}
|
||||
restore_std_fds(fds);
|
||||
if (exe == NULL)
|
||||
command_not_found(cmd, app);
|
||||
return (PARENTPROCESS);
|
||||
}
|
||||
|
||||
void simple_cmd_execute(t_simple_cmd *cmd, t_minishell *app,
|
||||
bool should_exit)
|
||||
t_subprocess simple_cmd_execute(t_simple_cmd *cmd, t_minishell *app)
|
||||
{
|
||||
t_std_fds fds;
|
||||
|
||||
if (cmd == NULL)
|
||||
return ;
|
||||
return (PARENTPROCESS);
|
||||
ft_errno(FT_ESUCCESS);
|
||||
if (post_process_command(cmd, app) == NULL)
|
||||
{
|
||||
if (ft_errno_get() != FT_ESUCCESS)
|
||||
ft_dprintf(STDERR_FILENO, "minishell: post-processing error\n");
|
||||
return ;
|
||||
return (PARENTPROCESS);
|
||||
}
|
||||
simple_cmd_execute_debug(cmd, app);
|
||||
if (handle_redirections(cmd->redirections, app, &fds) == NULL)
|
||||
return ;
|
||||
return (PARENTPROCESS);
|
||||
if (execute_builtin(cmd, app, &fds) == BUILTIN_INVALID)
|
||||
exec_external_cmd(cmd, app, &fds);
|
||||
if (should_exit)
|
||||
exit(app->last_return_value);
|
||||
return (exec_external_cmd(cmd, app, &fds));
|
||||
return (PARENTPROCESS);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue