mirror of
https://codeberg.org/la-chouette/minishell.git
synced 2025-12-06 07:28:09 +01:00
here_doc: handle input with correct end marker
This commit is contained in:
parent
a6d1386574
commit
7c6d061c6c
8 changed files with 191 additions and 44 deletions
|
|
@ -6,7 +6,7 @@
|
|||
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2025/03/07 11:42:29 by khais #+# #+# */
|
||||
/* Updated: 2025/03/11 11:38:42 by khais ### ########.fr */
|
||||
/* Updated: 2025/03/11 13:31:15 by khais ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
|
|
@ -14,46 +14,75 @@
|
|||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include "../../ft_errno.h"
|
||||
#include "../../buffer/buffer.h"
|
||||
#include "libft/libft.h"
|
||||
#include "libft.h"
|
||||
|
||||
/*
|
||||
** Genereate a random filename for use by here_doc
|
||||
** - check that arguments are not invalid
|
||||
** - create a random filename
|
||||
** - create the file
|
||||
**
|
||||
** The filename will be of the form
|
||||
** /tmp/minishell_here_doc_XXXXXXXXXXX
|
||||
** where each X is a random alphanumerical char
|
||||
**
|
||||
** Random bytes are generated by reading from /dev/urandom
|
||||
**
|
||||
** Return NULL and sets ft_errno on error
|
||||
** do these operations, with error checking
|
||||
*/
|
||||
char *here_doc_random_filename(void)
|
||||
static int setup_here_doc(t_worddesc *marker, int infd, char **filename)
|
||||
{
|
||||
int randomfd;
|
||||
char buf[1];
|
||||
t_buffer *filename;
|
||||
int outfd;
|
||||
|
||||
randomfd = open("/dev/urandom", O_RDONLY);
|
||||
if (randomfd < 0)
|
||||
return (ft_errno(FT_EERRNO), NULL);
|
||||
filename = ft_buffer_new();
|
||||
if (infd < 0 || marker == NULL || marker->word == NULL)
|
||||
return (-1);
|
||||
*filename = here_doc_random_filename();
|
||||
if (filename == NULL)
|
||||
return (close(randomfd), ft_errno(FT_EERRNO), NULL);
|
||||
filename = ft_buffer_push_buf(filename, "/tmp/minishell_here_doc_", 24);
|
||||
while (filename->length < 35)
|
||||
return (-1);
|
||||
outfd = open(*filename, O_CREAT | O_WRONLY | O_EXCL, S_IRUSR | S_IWUSR);
|
||||
if (outfd < 0)
|
||||
return (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);
|
||||
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)
|
||||
{
|
||||
if (read(randomfd, buf, 1) != 1)
|
||||
{
|
||||
ft_buffer_free(filename);
|
||||
return (close(randomfd), ft_errno(FT_EERRNO), NULL);
|
||||
}
|
||||
if (ft_isalnum(buf[0]))
|
||||
filename = ft_buffer_pushchar(filename, buf[0]);
|
||||
ft_dprintf(STDERR_FILENO, "Allocation failure!\n");
|
||||
free(line);
|
||||
return (true);
|
||||
}
|
||||
close(randomfd);
|
||||
return (ft_buffer_to_charptr(filename));
|
||||
res = ft_strcmp(marker->word, cleanline);
|
||||
free(cleanline);
|
||||
if (res == 0)
|
||||
free(line);
|
||||
return (res == 0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -70,14 +99,18 @@ int here_doc(t_worddesc *marker, int infd)
|
|||
{
|
||||
int outfd;
|
||||
char *filename;
|
||||
char *line;
|
||||
|
||||
if (infd < 0 || marker == NULL || marker->word == NULL)
|
||||
return (-1);
|
||||
filename = here_doc_random_filename();
|
||||
if (filename == NULL)
|
||||
return (-1);
|
||||
outfd = open(filename, O_CREAT | O_WRONLY | O_EXCL, S_IRUSR | S_IWUSR);
|
||||
outfd = setup_here_doc(marker, infd, &filename);
|
||||
if (outfd < 0)
|
||||
return (free(filename), -1);
|
||||
return (outfd);
|
||||
return (-1);
|
||||
line = get_next_line(infd);
|
||||
while (line != NULL)
|
||||
{
|
||||
if (is_marker(line, marker))
|
||||
line = NULL;
|
||||
else
|
||||
line = output_line_and_next(infd, outfd, line);
|
||||
}
|
||||
return (finalize(outfd, filename));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2025/03/07 11:41:27 by khais #+# #+# */
|
||||
/* Updated: 2025/03/11 11:32:12 by khais ### ########.fr */
|
||||
/* Updated: 2025/03/11 13:31:52 by khais ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
|
|
@ -17,5 +17,6 @@
|
|||
|
||||
int here_doc(t_worddesc *marker, int infd);
|
||||
char *here_doc_random_filename(void);
|
||||
char *strip_newline(char *str);
|
||||
|
||||
#endif // HERE_DOC_H
|
||||
|
|
|
|||
56
src/executing/here_doc/random_filename.c
Normal file
56
src/executing/here_doc/random_filename.c
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* random_filename.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2025/03/11 13:29:32 by khais #+# #+# */
|
||||
/* Updated: 2025/03/11 13:30:33 by khais ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "here_doc.h"
|
||||
#include "../../ft_errno.h"
|
||||
#include "../../buffer/buffer.h"
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include "libft.h"
|
||||
|
||||
/*
|
||||
** Genereate a random filename for use by here_doc
|
||||
**
|
||||
** The filename will be of the form
|
||||
** /tmp/minishell_here_doc_XXXXXXXXXXX
|
||||
** where each X is a random alphanumerical char
|
||||
**
|
||||
** Random bytes are generated by reading from /dev/urandom
|
||||
**
|
||||
** Return NULL and sets ft_errno on error
|
||||
*/
|
||||
char *here_doc_random_filename(void)
|
||||
{
|
||||
int randomfd;
|
||||
char buf[1];
|
||||
t_buffer *filename;
|
||||
|
||||
randomfd = open("/dev/urandom", O_RDONLY);
|
||||
if (randomfd < 0)
|
||||
return (ft_errno(FT_EERRNO), NULL);
|
||||
filename = ft_buffer_new();
|
||||
if (filename == NULL)
|
||||
return (close(randomfd), ft_errno(FT_EERRNO), NULL);
|
||||
filename = ft_buffer_push_buf(filename, "/tmp/minishell_here_doc_", 24);
|
||||
while (filename->length < 35)
|
||||
{
|
||||
if (read(randomfd, buf, 1) != 1)
|
||||
{
|
||||
ft_buffer_free(filename);
|
||||
return (close(randomfd), ft_errno(FT_EERRNO), NULL);
|
||||
}
|
||||
if (ft_isalnum(buf[0]))
|
||||
filename = ft_buffer_pushchar(filename, buf[0]);
|
||||
}
|
||||
close(randomfd);
|
||||
return (ft_buffer_to_charptr(filename));
|
||||
}
|
||||
32
src/executing/here_doc/strip_newline.c
Normal file
32
src/executing/here_doc/strip_newline.c
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* strip_newline.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2025/03/11 13:31:22 by khais #+# #+# */
|
||||
/* Updated: 2025/03/11 13:31:31 by khais ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "libft.h"
|
||||
|
||||
/*
|
||||
** create a new string without the terminating newline of the given string.
|
||||
**
|
||||
** If the given string has no terminating newline, create a copy of the input
|
||||
*/
|
||||
char *strip_newline(char *str)
|
||||
{
|
||||
size_t last_char_idx;
|
||||
char *outstr;
|
||||
|
||||
if (str == NULL)
|
||||
return (NULL);
|
||||
last_char_idx = ft_strlen(str) - 1;
|
||||
outstr = ft_strdup(str);
|
||||
if (str[last_char_idx] == '\n')
|
||||
outstr[last_char_idx] = '\0';
|
||||
return (outstr);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue