fix(redirection): prevent fd leak in subprocess when doing redirection with multiple processes

This commit is contained in:
Khaïs COLIN 2025-04-29 16:39:48 +02:00
parent 5ea55a9f9c
commit 95451520d6
8 changed files with 32 additions and 47 deletions

View file

@ -6,7 +6,7 @@
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/03/07 11:42:29 by khais #+# #+# */
/* Updated: 2025/04/17 11:51:27 by khais ### ########.fr */
/* Updated: 2025/04/29 16:56:08 by khais ### ########.fr */
/* */
/* ************************************************************************** */
@ -33,9 +33,9 @@ void failed_to_open_tmp_file(void);
**
** If NULL is given as argument, or marker->word is null, or infd is negative,
** or getting a random filename fails, or we are unable to create the file, or
** the file already exists, or any other error occurs, return -1.
** the file already exists, or any other error occurs, return NULL.
*/
int here_doc(t_worddesc *marker, int infd, t_minishell *app)
char *here_doc(t_worddesc *marker, int infd, t_minishell *app)
{
int outfd;
char *filename;
@ -43,7 +43,7 @@ int here_doc(t_worddesc *marker, int infd, t_minishell *app)
outfd = setup_here_doc(marker, infd, &filename);
if (outfd < 0)
return (ft_errno(FT_EHEREDOC_FAILED), failed_to_open_tmp_file(), -1);
return (ft_errno(FT_EHEREDOC_FAILED), failed_to_open_tmp_file(), NULL);
set_here_doc_mode_sig_handling();
line = get_next_line(infd);
while (line != NULL)
@ -55,7 +55,8 @@ int here_doc(t_worddesc *marker, int infd, t_minishell *app)
line = output_line_and_next(infd, outfd, line);
}
if (g_signum != 0)
return (ft_errno(FT_EHEREDOC_FAILED), interupted(outfd, filename));
return (ft_errno(FT_EHEREDOC_FAILED), interupted(outfd, filename),
NULL);
ft_dprintf(STDERR_FILENO, "minishell: warning: here-document delimited by \
end-of-file (wanted `%s')\n", marker->word);
return (finalize(outfd, filename));

View file

@ -6,7 +6,7 @@
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/03/07 11:41:27 by khais #+# #+# */
/* Updated: 2025/03/28 15:57:17 by khais ### ########.fr */
/* Updated: 2025/04/29 16:38:05 by khais ### ########.fr */
/* */
/* ************************************************************************** */
@ -16,7 +16,7 @@
# include "../../parser/worddesc/worddesc.h"
# include "../../minishell.h"
int here_doc(t_worddesc *marker, int infd, t_minishell *app);
char *here_doc(t_worddesc *marker, int infd, t_minishell *app);
char *here_doc_random_filename(void);
char *strip_newline(char *str);

View file

@ -6,7 +6,7 @@
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/04/17 11:50:08 by khais #+# #+# */
/* Updated: 2025/04/17 11:55:34 by khais ### ########.fr */
/* Updated: 2025/04/29 16:39:22 by khais ### ########.fr */
/* */
/* ************************************************************************** */
@ -50,18 +50,13 @@ char *output_line_and_next(int infd, int outfd, char *line)
}
/*
** seek filename to start, unlink filename, and return new outfd
** closes outfd, reset correct sig mode handling
*/
int finalize(int outfd, char *filename)
char *finalize(int outfd, char *filename)
{
close(outfd);
outfd = open(filename, O_RDONLY, 0);
unlink(filename);
free(filename);
if (outfd < 0)
ft_errno(FT_EERRNO);
set_interactive_mode_sig_handling();
return (outfd);
return (filename);
}
int interupted(int outfd, char *filename)

View file

@ -6,7 +6,7 @@
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/04/17 11:49:52 by khais #+# #+# */
/* Updated: 2025/04/17 11:53:08 by khais ### ########.fr */
/* Updated: 2025/04/29 16:37:56 by khais ### ########.fr */
/* */
/* ************************************************************************** */
@ -17,7 +17,7 @@
int setup_here_doc(t_worddesc *marker, int infd, char **filename);
char *output_line_and_next(int infd, int outfd, char *line);
int finalize(int outfd, char *filename);
char *finalize(int outfd, char *filename);
int interupted(int outfd, char *filename);
bool is_marker(char *line, t_worddesc *marker);

View file

@ -6,7 +6,7 @@
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/04/17 11:14:40 by khais #+# #+# */
/* Updated: 2025/04/28 12:47:50 by khais ### ########.fr */
/* Updated: 2025/04/29 16:55:24 by khais ### ########.fr */
/* */
/* ************************************************************************** */
@ -29,15 +29,12 @@ static t_redirect *do_redirection(t_redirect *redirection)
{
int fd;
fd = open(redirection->redirectee.filename->word,
redirection->open_flags, redirection->c_flags);
if (redirection->type == FT_HEREDOC)
fd = redirection->redirectee.dest;
else
{
fd = open(redirection->redirectee.filename->word,
redirection->open_flags, redirection->c_flags);
if (fd < 0)
return (redirection_error(redirection->redirectee.filename->word));
}
unlink(redirection->redirectee.filename->word);
if (fd < 0)
return (redirection_error(redirection->redirectee.filename->word));
if (dup2(fd, redirection->source) < 0)
return (perror("minishell: dup2"), NULL);
close(fd);

View file

@ -6,7 +6,7 @@
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/04/09 16:53:02 by khais #+# #+# */
/* Updated: 2025/04/21 10:55:02 by khais ### ########.fr */
/* Updated: 2025/04/29 16:40:44 by khais ### ########.fr */
/* */
/* ************************************************************************** */
@ -23,8 +23,7 @@ void redirect_destroy(t_redirect *redirect)
{
next = redirect->next;
free(redirect->here_doc_eof);
if (redirect->type != FT_HEREDOC)
worddesc_destroy(redirect->redirectee.filename);
worddesc_destroy(redirect->redirectee.filename);
free(redirect->unexpanded_filename);
free(redirect);
redirect = next;

View file

@ -6,7 +6,7 @@
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/04/09 15:07:58 by khais #+# #+# */
/* Updated: 2025/04/29 13:12:54 by khais ### ########.fr */
/* Updated: 2025/04/29 16:49:04 by khais ### ########.fr */
/* */
/* ************************************************************************** */
@ -37,11 +37,7 @@ static void redirectee_debug(t_redirectee redirectee, t_buffer *leader,
indent(leader, is_last);
ft_dprintf(STDERR_FILENO, "t_redirectee\n");
if (is_here_doc)
{
indent(leader, false);
ft_dprintf(STDERR_FILENO, "dest = %d\n", redirectee.dest);
dedent(leader, false);
}
worddesc_debug(redirectee.filename, leader, true);
else
worddesc_debug(redirectee.filename, leader, true);
dedent(leader, is_last);

View file

@ -3,10 +3,10 @@
/* ::: :::::::: */
/* redirect_from_words.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jguelen <jguelen@student.42.fr> +#+ +:+ +#+ */
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/04/14 17:31:35 by khais #+# #+# */
/* Updated: 2025/04/28 16:50:11 by jguelen ### ########.fr */
/* Created: 2025/04/30 10:35/43 by khais #+# #+# */
/* Updated: 2025/04/30 10:35:43 by khais ### ########.fr */
/* */
/* ************************************************************************** */
@ -61,7 +61,6 @@ static t_redirect *redir_basic_setup(t_worddesc *operator,
redir->source = redir_source_from_type(redir->type);
redir->open_flags = redir_open_flags_from_type(redir->type);
redir->c_flags = 0644;
redir->redirectee.dest = -1;
return (redir);
}
@ -72,6 +71,7 @@ t_redirect *redir_from_words(t_worddesc *operator,
t_worddesc *spec;
redir = redir_basic_setup(operator, specifier);
worddesc_destroy(operator);
if (redir == NULL)
return (NULL);
if (redir->type == FT_HEREDOC)
@ -79,16 +79,13 @@ t_redirect *redir_from_words(t_worddesc *operator,
redir->here_doc_eof = ft_strdup(specifier->word);
spec = remove_quotes(specifier);
worddesc_destroy(specifier);
redir->redirectee.dest = here_doc(spec, STDIN_FILENO, app);
redir->redirectee.filename = worddesc_create(
here_doc(spec, STDIN_FILENO, app), 0, NULL, WORD_TOKEN);
worddesc_destroy(spec);
if (redir->redirectee.dest < 0)
{
ft_errno(FT_EERRNO);
return (worddesc_destroy(operator), redirect_destroy(redir), NULL);
}
if (redir->redirectee.filename == NULL)
return (redirect_destroy(redir), ft_errno(FT_EERRNO), NULL);
}
else
redir->redirectee.filename = specifier;
worddesc_destroy(operator);
return (redir);
}