mirror of
https://codeberg.org/la-chouette/minishell.git
synced 2025-12-06 07:28:09 +01:00
feat(here_doc): handle signals (^C, ^\) correctly
This is a bit of a big commit, because I had to move some stuff to other files, sorry about that. I can split it up if it's too big to review.
This commit is contained in:
parent
5e6d7b3b4e
commit
f1a0af09f8
15 changed files with 269 additions and 126 deletions
|
|
@ -6,7 +6,7 @@
|
|||
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2025/03/07 11:42:29 by khais #+# #+# */
|
||||
/* Updated: 2025/03/28 19:07:45 by khais ### ########.fr */
|
||||
/* Updated: 2025/04/17 11:51:27 by khais ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
|
|
@ -16,81 +16,12 @@
|
|||
#include <unistd.h>
|
||||
#include "libft.h"
|
||||
#include "../../ft_errno.h"
|
||||
#include "../../sig/sig.h"
|
||||
#include "here_doc_utils.h"
|
||||
|
||||
char *expand_line(char *line, t_minishell *app);
|
||||
void failed_to_open_tmp_file(void);
|
||||
|
||||
/*
|
||||
** - check that arguments are not invalid
|
||||
** - create a random filename
|
||||
** - create the file
|
||||
**
|
||||
** do these operations, with error checking
|
||||
*/
|
||||
static int setup_here_doc(t_worddesc *marker, int infd, char **filename)
|
||||
{
|
||||
int outfd;
|
||||
|
||||
if (infd < 0 || marker == NULL || marker->word == NULL)
|
||||
return (ft_errno(FT_EINVAL), -1);
|
||||
*filename = here_doc_random_filename();
|
||||
if (filename == NULL)
|
||||
return (ft_errno(FT_EERRNO), -1);
|
||||
outfd = open(*filename, O_CREAT | O_WRONLY | O_EXCL, S_IRUSR | S_IWUSR);
|
||||
if (outfd < 0)
|
||||
return (ft_errno(FT_EERRNO), free(*filename), -1);
|
||||
return (outfd);
|
||||
}
|
||||
|
||||
/*
|
||||
** output line to outfd, get the next line from infd, and return it
|
||||
*/
|
||||
static char *output_line_and_next(int infd, int outfd, char *line)
|
||||
{
|
||||
ft_dprintf(outfd, "%s", line);
|
||||
free(line);
|
||||
line = get_next_line(infd);
|
||||
return (line);
|
||||
}
|
||||
|
||||
/*
|
||||
** seek filename to start, unlink filename, and return new outfd
|
||||
*/
|
||||
static int finalize(int outfd, char *filename)
|
||||
{
|
||||
close(outfd);
|
||||
outfd = open(filename, O_RDONLY, 0);
|
||||
unlink(filename);
|
||||
free(filename);
|
||||
if (outfd < 0)
|
||||
ft_errno(FT_EERRNO);
|
||||
return (outfd);
|
||||
}
|
||||
|
||||
/*
|
||||
** check if line corresponds to marker
|
||||
**
|
||||
** if true is returned, line has been freed
|
||||
*/
|
||||
static bool is_marker(char *line, t_worddesc *marker)
|
||||
{
|
||||
char *cleanline;
|
||||
int res;
|
||||
|
||||
cleanline = strip_newline(line);
|
||||
if (cleanline == NULL)
|
||||
{
|
||||
ft_dprintf(STDERR_FILENO, "Allocation failure!\n");
|
||||
free(line);
|
||||
return (true);
|
||||
}
|
||||
res = ft_strcmp(marker->word, cleanline);
|
||||
free(cleanline);
|
||||
if (res == 0)
|
||||
free(line);
|
||||
return (res == 0);
|
||||
}
|
||||
|
||||
/*
|
||||
** Read from infd into some file until a line that is exactly equal to the
|
||||
** marker is read.
|
||||
|
|
@ -112,7 +43,8 @@ int here_doc(t_worddesc *marker, int infd, t_minishell *app)
|
|||
|
||||
outfd = setup_here_doc(marker, infd, &filename);
|
||||
if (outfd < 0)
|
||||
return (failed_to_open_tmp_file(), -1);
|
||||
return (ft_errno(FT_EHEREDOC_FAILED), failed_to_open_tmp_file(), -1);
|
||||
set_here_doc_mode_sig_handling();
|
||||
line = get_next_line(infd);
|
||||
while (line != NULL)
|
||||
{
|
||||
|
|
@ -122,6 +54,8 @@ int here_doc(t_worddesc *marker, int infd, t_minishell *app)
|
|||
line = expand_line(line, app);
|
||||
line = output_line_and_next(infd, outfd, line);
|
||||
}
|
||||
if (g_signum != 0)
|
||||
return (ft_errno(FT_EHEREDOC_FAILED), interupted(outfd, filename));
|
||||
ft_dprintf(STDERR_FILENO, "minishell: warning: here-document delimited by \
|
||||
end-of-file (wanted `%s')\n", marker->word);
|
||||
return (finalize(outfd, filename));
|
||||
|
|
|
|||
100
src/executing/here_doc/here_doc_utils.c
Normal file
100
src/executing/here_doc/here_doc_utils.c
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* here_doc_utils.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2025/04/17 11:50:08 by khais #+# #+# */
|
||||
/* Updated: 2025/04/17 11:55:34 by khais ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "here_doc_utils.h"
|
||||
#include <stdlib.h>
|
||||
#include "../../ft_errno.h"
|
||||
#include "here_doc.h"
|
||||
#include "../../sig/sig.h"
|
||||
|
||||
/*
|
||||
** - check that arguments are not invalid
|
||||
** - create a random filename
|
||||
** - create the file
|
||||
**
|
||||
** do these operations, with error checking
|
||||
*/
|
||||
int setup_here_doc(t_worddesc *marker, int infd, char **filename)
|
||||
{
|
||||
int outfd;
|
||||
|
||||
if (infd < 0 || marker == NULL || marker->word == NULL)
|
||||
return (ft_errno(FT_EINVAL), -1);
|
||||
*filename = here_doc_random_filename();
|
||||
if (filename == NULL)
|
||||
return (ft_errno(FT_EERRNO), -1);
|
||||
outfd = open(*filename, O_CREAT | O_WRONLY | O_EXCL, S_IRUSR | S_IWUSR);
|
||||
if (outfd < 0)
|
||||
return (ft_errno(FT_EERRNO), free(*filename), -1);
|
||||
return (outfd);
|
||||
}
|
||||
|
||||
/*
|
||||
** output line to outfd, get the next line from infd, and return it
|
||||
*/
|
||||
char *output_line_and_next(int infd, int outfd, char *line)
|
||||
{
|
||||
ft_dprintf(outfd, "%s", line);
|
||||
free(line);
|
||||
line = get_next_line(infd);
|
||||
return (line);
|
||||
}
|
||||
|
||||
/*
|
||||
** seek filename to start, unlink filename, and return new outfd
|
||||
*/
|
||||
int 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);
|
||||
}
|
||||
|
||||
int interupted(int outfd, char *filename)
|
||||
{
|
||||
ft_printf("\n");
|
||||
close(outfd);
|
||||
unlink(filename);
|
||||
free(filename);
|
||||
g_signum = 0;
|
||||
set_interactive_mode_sig_handling();
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
** check if line corresponds to marker
|
||||
**
|
||||
** if true is returned, line has been freed
|
||||
*/
|
||||
bool is_marker(char *line, t_worddesc *marker)
|
||||
{
|
||||
char *cleanline;
|
||||
int res;
|
||||
|
||||
cleanline = strip_newline(line);
|
||||
if (cleanline == NULL)
|
||||
{
|
||||
ft_dprintf(STDERR_FILENO, "Allocation failure!\n");
|
||||
free(line);
|
||||
return (true);
|
||||
}
|
||||
res = ft_strcmp(marker->word, cleanline);
|
||||
free(cleanline);
|
||||
if (res == 0)
|
||||
free(line);
|
||||
return (res == 0);
|
||||
}
|
||||
24
src/executing/here_doc/here_doc_utils.h
Normal file
24
src/executing/here_doc/here_doc_utils.h
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* here_doc_utils.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2025/04/17 11:49:52 by khais #+# #+# */
|
||||
/* Updated: 2025/04/17 11:53:08 by khais ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef HERE_DOC_UTILS_H
|
||||
# define HERE_DOC_UTILS_H
|
||||
|
||||
# include "../../parser/worddesc/worddesc.h"
|
||||
|
||||
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);
|
||||
int interupted(int outfd, char *filename);
|
||||
bool is_marker(char *line, t_worddesc *marker);
|
||||
|
||||
#endif // HERE_DOC_UTILS_H
|
||||
Loading…
Add table
Add a link
Reference in a new issue