├── src ├── utils │ ├── signals2.c │ ├── signals.c │ ├── debug.c │ ├── array_utils.c │ ├── free.c │ ├── list_token.c │ ├── list_utils.c │ ├── ms_utils.c │ └── list_cmd.c ├── builtin │ ├── ft_pwd.c │ ├── ft_env.c │ ├── ft_echo.c │ ├── ft_exit.c │ ├── ft_cd.c │ ├── ft_unset.c │ └── ft_export.c ├── parsing │ ├── quote.c │ ├── create_cmd.c │ ├── cmd_param.c │ ├── dollar_env.c │ ├── dollar_replace.c │ ├── cmd_fd.c │ └── create_token.c ├── exec │ ├── here_doc.c │ ├── launch_builtin.c │ ├── find_cmd.c │ ├── exec2.c │ └── exec.c └── main.c ├── Libft ├── src │ ├── ft_isascii.c │ ├── ft_isdigit.c │ ├── ft_isprint.c │ ├── ft_putchar_fd.c │ ├── ft_tolower.c │ ├── ft_toupper.c │ ├── ft_isalpha.c │ ├── ft_lstdelone.c │ ├── ft_lstlast.c │ ├── ft_putstr_fd.c │ ├── ft_isalnum.c │ ├── ft_lstadd_front.c │ ├── ft_lstiter.c │ ├── ft_lstsize.c │ ├── ft_bzero.c │ ├── ft_striteri.c │ ├── ft_putendl_fd.c │ ├── ft_lstnew.c │ ├── ft_lstadd_back.c │ ├── ft_lstclear.c │ ├── ft_strlen.c │ ├── ft_strncmp.c │ ├── ft_putnbr_fd.c │ ├── ft_calloc.c │ ├── ft_strmapi.c │ ├── ft_strdup.c │ ├── ft_lstmap.c │ ├── ft_strjoin.c │ ├── ft_strrchr.c │ ├── ft_strchr.c │ ├── ft_memmove.c │ ├── ft_strlcpy.c │ ├── ft_atoi.c │ ├── get_next_line.h │ ├── ft_memcpy.c │ ├── ft_itoa.c │ ├── ft_memset.c │ ├── ft_strtrim.c │ ├── ft_memcmp.c │ ├── ft_substr.c │ ├── ft_memchr.c │ ├── ft_strlcat.c │ ├── ft_strnstr.c │ ├── ft_split.c │ ├── libft.h │ ├── get_next_line.c │ └── get_next_line_utils.c └── Makefile ├── Makefile ├── include └── minishell.h └── README.md /src/utils/signals2.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* signals2.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: reldnah +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/05/12 11:20:46 by reldnah #+# #+# */ 9 | /* Updated: 2023/05/12 11:50:05 by reldnah ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "../../include/minishell.h" 14 | 15 | void signals2(void) 16 | { 17 | signal(SIGQUIT, SIG_DFL); 18 | } 19 | -------------------------------------------------------------------------------- /Libft/src/ft_isascii.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_isascii.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/11/08 09:44:54 by handler #+# #+# */ 9 | /* Updated: 2022/11/08 12:39:51 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | int ft_isascii(int c) 14 | { 15 | if (c >= 0 && c <= 127) 16 | return (1); 17 | return (0); 18 | } 19 | -------------------------------------------------------------------------------- /Libft/src/ft_isdigit.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_isdigit.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/11/08 09:45:03 by handler #+# #+# */ 9 | /* Updated: 2022/11/08 12:41:38 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | int ft_isdigit(int c) 14 | { 15 | if (c >= 48 && c <= 57) 16 | return (1); 17 | return (0); 18 | } 19 | -------------------------------------------------------------------------------- /Libft/src/ft_isprint.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_isprint.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/11/08 09:45:12 by handler #+# #+# */ 9 | /* Updated: 2022/11/08 12:41:41 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | int ft_isprint(int c) 14 | { 15 | if (c >= 32 && c <= 126) 16 | return (1); 17 | return (0); 18 | } 19 | -------------------------------------------------------------------------------- /Libft/src/ft_putchar_fd.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_putchar_fd.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/11/09 23:51:43 by handler #+# #+# */ 9 | /* Updated: 2022/11/11 14:08:27 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | void ft_putchar_fd(char c, int fd) 16 | { 17 | write(fd, &c, 1); 18 | } 19 | -------------------------------------------------------------------------------- /Libft/src/ft_tolower.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_tolower.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/11/08 09:45:27 by handler #+# #+# */ 9 | /* Updated: 2022/11/08 12:41:53 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | int ft_tolower(int c) 14 | { 15 | if (c >= 65 && c <= 90) 16 | return (c + 32); 17 | return (c); 18 | } 19 | -------------------------------------------------------------------------------- /Libft/src/ft_toupper.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_toupper.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/11/08 09:45:36 by handler #+# #+# */ 9 | /* Updated: 2022/11/08 12:41:56 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | int ft_toupper(int c) 14 | { 15 | if (c >= 97 && c <= 122) 16 | return (c - 32); 17 | return (c); 18 | } 19 | -------------------------------------------------------------------------------- /Libft/src/ft_isalpha.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_isalpha.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/11/08 09:45:49 by handler #+# #+# */ 9 | /* Updated: 2022/11/08 12:41:20 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | int ft_isalpha(int c) 14 | { 15 | if ((c >= 65 && c <= 90) || (c >= 97 && c <= 122)) 16 | return (1); 17 | return (0); 18 | } 19 | -------------------------------------------------------------------------------- /Libft/src/ft_lstdelone.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_lstdelone.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/11/11 15:25:21 by handler #+# #+# */ 9 | /* Updated: 2022/11/11 16:38:24 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | void ft_lstdelone(t_list *lst, void (*del)(void *)) 16 | { 17 | (*del)(lst->content); 18 | free(lst); 19 | } 20 | -------------------------------------------------------------------------------- /Libft/src/ft_lstlast.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_lstlast.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/11/10 23:31:42 by handler #+# #+# */ 9 | /* Updated: 2022/11/14 12:31:33 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | t_list *ft_lstlast(t_list *lst) 16 | { 17 | while (lst && lst->next) 18 | lst = lst->next; 19 | return (lst); 20 | } 21 | -------------------------------------------------------------------------------- /Libft/src/ft_putstr_fd.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_putstr_fd.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/11/09 23:53:37 by handler #+# #+# */ 9 | /* Updated: 2022/11/11 14:08:34 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | void ft_putstr_fd(char *s, int fd) 16 | { 17 | int i; 18 | 19 | i = -1; 20 | while (s[++i]) 21 | write(fd, &s[i], 1); 22 | } 23 | -------------------------------------------------------------------------------- /Libft/src/ft_isalnum.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_isalnum.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/11/08 09:44:43 by handler #+# #+# */ 9 | /* Updated: 2022/11/08 12:41:32 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | int ft_isalnum(int c) 16 | { 17 | if (ft_isalpha((unsigned char)c) || ft_isdigit((unsigned char)c)) 18 | return (1); 19 | return (0); 20 | } 21 | -------------------------------------------------------------------------------- /Libft/src/ft_lstadd_front.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_lstadd_front.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/11/10 23:09:20 by handler #+# #+# */ 9 | /* Updated: 2022/11/14 12:30:21 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | void ft_lstadd_front(t_list **lst, t_list *new) 16 | { 17 | if (!new || !lst) 18 | return ; 19 | new -> next = *lst; 20 | *lst = new; 21 | } 22 | -------------------------------------------------------------------------------- /Libft/src/ft_lstiter.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_lstiter.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/11/11 16:16:34 by handler #+# #+# */ 9 | /* Updated: 2022/11/11 16:38:19 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | void ft_lstiter(t_list *lst, void (*f)(void *)) 16 | { 17 | while (lst) 18 | { 19 | (*f)(lst->content); 20 | lst = lst->next; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Libft/src/ft_lstsize.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_lstsize.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/11/10 23:27:18 by handler #+# #+# */ 9 | /* Updated: 2022/11/11 14:18:08 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | int ft_lstsize(t_list *lst) 16 | { 17 | int count; 18 | 19 | count = 0; 20 | while (lst) 21 | { 22 | lst = lst->next; 23 | ++count; 24 | } 25 | return (count); 26 | } 27 | -------------------------------------------------------------------------------- /Libft/src/ft_bzero.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_bzero.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/11/08 11:54:49 by handler #+# #+# */ 9 | /* Updated: 2022/11/09 13:54:42 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | void *ft_bzero(void *s, size_t n) 16 | { 17 | unsigned char *str; 18 | 19 | str = s; 20 | while (n--) 21 | { 22 | *str = (unsigned char) '\0'; 23 | str++; 24 | } 25 | return (s); 26 | } 27 | -------------------------------------------------------------------------------- /Libft/src/ft_striteri.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_striteri.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/11/10 18:39:19 by handler #+# #+# */ 9 | /* Updated: 2022/11/11 14:16:02 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | void ft_striteri(char *s, void (*f)(unsigned int, char*)) 16 | { 17 | int i; 18 | 19 | if (!s || !f) 20 | return ; 21 | i = -1; 22 | while (s[++i]) 23 | f((unsigned int)i, &s[i]); 24 | } 25 | -------------------------------------------------------------------------------- /src/builtin/ft_pwd.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_pwd.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/05/08 11:38:03 by handler #+# #+# */ 9 | /* Updated: 2023/05/08 11:38:05 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "../../include/minishell.h" 14 | 15 | int ft_pwd(void) 16 | { 17 | char cwd[PATH_MAX]; 18 | 19 | if (getcwd(cwd, PATH_MAX)) 20 | { 21 | printf("%s\n", cwd); 22 | return (0); 23 | } 24 | else 25 | { 26 | perror("pwd"); 27 | return (1); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Libft/src/ft_putendl_fd.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_putendl_fd.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/11/09 23:55:36 by handler #+# #+# */ 9 | /* Updated: 2022/11/11 14:03:01 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | void ft_putendl_fd(char *s, int fd) 16 | { 17 | int i; 18 | 19 | i = -1; 20 | while (s[++i]) 21 | write(fd, &s[i], 1); 22 | write(fd, "\n", 1); 23 | } 24 | 25 | // int main() 26 | // { 27 | // ft_putendl_fd("truc de fou", 1); 28 | // } -------------------------------------------------------------------------------- /Libft/src/ft_lstnew.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_lstnew.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/11/10 22:30:51 by handler #+# #+# */ 9 | /* Updated: 2022/11/11 14:12:48 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | t_list *ft_lstnew(void *content) 16 | { 17 | t_list *element; 18 | 19 | element = malloc(sizeof(*element)); 20 | if (!element) 21 | return (NULL); 22 | element -> content = content; 23 | element -> next = NULL; 24 | return (element); 25 | } 26 | -------------------------------------------------------------------------------- /Libft/src/ft_lstadd_back.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_lstadd_back.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/11/10 23:36:41 by handler #+# #+# */ 9 | /* Updated: 2022/11/14 17:28:03 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | void ft_lstadd_back(t_list **lst, t_list *new) 16 | { 17 | t_list *tmp; 18 | 19 | if (lst) 20 | { 21 | if (*lst == NULL) 22 | *lst = new; 23 | else 24 | { 25 | tmp = ft_lstlast(*lst); 26 | tmp -> next = new; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Libft/src/ft_lstclear.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_lstclear.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/11/11 15:28:36 by handler #+# #+# */ 9 | /* Updated: 2022/11/14 18:28:44 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | void ft_lstclear(t_list **lst, void (*del)(void *)) 16 | { 17 | t_list *tmp; 18 | t_list *next; 19 | 20 | next = *lst; 21 | while (next) 22 | { 23 | tmp = next; 24 | next = next->next; 25 | (*del)(tmp->content); 26 | free(tmp); 27 | } 28 | *lst = NULL; 29 | } 30 | -------------------------------------------------------------------------------- /Libft/src/ft_strlen.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_strlen.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/11/07 17:28:18 by handler #+# #+# */ 9 | /* Updated: 2022/11/09 14:02:00 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | size_t ft_strlen(const char *s) 16 | { 17 | unsigned int i; 18 | 19 | i = 0; 20 | while (s && s[i]) 21 | ++i; 22 | return (i); 23 | } 24 | 25 | // #include 26 | // 27 | // void main() 28 | // { 29 | // printf("%ld\n", ft_strlen("un truc un peu long puet etre")); 30 | // } -------------------------------------------------------------------------------- /Libft/src/ft_strncmp.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_strncmp.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/08/15 11:26:41 by handler #+# #+# */ 9 | /* Updated: 2022/08/18 09:58:20 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | int ft_strncmp(const char *s1, const char *s2, size_t n) 16 | { 17 | unsigned int i; 18 | 19 | if (n == 0) 20 | return (-1); 21 | i = 0; 22 | while ((s1[i] && s2[i]) && i < n - 1) 23 | { 24 | if (s1[i] == s2[i]) 25 | i++; 26 | else 27 | break ; 28 | } 29 | return (s1[i] - s2[i]); 30 | } 31 | -------------------------------------------------------------------------------- /Libft/src/ft_putnbr_fd.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_putnbr_fd.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/11/09 23:35:23 by handler #+# #+# */ 9 | /* Updated: 2022/11/11 14:03:00 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | void ft_putnbr_fd(int n, int fd) 16 | { 17 | unsigned int x; 18 | char c; 19 | 20 | if (n < 0) 21 | { 22 | write(fd, "-", 1); 23 | x = -n; 24 | } 25 | else 26 | x = n; 27 | while (x >= 10) 28 | { 29 | ft_putnbr_fd(x / 10, fd); 30 | x %= 10; 31 | } 32 | c = x + '0'; 33 | write(fd, &c, 1); 34 | } 35 | -------------------------------------------------------------------------------- /Libft/src/ft_calloc.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_calloc.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/11/07 18:12:49 by handler #+# #+# */ 9 | /* Updated: 2022/11/09 13:54:42 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | void *ft_calloc(size_t count, size_t size) 16 | { 17 | size_t i; 18 | unsigned char *tmp; 19 | 20 | if (count != 0 && size != 0 && size > 2147483647 / count) 21 | return (NULL); 22 | i = -1; 23 | tmp = malloc(count * size); 24 | if (!tmp) 25 | return (NULL); 26 | while (++i < count * size) 27 | tmp[i] = 0; 28 | return (tmp); 29 | } 30 | -------------------------------------------------------------------------------- /src/builtin/ft_env.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_env.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: reldnah +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/04/24 15:47:27 by reldnah #+# #+# */ 9 | /* Updated: 2023/05/10 16:05:06 by reldnah ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "../../include/minishell.h" 14 | 15 | int ft_env(t_list *env) 16 | { 17 | t_list *temp; 18 | 19 | temp = env; 20 | if (!temp) 21 | return (0); 22 | if (ft_strchr(temp->str, '=')) 23 | printf("%s\n", temp->str); 24 | temp = temp->next; 25 | while (temp != env) 26 | { 27 | if (ft_strchr(temp->str, '=')) 28 | printf("%s\n", temp->str); 29 | temp = temp->next; 30 | } 31 | return (0); 32 | } 33 | -------------------------------------------------------------------------------- /Libft/src/ft_strmapi.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_strmapi.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/11/10 16:57:49 by handler #+# #+# */ 9 | /* Updated: 2022/11/11 14:17:20 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | char *ft_strmapi(char const *s, char (*f)(unsigned int, char)) 16 | { 17 | char *str; 18 | size_t i; 19 | 20 | i = 0; 21 | while (s[i]) 22 | ++i; 23 | str = malloc(sizeof(char) * (i + 1)); 24 | if (!str || !s || !f) 25 | return (NULL); 26 | i = -1; 27 | while (s[++i]) 28 | str[i] = s[i]; 29 | str[i] = '\0'; 30 | i = -1; 31 | while (str[++i]) 32 | str[i] = f(i, str[i]); 33 | return (str); 34 | } 35 | -------------------------------------------------------------------------------- /Libft/src/ft_strdup.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_strdup.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/08/22 09:49:27 by handler #+# #+# */ 9 | /* Updated: 2022/11/09 13:54:42 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | char *ft_strdup(const char *src) 16 | { 17 | char *new; 18 | int i; 19 | 20 | i = 0; 21 | while (src[i]) 22 | i++; 23 | new = malloc(sizeof(char) * (i + 1)); 24 | if (!new) 25 | return (NULL); 26 | i = -1; 27 | while (src[++i]) 28 | new[i] = src[i]; 29 | new[i] = '\0'; 30 | return (new); 31 | } 32 | 33 | // int main(void) 34 | // { 35 | // printf("%s\n", ft_strdup("une chaine de characteres.")); 36 | // return 0; 37 | // } -------------------------------------------------------------------------------- /Libft/src/ft_lstmap.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_lstmap.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/11/11 16:18:27 by handler #+# #+# */ 9 | /* Updated: 2022/11/14 18:13:19 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | t_list *ft_lstmap(t_list *lst, void *(*f)(void *), void (*del)(void *)) 16 | { 17 | t_list *new; 18 | t_list *first; 19 | 20 | if (!lst) 21 | return (NULL); 22 | first = NULL; 23 | while (lst && f && del) 24 | { 25 | new = ft_lstnew(f(lst->content)); 26 | if (!new) 27 | { 28 | ft_lstclear(&first, del); 29 | return (NULL); 30 | } 31 | ft_lstadd_back(&first, new); 32 | lst = lst -> next; 33 | } 34 | return (first); 35 | } 36 | -------------------------------------------------------------------------------- /Libft/src/ft_strjoin.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_strjoin.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/11/09 22:45:22 by handler #+# #+# */ 9 | /* Updated: 2022/11/14 16:03:56 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | char *ft_strjoin(char const *s1, char const *s2) 16 | { 17 | int i; 18 | int j; 19 | char *str; 20 | 21 | if (!s1 || !s2) 22 | return (NULL); 23 | str = malloc(sizeof(char) * (ft_strlen(s1) + ft_strlen(s2) + 1)); 24 | if (!str) 25 | return (NULL); 26 | i = -1; 27 | j = -1; 28 | while (s1[++j]) 29 | str[++i] = s1[j]; 30 | j = -1; 31 | while (s2[++j]) 32 | str[++i] = s2[j]; 33 | str[i + 1] = '\0'; 34 | return (str); 35 | } 36 | -------------------------------------------------------------------------------- /Libft/Makefile: -------------------------------------------------------------------------------- 1 | SRCS = ft_atoi ft_bzero ft_calloc ft_isalnum ft_isalpha ft_isascii \ 2 | ft_isdigit ft_isprint ft_memchr ft_memcmp ft_memmove ft_memset \ 3 | ft_strchr ft_strlen ft_strnstr ft_strrchr ft_tolower ft_toupper \ 4 | ft_memcpy ft_strdup ft_strlcat ft_strlcpy ft_strncmp ft_substr \ 5 | ft_putnbr_fd ft_strjoin ft_strtrim ft_putchar_fd ft_putnbr_fd \ 6 | ft_putstr_fd ft_putendl_fd ft_itoa ft_split ft_striteri ft_strmapi get_next_line get_next_line_utils 7 | 8 | BONUS = ft_lstnew.c ft_lstsize.c ft_lstmap.c ft_lstlast.c ft_lstiter.c ft_lstdelone.c \ 9 | ft_lstclear.c ft_lstadd_front.c ft_lstadd_back.c $(SRCS) 10 | 11 | BONUS_OBJS = ${BONUS:.c=.o} 12 | 13 | NAME = libft.a 14 | 15 | OBJ_DIR = obj/ 16 | SRC_DIR = src/ 17 | 18 | INCLUDES = -I 19 | 20 | SRC = $(addprefix $(SRC_DIR), $(addsuffix .c, $(SRCS))) 21 | OBJS = $(addprefix $(OBJ_DIR), $(addsuffix .o, $(SRCS))) 22 | 23 | CC = gcc 24 | 25 | CFLAGS = -Wall -Wextra -Werror 26 | 27 | AR = ar rc 28 | 29 | RM = rm -f 30 | 31 | OBJF = .cache_exits 32 | 33 | $(OBJF) : 34 | @mkdir -p $(OBJ_DIR) 35 | 36 | ${NAME}: ${OBJS} 37 | $(AR) ${NAME} ${OBJS} 38 | 39 | $(OBJ_DIR)%.o : $(SRC_DIR)%.c | $(OBJF) 40 | $(CC) $(CFLAGS) -c $< -o $@ 41 | 42 | all: ${NAME} 43 | 44 | clean: 45 | ${RM} ${OBJS} $(BONUS_OBJS) 46 | 47 | fclean: clean 48 | ${RM} ${NAME} 49 | 50 | bonus: ${BONUS_OBJS} 51 | ${AR} ${NAME} ${BONUS_OBJS} 52 | 53 | re: fclean all 54 | 55 | .PHONY: all clean fclean re bonus -------------------------------------------------------------------------------- /Libft/src/ft_strrchr.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_strrchr.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/11/08 10:09:19 by handler #+# #+# */ 9 | /* Updated: 2022/11/09 14:18:46 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | char *ft_strrchr(const char *string, int searchedChar) 16 | { 17 | int i; 18 | 19 | i = 0; 20 | while (string[i]) 21 | ++i; 22 | if (searchedChar == 0) 23 | return ((char *)&string[i]); 24 | while (--i >= 0) 25 | if (string[i] == (unsigned char)searchedChar) 26 | return ((char *)&string[i]); 27 | return (NULL); 28 | } 29 | 30 | // int main(void) 31 | // { 32 | // printf("%s\n", ft_strrchr("je cherche une lettre", 'e')); 33 | // printf("%s\n", strrchr("je cherche une lettre", 'e')); 34 | // return 0; 35 | // } 36 | -------------------------------------------------------------------------------- /Libft/src/ft_strchr.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_strchr.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/11/08 09:57:37 by handler #+# #+# */ 9 | /* Updated: 2022/11/09 13:54:42 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | char *ft_strchr(const char *string, int searchedChar) 16 | { 17 | int i; 18 | 19 | i = -1; 20 | while (string[++i]) 21 | if (string[i] == (unsigned char)searchedChar) 22 | return ((char *)&string[i]); 23 | if (string[i] == (unsigned char)searchedChar) 24 | return ((char *)&string[i]); 25 | return (NULL); 26 | } 27 | 28 | // void main() 29 | // { 30 | // printf("%s\n", strchr("je cherche une lettre", 'e')); 31 | // printf("%s\n", ft_strchr("je cherche une lettre", 'e')); 32 | // char *f = NULL; 33 | // printf("%d\n", (f || NULL)); 34 | // } -------------------------------------------------------------------------------- /Libft/src/ft_memmove.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_memmove.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/11/08 14:08:53 by handler #+# #+# */ 9 | /* Updated: 2022/11/09 13:54:42 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | void *ft_memmove(void *destination, const void *source, size_t size) 16 | { 17 | size_t i; 18 | unsigned char *d; 19 | unsigned char *s; 20 | 21 | d = (unsigned char *) destination; 22 | s = (unsigned char *) source; 23 | i = -1; 24 | if (d > s) 25 | while (size-- > 0) 26 | d[size] = s[size]; 27 | else 28 | while (++i < size) 29 | d[i] = s[i]; 30 | return (destination); 31 | } 32 | // 33 | // int main(void) 34 | // { 35 | // char sResult[] = {67, 68, 67, 68, 69, 0, 45}; 36 | // char *dest = ft_memmove(sResult + 1, sResult, 2); 37 | // printf("%s\n", dest); 38 | // } -------------------------------------------------------------------------------- /Libft/src/ft_strlcpy.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_strlcpy.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/08/14 12:39:46 by handler #+# #+# */ 9 | /* Updated: 2022/08/15 11:00:13 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | size_t ft_strlcpy(char *dest, char const *src, size_t size) 16 | { 17 | unsigned int i; 18 | 19 | i = 0; 20 | if (size != 0) 21 | { 22 | while (src[i] && i < (size - 1)) 23 | { 24 | dest[i] = src[i]; 25 | i++; 26 | } 27 | dest[i] = '\0'; 28 | } 29 | while (src[i]) 30 | i++; 31 | return (i); 32 | } 33 | 34 | // #include 35 | 36 | // int main() 37 | // { 38 | // char dst[] = "sjhgdfjhsdgfjhsdgfjhsgfhjsdgfjhsdgf"; 39 | // char src[] = "Bonjour je suis un super beau gosse"; 40 | // printf("%ld\n", ft_strlcpy(dst, src, 20)); 41 | // return 0; 42 | // } -------------------------------------------------------------------------------- /Libft/src/ft_atoi.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_atoi.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/11/07 11:35:43 by handler #+# #+# */ 9 | /* Updated: 2022/11/08 16:54:10 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | int ft_atoi(const char *nptr) 16 | { 17 | int nbr; 18 | int signe; 19 | int i; 20 | char *str; 21 | 22 | i = 0; 23 | str = (char *)nptr; 24 | while ((str[i] >= 9 && str[i] <= 13) || str[i] == 32) 25 | i++; 26 | signe = 1; 27 | if (str[i] == '+' || str[i] == '-') 28 | if (str[i++] == '-') 29 | signe = -signe; 30 | nbr = 0; 31 | while (str[i] >= '0' && str[i] <= '9') 32 | nbr = nbr * 10 + (str[i++] - 48); 33 | return (nbr * signe); 34 | } 35 | 36 | // #include 37 | // 38 | // int main() 39 | // { 40 | // printf("%d\n", ft_atoi("-2147483648")); 41 | // } 42 | -------------------------------------------------------------------------------- /src/utils/signals.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* signals.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: reldnah +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/04/24 14:43:55 by reldnah #+# #+# */ 9 | /* Updated: 2023/05/12 11:31:50 by reldnah ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "../../include/minishell.h" 14 | 15 | void clear_rl_line(void) 16 | { 17 | rl_replace_line("", 0); 18 | rl_on_new_line(); 19 | } 20 | 21 | static void handle_sigint(int code) 22 | { 23 | (void)code; 24 | printf("\n"); 25 | clear_rl_line(); 26 | if (g_signal_pid == 0) 27 | rl_redisplay(); 28 | } 29 | 30 | static void handle_sigsegv(int code) 31 | { 32 | (void)code; 33 | write(2, "Segmentation fault\n", 19); 34 | exit(11); 35 | } 36 | 37 | static void handle_sigabrt(int code) 38 | { 39 | (void)code; 40 | write(1, "abort\n", 6); 41 | } 42 | 43 | void signals(void) 44 | { 45 | signal(SIGINT, &handle_sigint); 46 | signal(SIGSEGV, &handle_sigsegv); 47 | signal(SIGABRT, &handle_sigabrt); 48 | signal(SIGQUIT, SIG_IGN); 49 | } 50 | -------------------------------------------------------------------------------- /Libft/src/get_next_line.h: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* get_next_line.h :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/11/23 12:11:18 by handler #+# #+# */ 9 | /* Updated: 2023/05/08 11:28:52 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #ifndef GET_NEXT_LINE_H 14 | # define GET_NEXT_LINE_H 15 | 16 | # include 17 | # include 18 | # include 19 | # include "libft.h" 20 | 21 | # ifndef BUFFER_SIZE 22 | # define BUFFER_SIZE 1 23 | # endif 24 | 25 | typedef struct s_list_gnl 26 | { 27 | char *content; 28 | struct s_list_gnl *next; 29 | struct s_list_gnl *prev; 30 | } t_list_gnl; 31 | 32 | int free_list_gnl(t_list_gnl **list); 33 | int how_many(t_list_gnl *list, char **line); 34 | int make_line(t_list_gnl *list, char **line); 35 | int new_line(t_list_gnl *list); 36 | int add_to_list_gnl(t_list_gnl **list, char *buf); 37 | int write_in_list_gnl(int fd, t_list_gnl **list); 38 | int clear_list_gnl(t_list_gnl **list); 39 | char *get_next_line(int fd); 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /src/builtin/ft_echo.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_echo.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/05/08 11:33:45 by handler #+# #+# */ 9 | /* Updated: 2023/05/08 11:34:51 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "../../include/minishell.h" 14 | 15 | static int check_new_line(char *str) 16 | { 17 | int i; 18 | 19 | i = 0; 20 | if (str[i] && str[i] == '-') 21 | { 22 | ++i; 23 | while (str[i] && str[i] == 'n') 24 | i++; 25 | if (i == (int)ft_strlen(str)) 26 | return (1); 27 | } 28 | return (0); 29 | } 30 | 31 | static void write_echo(int count, int i, bool new_line, char **args) 32 | { 33 | while (args[i] && check_new_line(args[i])) 34 | { 35 | ++i; 36 | new_line = false; 37 | } 38 | while (i < count) 39 | { 40 | write(1, args[i], ft_strlen(args[i])); 41 | if (i != count - 1) 42 | write(1, " ", 1); 43 | ++i; 44 | } 45 | if (new_line) 46 | write(1, "\n", 1); 47 | } 48 | 49 | int ft_echo(char **args) 50 | { 51 | int count; 52 | int i; 53 | bool new_line; 54 | 55 | count = 0; 56 | while (args[count]) 57 | ++count; 58 | i = 1; 59 | new_line = true; 60 | write_echo(count, i, new_line, args); 61 | return (0); 62 | } 63 | -------------------------------------------------------------------------------- /src/parsing/quote.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* quote.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/05/08 11:58:47 by handler #+# #+# */ 9 | /* Updated: 2023/05/11 22:49:07 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "../../include/minishell.h" 14 | 15 | void quoting_choice(bool *dq, bool *sq, int *index, char c) 16 | { 17 | if ((c == '\'' || c == '"') && !*sq && !*dq) 18 | { 19 | if (c == '\'' && !*dq) 20 | *sq = true; 21 | else if (c == '"' && !*sq) 22 | *dq = true; 23 | if (index) 24 | ++(*index); 25 | } 26 | else if ((c == '\'' || c == '"')) 27 | { 28 | if (c == '\'' && !*dq && *sq) 29 | *sq = false; 30 | else if (c == '"' && !*sq && *dq) 31 | *dq = false; 32 | if (index) 33 | ++(*index); 34 | } 35 | } 36 | 37 | int open_quote(t_data *data, char *line) 38 | { 39 | bool dq; 40 | bool sq; 41 | int i; 42 | 43 | i = 0; 44 | dq = false; 45 | sq = false; 46 | while (line && line[i]) 47 | { 48 | quoting_choice(&dq, &sq, &i, line[i]); 49 | if (line[i] && line[i] != '\'' && line[i] != '"') 50 | ++i; 51 | } 52 | if (dq || sq) 53 | { 54 | print_error("open quote\n"); 55 | data->exit_code = 2; 56 | return (1); 57 | } 58 | return (0); 59 | } 60 | -------------------------------------------------------------------------------- /Libft/src/ft_memcpy.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_memcpy.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/11/08 12:20:28 by handler #+# #+# */ 9 | /* Updated: 2022/11/09 13:54:42 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | void *ft_memcpy(void *destination, const void *source, size_t size) 16 | { 17 | unsigned char *d; 18 | unsigned char *s; 19 | size_t i; 20 | 21 | d = (unsigned char *)destination; 22 | s = (unsigned char *)source; 23 | i = -1; 24 | while (++i < size) 25 | d[i] = s[i]; 26 | return (destination); 27 | } 28 | // #include 29 | // #include "libft.h" 30 | // #include 31 | // 32 | // int main() { 33 | // 34 | // int array [] = { 54, 85, 20, 63, 21 }; 35 | // int * copy = NULL; 36 | // int length = sizeof( int ) * 5; 37 | // 38 | // /* Memory allocation and copy */ 39 | // copy = (int *) malloc( length ); 40 | // ft_memcpy( copy, array, length ); 41 | // 42 | // /* Display the copied values */ 43 | // for( length=0; length<5; length++ ) { 44 | // printf( "%d ", copy[ length ] ); 45 | // } 46 | // printf( "\n" ); 47 | // 48 | // free( copy ); 49 | // 50 | // return EXIT_SUCCESS; 51 | // } -------------------------------------------------------------------------------- /Libft/src/ft_itoa.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_itoa.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/11/10 11:03:24 by handler #+# #+# */ 9 | /* Updated: 2022/11/11 14:16:58 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | static int count_nbr(int nbr) 16 | { 17 | int count; 18 | unsigned int n; 19 | 20 | count = 1; 21 | if (nbr < 0) 22 | { 23 | n = -nbr; 24 | ++count; 25 | } 26 | else 27 | n = nbr; 28 | while (n >= 10) 29 | { 30 | n /= 10; 31 | ++count; 32 | } 33 | return (count); 34 | } 35 | 36 | char *ft_itoa(int n) 37 | { 38 | char *str; 39 | int i; 40 | unsigned int t; 41 | 42 | i = count_nbr(n); 43 | str = malloc(sizeof(char) * (i + 1)); 44 | if (!str) 45 | return (NULL); 46 | if (n < 0) 47 | t = -n; 48 | else 49 | t = n; 50 | str[i] = '\0'; 51 | while (--i >= 0) 52 | { 53 | str[i] = (t % 10) + 48; 54 | t /= 10; 55 | } 56 | if (n < 0) 57 | str[0] = '-'; 58 | return (str); 59 | } 60 | 61 | // int main() 62 | // { 63 | // printf("%s\n", ft_itoa(-123456789)); 64 | // printf("%s\n", ft_itoa(-2147483648)); 65 | // printf("%s\n", ft_itoa(2147483647)); 66 | // } 67 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | NAME = minishell 2 | 3 | CC = cc 4 | FLAG = -Wall -Wextra -Werror -g3 5 | 6 | DIRLIB = ./Libft/ 7 | FILELIB = libft.a 8 | NAMELFT = $(addprefix $(DIRLIB), $(FILELIB)) 9 | 10 | SRC_DIR = src/ 11 | OBJ_DIR = obj/ 12 | INCLUDE = -I ./include -I ./Libft 13 | HEADER = include/minishell.h 14 | 15 | # Color 16 | 17 | DEF_COLOR = \033[0;39m 18 | GRAY = \033[0;90m 19 | RED = \033[0;91m 20 | GREEN = \033[0;92m 21 | YELLOW = \033[0;93m 22 | BLUE = \033[0;94m 23 | MAGENTA = \033[0;95m 24 | CYAN = \033[0;96m 25 | WHITE = \033[0;97m 26 | 27 | # Source 28 | FILES = main quote dollar_env dollar_replace list_utils signals create_token \ 29 | list_token ms_utils ft_env ft_export free array_utils ft_unset ft_pwd \ 30 | ft_cd list_cmd create_cmd cmd_fd here_doc cmd_param exec launch_builtin \ 31 | ft_echo ft_exit find_cmd exec2 debug signals2 32 | 33 | SRCS = $(addprefix $(SRC_DIR), $(addsuffix .c, $(FILES))) 34 | OBJS = $(addprefix $(OBJ_DIR), $(addsuffix .o, $(FILES))) 35 | 36 | OBJF = .cache_exits 37 | 38 | $(OBJF) : 39 | @mkdir -p $(OBJ_DIR) 40 | 41 | # Add the path to the builtin folder to vpath 42 | vpath %.c $(SRC_DIR) $(SRC_DIR)builtin $(SRC_DIR)utils $(SRC_DIR)parsing $(SRC_DIR)exec 43 | 44 | all : $(NAME) 45 | 46 | $(NAME) : $(OBJS) 47 | make -C $(DIRLIB) 48 | $(CC) $(FLAG) $(OBJS) $(NAMELFT) -lreadline $(INCLUDE) -o $(NAME) 49 | @echo "$(GREEN)Minishell Compiled!$(DEF_COLOR)" 50 | 51 | $(OBJ_DIR)%.o : %.c $(HEADER) Makefile | $(OBJF) 52 | $(CC) $(FLAG) $(INCLUDE) -c $< -o $@ 53 | 54 | clean : 55 | @ make clean -sC $(DIRLIB) 56 | @rm -rf $(OBJ_DIR) 57 | @rm -rf $(OBJF) 58 | @echo "$(MAGENTA)Minishell objects cleaned !$(DEF_COLOR)" 59 | 60 | fclean : clean 61 | @ make clean -sC $(DIRLIB) 62 | @rm -rf $(NAME) 63 | @rm -rf $(NAME_B) 64 | @echo "$(YELLOW)Minishell cleaned !$(DEF_COLOR)" 65 | 66 | re : fclean all 67 | @echo "$(GREEN)Cleaned and rebuilt !$(DEF_COLOR)" 68 | 69 | .PHONY : all clean fclean re 70 | -------------------------------------------------------------------------------- /Libft/src/ft_memset.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_memset.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/11/08 10:36:44 by handler #+# #+# */ 9 | /* Updated: 2022/11/09 13:54:42 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | void *ft_memset(void *pointer, int value, size_t count) 16 | { 17 | unsigned char *str; 18 | 19 | str = pointer; 20 | while (count--) 21 | { 22 | *str = (unsigned char) value; 23 | str++; 24 | } 25 | return (pointer); 26 | } 27 | 28 | // #include 29 | // #include "libft.h" 30 | // #include 31 | 32 | // int main() { 33 | 34 | // int array [] = { 54, 85, 20, 63, 21 }; 35 | // size_t size = sizeof( int ) * 5; 36 | // int length; 37 | 38 | // /* Display the initial values */ 39 | // for( length=0; length<5; length++) { 40 | // printf( "%d ", array[ length ] ); 41 | // } 42 | // printf( "\n" ); 43 | 44 | // /* Reset the memory bloc */ 45 | // ft_memset( array, 'q', size ); 46 | 47 | // /* Display the new values */ 48 | // for( length=0; length<5; length++) { 49 | // printf( "%d ", array[ length ] ); 50 | // } 51 | // printf( "\n" ); 52 | 53 | // return 0; 54 | // } -------------------------------------------------------------------------------- /Libft/src/ft_strtrim.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_strtrim.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/11/09 22:48:42 by handler #+# #+# */ 9 | /* Updated: 2022/11/14 18:12:56 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | static int in_sep(char *str, char sep) 16 | { 17 | int i; 18 | 19 | i = -1; 20 | while (str[++i]) 21 | if (str[i] == sep) 22 | return (1); 23 | return (0); 24 | } 25 | 26 | char *ft_strtrim(char const *s1, char const *set) 27 | { 28 | int start; 29 | int end; 30 | int i; 31 | char *str; 32 | 33 | if (!s1 || !set) 34 | return (NULL); 35 | start = 0; 36 | while (s1[start] && in_sep((char *)set, s1[start])) 37 | start++; 38 | end = ft_strlen(s1) - 1; 39 | while (end && in_sep((char *)set, s1[end])) 40 | end--; 41 | i = 0; 42 | if (start > end) 43 | return (ft_strdup("")); 44 | str = malloc(sizeof(char) * (end - start + 2)); 45 | if (!str) 46 | return (NULL); 47 | while (start <= end) 48 | str[i++] = s1[start++]; 49 | str[i] = '\0'; 50 | return (str); 51 | } 52 | 53 | // int main(void) 54 | // { 55 | // char s1[] = " x x xxxx xxx x x x x x x xxxx x x"; 56 | // printf("[%s]\n", ft_strtrim(s1, " x")); 57 | // } -------------------------------------------------------------------------------- /src/exec/here_doc.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* here_doc.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/05/02 13:07:16 by reldnah #+# #+# */ 9 | /* Updated: 2023/05/11 22:49:07 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "../../include/minishell.h" 14 | 15 | static bool read_in_stdin(t_data *data, int fd, char *word) 16 | { 17 | char *buf; 18 | 19 | while (1) 20 | { 21 | buf = NULL; 22 | buf = readline("> "); 23 | if (!buf) 24 | { 25 | print_error("warning: here-document delimited by end-of-file "); 26 | print_error("(wanted '"); 27 | print_error(word); 28 | print_error("')\n"); 29 | break ; 30 | } 31 | if (!ft_strncmp(word, buf, INT_MAX)) 32 | break ; 33 | if (!replace_dollar(&buf, data)) 34 | free_all(data, ERR_MALLOC, EXT_MALLOC); 35 | write(fd, buf, ft_strlen(buf)); 36 | write(fd, "\n", 1); 37 | free(buf); 38 | } 39 | free(buf); 40 | close(fd); 41 | return (true); 42 | } 43 | 44 | int here_doc(t_data *data, char *word) 45 | { 46 | int fd; 47 | 48 | fd = open(".heredoc.tmp", O_CREAT | O_WRONLY | O_TRUNC, 0644); 49 | if (fd < 0) 50 | return (-1); 51 | if (!read_in_stdin(data, fd, word)) 52 | { 53 | unlink(".heredoc.tmp"); 54 | return (-1); 55 | } 56 | fd = open(".heredoc.tmp", O_RDONLY); 57 | if (fd > 0) 58 | unlink(".heredoc.tmp"); 59 | return (fd); 60 | } 61 | -------------------------------------------------------------------------------- /src/utils/debug.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* debug.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/05/11 22:51:03 by handler #+# #+# */ 9 | /* Updated: 2023/05/11 22:51:36 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "../../include/minishell.h" 14 | 15 | void print_token(t_token *token) 16 | { 17 | t_token *tmp; 18 | 19 | tmp = token; 20 | while (tmp->next != token) 21 | { 22 | printf("Type : %d, [%s]\n", tmp->type, tmp->str); 23 | tmp = tmp->next; 24 | } 25 | printf("Type : %d, [%s]\n", tmp->type, tmp->str); 26 | } 27 | 28 | void print_tab(char **tab) 29 | { 30 | int i; 31 | 32 | if (!(tab)) 33 | { 34 | printf("NULL"); 35 | return ; 36 | } 37 | i = 0; 38 | printf("["); 39 | while (tab[i]) 40 | { 41 | printf("%s", tab[i]); 42 | if (tab[i + 1]) 43 | printf(", "); 44 | i++; 45 | } 46 | printf("]"); 47 | } 48 | 49 | void print_cmd(t_cmd *cmd) 50 | { 51 | t_cmd *tmp; 52 | 53 | tmp = cmd; 54 | while (tmp->next != cmd) 55 | { 56 | printf("Skip -> %d, infile -> %d, outfile -> %d, cmd : ", 57 | tmp->skip_cmd, tmp->infile, tmp->outfile); 58 | print_tab(tmp->cmd_param); 59 | printf("\n"); 60 | tmp = tmp->next; 61 | } 62 | printf("Skip -> %d, infile -> %d, outfile -> %d, cmd : ", tmp->skip_cmd, 63 | tmp->infile, tmp->outfile); 64 | print_tab(tmp->cmd_param); 65 | printf("\n"); 66 | } 67 | -------------------------------------------------------------------------------- /src/utils/array_utils.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* array_utils.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/04/25 15:38:49 by reldnah #+# #+# */ 9 | /* Updated: 2023/05/11 22:49:07 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "../../include/minishell.h" 14 | 15 | //Transform lst to array 16 | char **lst_to_arr(t_list *env) 17 | { 18 | t_list *lst; 19 | char **dest; 20 | int i; 21 | 22 | dest = NULL; 23 | i = 0; 24 | lst = env; 25 | dest = (char **)malloc(sizeof(char *) * (len_list(lst) + 1)); 26 | if (!dest) 27 | return (NULL); 28 | dest[i] = (lst->str); 29 | lst = lst->next; 30 | i++; 31 | while (lst != env) 32 | { 33 | dest[i] = (lst->str); 34 | lst = lst->next; 35 | i++; 36 | } 37 | dest[i] = NULL; 38 | return (dest); 39 | } 40 | 41 | //swap to elems in array 42 | static void ft_swap_str_tab(int i, int j, char **tab) 43 | { 44 | char *temp; 45 | 46 | temp = tab[i]; 47 | tab[i] = tab[j]; 48 | tab[j] = temp; 49 | } 50 | 51 | //sorts array 52 | void sort_array(char **arr, int len) 53 | { 54 | int i; 55 | int j; 56 | int diff; 57 | 58 | i = 0; 59 | while (i < len) 60 | { 61 | j = i + 1; 62 | while (j < len) 63 | { 64 | diff = ft_strncmp(arr[i], arr[j], __INT_MAX__); 65 | if (diff > 0) 66 | { 67 | ft_swap_str_tab(i, j, arr); 68 | continue ; 69 | } 70 | j++; 71 | } 72 | i++; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Libft/src/ft_memcmp.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_memcmp.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/11/07 15:16:39 by handler #+# #+# */ 9 | /* Updated: 2022/11/09 14:18:26 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | int ft_memcmp(const void *s1, const void *s2, size_t len) 16 | { 17 | size_t pos; 18 | unsigned char *cs1; 19 | unsigned char *cs2; 20 | 21 | pos = 0; 22 | cs1 = (unsigned char *)s1; 23 | cs2 = (unsigned char *)s2; 24 | if (len == 0) 25 | return (0); 26 | while (pos < len - 1) 27 | { 28 | if (cs1[pos] != cs2[pos]) 29 | return (cs1[pos] - cs2[pos]); 30 | pos++; 31 | } 32 | return (cs1[pos] - cs2[pos]); 33 | } 34 | 35 | // int main() 36 | // { 37 | // printf("%d\n", memcmp("Hello world", "Hello ", 6)); 38 | // printf("%d\n", ft_memcmp("Hello world", "Hello ", 6)); 39 | // } 40 | 41 | // #include 42 | 43 | // int main () 44 | // { 45 | // char s[] = {-128, 0, 127, 0}; 46 | // char sCpy[] = {-128, 0, 127, 0}; 47 | // char s2[] = {0, 0, 127, 0}; 48 | // char s3[] = {0, 0, 42, 0}; 49 | // int size = sizeof( int ) * 5; 50 | 51 | // printf("ft : %d - n : %d\n", ft_memcmp(s, s2, 0), memcmp(s, s2, 0)); 52 | // printf("ft : %d - n : %d\n", ft_memcmp(s2, s, 1), memcmp(s2, s, 1)); 53 | // printf("ft : %d - n : %d\n", ft_memcmp(s2, s3, 4), memcmp(s2, s3, 4)); 54 | // } -------------------------------------------------------------------------------- /Libft/src/ft_substr.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_substr.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/11/10 18:48:56 by handler #+# #+# */ 9 | /* Updated: 2022/11/10 18:48:56 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | char *ft_substr(char const *s, unsigned int start, size_t len) 16 | { 17 | unsigned int i; 18 | unsigned int len_s; 19 | char *str; 20 | 21 | i = 0; 22 | len_s = ft_strlen(s); 23 | if (len >= len_s) 24 | len = len_s - start; 25 | if (start > len_s) 26 | { 27 | str = malloc(sizeof(char) * 1); 28 | if (!str) 29 | return (NULL); 30 | str[0] = '\0'; 31 | return (str); 32 | } 33 | str = malloc(sizeof(char) * len + 1); 34 | if (!str) 35 | return (NULL); 36 | while (start < len_s && i < len) 37 | str[i++] = (char)s[start++]; 38 | str[i] = '\0'; 39 | return (str); 40 | } 41 | 42 | // int main (void) 43 | // { 44 | // printf("1 [%s]\n", ft_substr("tripoulle",0,42000)); 45 | // printf("2 [%s]\n", ft_substr("tripoulle",1,1)); 46 | // printf("3 [%s]\n", ft_substr("tripoulle",100,1)); 47 | // printf("4 [%s]\n", ft_substr("1",42,42000)); 48 | // printf("5 [%s]\n", ft_substr("0123456789",9,10)); 49 | // printf("6 [%s]\n", ft_substr("42",0,0)); 50 | // printf("7 [%s]\n", ft_substr("BONJOUR LES HARICOTS !",8,14)); 51 | // printf("8 [%s]\n", ft_substr("test",1,2)); 52 | // } -------------------------------------------------------------------------------- /Libft/src/ft_memchr.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_memchr.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/11/07 16:32:00 by handler #+# #+# */ 9 | /* Updated: 2022/11/09 13:54:42 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | void *ft_memchr(const void *memoryBlock, int searchedChar, size_t size) 16 | { 17 | size_t pos; 18 | unsigned char *tmp; 19 | 20 | tmp = (unsigned char *)memoryBlock; 21 | pos = -1; 22 | while (++pos < size) 23 | if (tmp[pos] == (unsigned char)searchedChar) 24 | return (&(tmp[pos])); 25 | return (NULL); 26 | } 27 | 28 | // #include 29 | // #include "libft.h" 30 | // #include 31 | 32 | // int main() { 33 | 34 | // char data[] = { 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 }; 35 | // const unsigned int size = 10; 36 | 37 | // // On recherche une valeur inhéxistante : 38 | // void * found = ft_memchr( data, 57, size ); 39 | // printf( "57 is %s\n", ( found != NULL ? "found" : "not found" ) ); 40 | 41 | // // On recherche une valeur existante : 42 | // found = ft_memchr( data, 50, size ); 43 | // printf( "50 is %s\n", ( found != NULL ? "found" : "not found" ) ); 44 | // if ( found != NULL ) 45 | // { 46 | // printf( "La valeur à la position calculée est %d\n", 47 | // *((char *) found) ); 48 | // } 49 | 50 | // return EXIT_SUCCESS; 51 | // } -------------------------------------------------------------------------------- /src/utils/free.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* free.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: reldnah +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/04/25 14:27:47 by reldnah #+# #+# */ 9 | /* Updated: 2023/05/10 16:37:33 by reldnah ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "../include/minishell.h" 14 | 15 | void free_array(char **arr) 16 | { 17 | int i; 18 | 19 | i = 0; 20 | while (arr && arr[i]) 21 | free(arr[i++]); 22 | if (arr) 23 | free(arr); 24 | arr = NULL; 25 | } 26 | 27 | bool print_error(char *str) 28 | { 29 | if (str) 30 | write(2, str, ft_strlen(str)); 31 | return (true); 32 | } 33 | 34 | bool print_error_token(t_token *token, t_data *data) 35 | { 36 | write(2, "syntax error near unexpected token ", 35); 37 | write(2, "'", 1); 38 | if (token->next == data->token) 39 | write(2, "newline", 7); 40 | else 41 | write(2, token->next->str, ft_strlen(token->next->str)); 42 | write(2, "'\n", 2); 43 | return (false); 44 | } 45 | 46 | void free_all(t_data *data, char *err, int ext) 47 | { 48 | if (data->cmd) 49 | free_cmd(&data->cmd); 50 | if (data->token) 51 | free_token(&data->token); 52 | if (data->env) 53 | free_list(&data->env); 54 | if (data->pip[0] && data->pip[0] != -1) 55 | close(data->pip[0]); 56 | if (data->pip[1] && data->pip[1] != -1) 57 | close(data->pip[1]); 58 | if (err) 59 | print_error(err); 60 | rl_clear_history(); 61 | if (!access(".heredoc.tmp", F_OK)) 62 | unlink(".heredoc.tmp"); 63 | if (ext != -1) 64 | exit(ext); 65 | } 66 | -------------------------------------------------------------------------------- /src/utils/list_token.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* list_token.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/04/19 15:53:33 by reldnah #+# #+# */ 9 | /* Updated: 2023/05/11 22:49:07 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "../../include/minishell.h" 14 | 15 | static int token_new_elem(t_token **new, char *str, int type) 16 | { 17 | if (!str) 18 | return (0); 19 | (*new) = malloc(sizeof(t_token)); 20 | if (*new == NULL) 21 | { 22 | free(str); 23 | return (0); 24 | } 25 | (*new)->str = str; 26 | (*new)->type = type; 27 | (*new)->next = NULL; 28 | (*new)->prev = NULL; 29 | return (1); 30 | } 31 | 32 | static void add_first(t_token **list, t_token *new) 33 | { 34 | (*list) = new; 35 | (*list)->prev = *list; 36 | (*list)->next = *list; 37 | } 38 | 39 | int append_token(t_token **list, char *str, int type) 40 | { 41 | t_token *new; 42 | 43 | if (!token_new_elem(&new, str, type)) 44 | return (0); 45 | if (!(*list)) 46 | add_first(list, new); 47 | else 48 | { 49 | new->prev = (*list)->prev; 50 | new->next = (*list); 51 | (*list)->prev->next = new; 52 | (*list)->prev = new; 53 | } 54 | return (1); 55 | } 56 | 57 | void free_token(t_token **list) 58 | { 59 | t_token *tmp; 60 | t_token *current; 61 | 62 | if (!(*list)) 63 | return ; 64 | current = *list; 65 | while (current->next != *list) 66 | { 67 | tmp = current; 68 | current = current->next; 69 | free(tmp->str); 70 | free(tmp); 71 | } 72 | free(current->str); 73 | free(current); 74 | *list = NULL; 75 | } 76 | -------------------------------------------------------------------------------- /src/builtin/ft_exit.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_exit.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: reldnah +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/05/03 14:25:07 by reldnah #+# #+# */ 9 | /* Updated: 2023/05/11 11:26:59 by reldnah ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "../include/minishell.h" 14 | 15 | static int almost_atoi(char *str, int *err) 16 | { 17 | unsigned long long ret; 18 | int i; 19 | int j; 20 | int pn; 21 | 22 | i = 0; 23 | while ((9 <= str[i] && str[i] <= 13) || str[i] == 32) 24 | i++; 25 | pn = 1; 26 | if (str[i] == '+' || str[i] == '-') 27 | if (str[i++] == '-') 28 | pn = -1; 29 | j = i; 30 | ret = 0; 31 | while ('0' <= str[i] && str[i] <= '9') 32 | ret = ret * 10 + (str[i++] - 48); 33 | while ((9 <= str[i] && str[i] <= 13) || str[i] == 32) 34 | i++; 35 | if (str[i] || i - j > 20 || ((pn == -1 && (ret - 1) > LONG_MAX) || \ 36 | (pn == 1 && (ret > LONG_MAX)))) 37 | *err = 1; 38 | return ((int)((ret * pn) % 256)); 39 | } 40 | 41 | void ft_exit(t_data *data, char **args) 42 | { 43 | int ret; 44 | int err; 45 | 46 | ret = 0; 47 | err = 0; 48 | if (args[1]) 49 | { 50 | ret = almost_atoi(args[1], &err); 51 | if (err) 52 | { 53 | print_error("exit: "); 54 | print_error(args[1]); 55 | print_error(": numeric argument required\n"); 56 | free_all(data, NULL, 2); 57 | } 58 | } 59 | if (args[1] && args[2]) 60 | { 61 | print_error("exit: too many arguments\n"); 62 | data->exit_code = 1; 63 | return ; 64 | } 65 | if (!args[1]) 66 | free_all(data, NULL, data->exit_code); 67 | free_all(data, NULL, ret); 68 | } 69 | -------------------------------------------------------------------------------- /Libft/src/ft_strlcat.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_strlcat.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/08/15 18:30:56 by handler #+# #+# */ 9 | /* Updated: 2022/11/09 14:45:47 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | // #include "libft.h" 14 | // #include 15 | // #include 16 | #include "libft.h" 17 | 18 | // size_t ftt_strlen(const char *s) 19 | // { 20 | // unsigned int i; 21 | 22 | // i = 0; 23 | // while (s[i]) 24 | // ++i; 25 | // return (i); 26 | // } 27 | 28 | size_t ft_strlcat(char *dest, const char *src, size_t size) 29 | { 30 | size_t i; 31 | size_t j; 32 | size_t dest_len; 33 | size_t src_len; 34 | 35 | i = 0; 36 | dest_len = ft_strlen(dest); 37 | src_len = ft_strlen(src); 38 | j = dest_len; 39 | if (dest_len < size - 1 && size > 0) 40 | { 41 | while (src[i] && dest_len + i < size - 1) 42 | dest[j++] = src[i++]; 43 | dest[j] = '\0'; 44 | } 45 | if (dest_len > size) 46 | dest_len = size; 47 | return (dest_len + src_len); 48 | } 49 | 50 | // int main(int argc, char **argv) 51 | // { 52 | // int truc = atoi(argv[1]); 53 | // // char un[] = "une chaine "; 54 | // char un[] = "01234"; 55 | // // char deux[] = "une deuxieme"; 56 | // char deux[] = "56789"; 57 | // printf("Fonction de base : %ld - %s\n", 58 | // strlcat(un, deux, truc), un); 59 | // // char un2[] = "une chaine "; 60 | // char un2[] = "01234"; 61 | // // char deux2[] = "une deuxieme"; 62 | // char deux2[] = "56789"; 63 | // printf("Fonction recodé avec le fion : %ld - %s\n", 64 | // ft_strlcat(un2, deux2, truc), un2); 65 | // } -------------------------------------------------------------------------------- /src/exec/launch_builtin.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* launch_builtin.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/05/02 14:00:25 by reldnah #+# #+# */ 9 | /* Updated: 2023/05/11 22:49:07 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "../../include/minishell.h" 14 | 15 | static void exec_builtin(int save_stdout, t_data *data, t_cmd *cmd) 16 | { 17 | if (!ft_strncmp("echo", cmd->cmd_param[0], INT_MAX)) 18 | data->exit_code = ft_echo(cmd->cmd_param); 19 | else if (!ft_strncmp("cd", cmd->cmd_param[0], INT_MAX)) 20 | data->exit_code = ft_cd(data, cmd->cmd_param); 21 | else if (!ft_strncmp("pwd", cmd->cmd_param[0], INT_MAX)) 22 | data->exit_code = ft_pwd(); 23 | else if (!ft_strncmp("export", cmd->cmd_param[0], INT_MAX)) 24 | data->exit_code = ft_export(cmd->cmd_param, &data->env); 25 | else if (!ft_strncmp("unset", cmd->cmd_param[0], INT_MAX)) 26 | data->exit_code = ft_unset(cmd->cmd_param, &data->env); 27 | else if (!ft_strncmp("env", cmd->cmd_param[0], INT_MAX)) 28 | data->exit_code = ft_env(data->env); 29 | else if (!ft_strncmp("exit", cmd->cmd_param[0], INT_MAX)) 30 | { 31 | if (cmd->outfile >= 0) 32 | { 33 | dup2(save_stdout, 1); 34 | close(save_stdout); 35 | } 36 | ft_exit(data, cmd->cmd_param); 37 | } 38 | } 39 | 40 | bool launch_builtin(t_data *data, t_cmd *cmd) 41 | { 42 | int save_stdout; 43 | 44 | save_stdout = -1; 45 | if (cmd->outfile >= 0) 46 | { 47 | save_stdout = dup(1); 48 | dup2(cmd->outfile, 1); 49 | } 50 | exec_builtin(save_stdout, data, cmd); 51 | if (cmd->outfile >= 0) 52 | { 53 | dup2(save_stdout, 1); 54 | close (save_stdout); 55 | } 56 | return (true); 57 | } 58 | -------------------------------------------------------------------------------- /src/utils/list_utils.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* list_utils.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: reldnah +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/05/08 11:43:41 by handler #+# #+# */ 9 | /* Updated: 2023/05/10 11:42:46 by reldnah ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "../../include/minishell.h" 14 | 15 | int free_list(t_list **list) 16 | { 17 | t_list *tmp; 18 | t_list *current; 19 | 20 | if (!(*list)) 21 | return (0); 22 | current = *list; 23 | while (current->next != *list) 24 | { 25 | tmp = current; 26 | current = current->next; 27 | free(tmp->str); 28 | free(tmp); 29 | } 30 | free(current->str); 31 | free(current); 32 | *list = NULL; 33 | return (0); 34 | } 35 | 36 | static int list_new_elem_str(t_list **new, char *elem) 37 | { 38 | (*new) = malloc(sizeof(t_list)); 39 | if (*new == NULL) 40 | return (0); 41 | (*new)->str = elem; 42 | (*new)->next = NULL; 43 | (*new)->prev = NULL; 44 | return (1); 45 | } 46 | 47 | static void add_first(t_list **list, t_list *new) 48 | { 49 | (*list) = new; 50 | (*list)->prev = *list; 51 | (*list)->next = *list; 52 | } 53 | 54 | size_t len_list(t_list *list) 55 | { 56 | t_list *tmp; 57 | size_t i; 58 | 59 | if ((list)) 60 | { 61 | tmp = list; 62 | i = 1; 63 | while (tmp->next != list) 64 | { 65 | ++i; 66 | tmp = tmp->next; 67 | } 68 | return (i); 69 | } 70 | return (0); 71 | } 72 | 73 | int append(t_list **list, char *elem) 74 | { 75 | t_list *new; 76 | 77 | if (!list_new_elem_str(&new, elem)) 78 | return (0); 79 | if (!(*list)) 80 | add_first(list, new); 81 | else 82 | { 83 | new->prev = (*list)->prev; 84 | new->next = (*list); 85 | (*list)->prev->next = new; 86 | (*list)->prev = new; 87 | } 88 | return (1); 89 | } 90 | -------------------------------------------------------------------------------- /src/parsing/create_cmd.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* create_cmd.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/04/26 14:40:06 by reldnah #+# #+# */ 9 | /* Updated: 2023/05/11 22:49:07 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "../../include/minishell.h" 14 | 15 | static bool fill_cmd(t_data *data, t_token *tmp) 16 | { 17 | if (!get_infile(data, tmp, data->cmd->prev) && \ 18 | data->cmd->prev->infile != -1) 19 | return (false); 20 | if (data->cmd->prev->infile == -1) 21 | { 22 | data->cmd->prev->skip_cmd = true; 23 | data->cmd->prev->outfile = -1; 24 | return (true); 25 | } 26 | if (!get_outfile(tmp, data->cmd->prev, data) && data->cmd->prev->outfile \ 27 | != -1) 28 | return (false); 29 | if (data->cmd->prev->outfile == -1) 30 | { 31 | if (data->cmd->prev->infile >= 0) 32 | close (data->cmd->prev->infile); 33 | data->cmd->prev->skip_cmd = true; 34 | data->cmd->prev->infile = -1; 35 | return (true); 36 | } 37 | data->cmd->prev->cmd_param = get_param(data, tmp); 38 | if (!data->cmd->prev->cmd_param) 39 | free_all(data, ERR_MALLOC, EXT_MALLOC); 40 | return (true); 41 | } 42 | 43 | static bool norm(t_data *data, t_token *tmp) 44 | { 45 | if (!append_cmd(&data->cmd, -2, -2, NULL)) 46 | free_all(data, ERR_MALLOC, EXT_MALLOC); 47 | if (!fill_cmd(data, tmp)) 48 | { 49 | data->exit_code = 2; 50 | return (false); 51 | } 52 | return (true); 53 | } 54 | 55 | bool create_list_cmd(t_data *data) 56 | { 57 | t_token *tmp; 58 | 59 | tmp = data->token; 60 | if (!norm(data, tmp)) 61 | return (false); 62 | tmp = tmp->next; 63 | while (tmp != data->token) 64 | { 65 | if (tmp->prev->type == PIPE) 66 | { 67 | if (!norm(data, tmp)) 68 | return (false); 69 | } 70 | tmp = tmp->next; 71 | } 72 | return (true); 73 | } 74 | -------------------------------------------------------------------------------- /src/builtin/ft_cd.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_cd.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: reldnah +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/05/08 11:38:32 by handler #+# #+# */ 9 | /* Updated: 2023/05/10 13:25:14 by reldnah ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "../../include/minishell.h" 14 | 15 | static int count_arg(char **params) 16 | { 17 | int count; 18 | 19 | count = 0; 20 | while (params[count]) 21 | count++; 22 | return (count); 23 | } 24 | 25 | static void error_malloc(void) 26 | { 27 | print_error(ERR_MALLOC); 28 | return ; 29 | } 30 | 31 | static void update_oldpwd(t_data *data) 32 | { 33 | t_list *tmp; 34 | char *test; 35 | int len; 36 | 37 | tmp = data->env; 38 | test = NULL; 39 | len = len_list(tmp); 40 | while (len--) 41 | { 42 | if (ft_strncmp(tmp->str, "PWD=", 3) == 0) 43 | test = tmp->str; 44 | tmp = tmp->next; 45 | } 46 | if (!test) 47 | export("OLDPWD", &data->env); 48 | if (test) 49 | { 50 | test = ft_strjoin("OLD", test); 51 | if (!test) 52 | return (error_malloc()); 53 | export(test, &data->env); 54 | } 55 | free(test); 56 | } 57 | 58 | static void update_pwd(t_data *data, char *param) 59 | { 60 | char cwd[PATH_MAX]; 61 | char *pwd; 62 | 63 | update_oldpwd(data); 64 | if (getcwd(cwd, PATH_MAX) == NULL) 65 | { 66 | perror(param); 67 | return ; 68 | } 69 | pwd = ft_strjoin("PWD=", cwd); 70 | if (!pwd) 71 | return (error_malloc()); 72 | export(pwd, &data->env); 73 | free(pwd); 74 | } 75 | 76 | int ft_cd(t_data *data, char **params) 77 | { 78 | int res; 79 | 80 | if (count_arg(params) == 2) 81 | { 82 | res = chdir(params[1]); 83 | if (res == 0) 84 | update_pwd(data, params[1]); 85 | if (res == -1) 86 | res *= -1; 87 | if (res == 1) 88 | perror(params[1]); 89 | return (res); 90 | } 91 | return (1); 92 | } 93 | -------------------------------------------------------------------------------- /src/exec/find_cmd.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* find_cmd.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/05/05 17:29:58 by handler #+# #+# */ 9 | /* Updated: 2023/05/11 22:49:07 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "../../include/minishell.h" 14 | 15 | int ft_strslashjoin(char *dest, char *str, char *env, int *index) 16 | { 17 | int i; 18 | int j; 19 | 20 | i = 0; 21 | while (*index < (PATH_MAX - 1) && env[(*index)] && env[(*index)] != ':') 22 | dest[i++] = env[(*index)++]; 23 | ++(*index); 24 | dest[i++] = '/'; 25 | j = 0; 26 | while (j < (PATH_MAX - 1) && str[j]) 27 | dest[i++] = str[j++]; 28 | dest[i] = '\0'; 29 | return (0); 30 | } 31 | 32 | static char *create_paths(t_list *env, int len) 33 | { 34 | t_list *tmp; 35 | 36 | tmp = env; 37 | while (len--) 38 | { 39 | if (ft_strncmp(tmp->str, "PATH=", 5) == 0) 40 | return (&(tmp->str[5])); 41 | tmp = tmp->next; 42 | } 43 | return (NULL); 44 | } 45 | 46 | static char *cmd_not_found(char *sample) 47 | { 48 | write(2, sample, ft_strlen(sample)); 49 | write(2, " : command not found\n", 21); 50 | return (NULL); 51 | } 52 | 53 | char *find_cmd(t_data *data, char *sample, t_list *env) 54 | { 55 | char *paths; 56 | char path[PATH_MAX]; 57 | int i; 58 | int len; 59 | 60 | paths = create_paths(env, len_list(env)); 61 | if (!paths || ft_strlen(sample) > PATH_MAX / 2) 62 | return (cmd_not_found(sample)); 63 | i = 0; 64 | len = ft_strlen(paths); 65 | while (i < len) 66 | { 67 | ft_strslashjoin(path, sample, paths, &i); 68 | if (access(path, F_OK) == 0) 69 | { 70 | sample = ft_strdup(path); 71 | if (!sample) 72 | { 73 | print_error(ERR_MALLOC); 74 | data->exit_code = -1; 75 | } 76 | return (sample); 77 | } 78 | } 79 | return (cmd_not_found(sample)); 80 | } 81 | -------------------------------------------------------------------------------- /src/utils/ms_utils.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ms_utils.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: reldnah +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/04/24 15:44:21 by reldnah #+# #+# */ 9 | /* Updated: 2023/05/10 14:36:44 by reldnah ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "../../include/minishell.h" 14 | 15 | bool is_space(char c) 16 | { 17 | if (c && (c == ' ' || c == '\n' || c == '\r' || c == '\f' || c == '\t' \ 18 | || c == '\v')) 19 | return (true); 20 | return (false); 21 | } 22 | 23 | int is_special(char *str) 24 | { 25 | if (str && *str && ft_strlen(str) >= 2) 26 | { 27 | if (!ft_strncmp(str, "<<", 2)) 28 | return (HEREDOC); 29 | if (!ft_strncmp(str, ">>", 2)) 30 | return (APPEND); 31 | } 32 | if (*str && ft_strlen(str) >= 1) 33 | { 34 | if (!ft_strncmp(str, "<", 1)) 35 | return (INPUT); 36 | if (!ft_strncmp(str, ">", 1)) 37 | return (TRUNC); 38 | if (!ft_strncmp(str, "|", 1)) 39 | return (PIPE); 40 | } 41 | return (0); 42 | } 43 | 44 | bool check_pipe(t_data *data) 45 | { 46 | if (data->token->type == PIPE) 47 | { 48 | write(2, "syntax error near unexpected token '|'\n", 39); 49 | free_token(&data->token); 50 | free_cmd(&data->cmd); 51 | return (false); 52 | } 53 | return (true); 54 | } 55 | 56 | bool make_env2(t_data *data) 57 | { 58 | char path[PATH_MAX]; 59 | char *tmp; 60 | 61 | tmp = ft_strdup("OLDPWD"); 62 | if (!tmp || !append(&(data->env), tmp) || getcwd(path, PATH_MAX) == NULL) 63 | free_all(data, ERR_MALLOC, EXT_MALLOC); 64 | tmp = ft_strjoin("PWD=", path); 65 | if (!tmp || !append(&(data->env), tmp)) 66 | free_all(data, ERR_MALLOC, EXT_MALLOC); 67 | return (1); 68 | } 69 | 70 | void absolute_path(char **path, char *cmd, t_data *data) 71 | { 72 | *path = ft_strdup(cmd); 73 | if (!(*path)) 74 | free_all(data, ERR_MALLOC, EXT_MALLOC); 75 | if (access((*path), F_OK)) 76 | { 77 | write(2, (*path), ft_strlen((*path))); 78 | write(2, " : command not found\n", 21); 79 | free(*path); 80 | *path = NULL; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/parsing/cmd_param.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* cmd_param.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/05/02 13:09:22 by reldnah #+# #+# */ 9 | /* Updated: 2023/05/11 22:49:07 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "../../include/minishell.h" 14 | 15 | static int count_args(t_data *data, t_token *token) 16 | { 17 | int count; 18 | t_token *tmp; 19 | 20 | count = 0; 21 | tmp = token; 22 | if (tmp->type == CMD || (tmp->type == ARG && \ 23 | tmp->prev != data->token->prev && tmp->prev->type > 5)) 24 | count ++; 25 | tmp = tmp->next; 26 | while (tmp != data->token && tmp->type != PIPE) 27 | { 28 | if (tmp->type == CMD || (tmp->type == ARG && \ 29 | tmp->prev != data->token->prev && tmp->prev->type > 5)) 30 | count ++; 31 | tmp = tmp->next; 32 | } 33 | return (count); 34 | } 35 | 36 | static int add_to_cmd_param(char **cmd_param, int *i, char *str) 37 | { 38 | cmd_param[*i] = ft_strdup(str); 39 | if (!cmd_param[*i]) 40 | return (0); 41 | (*i)++; 42 | return (1); 43 | } 44 | 45 | static void *free_cmd_param(char **cmd, int i) 46 | { 47 | while (--i != -1) 48 | free(cmd[i]); 49 | free(cmd); 50 | return (NULL); 51 | } 52 | 53 | char **get_param(t_data *data, t_token *token) 54 | { 55 | char **cmd_param; 56 | int i; 57 | t_token *tmp; 58 | 59 | i = 0; 60 | cmd_param = malloc(sizeof(char *) * (count_args(data, token) + 1)); 61 | if (cmd_param == NULL) 62 | return (NULL); 63 | tmp = token; 64 | if (tmp->type != PIPE && (tmp->type == CMD || (tmp->type == ARG && \ 65 | tmp->prev != data->token->prev && tmp->prev->type > 5)) && \ 66 | !add_to_cmd_param(cmd_param, &i, tmp->str)) 67 | return (free_cmd_param(cmd_param, i)); 68 | tmp = tmp->next; 69 | while (tmp != data->token && tmp->type != PIPE) 70 | { 71 | if ((tmp->type == CMD || (tmp->type == ARG && \ 72 | tmp->prev != data->token->prev && tmp->prev->type > 5)) && \ 73 | !add_to_cmd_param(cmd_param, &i, tmp->str)) 74 | return (free_cmd_param(cmd_param, i)); 75 | tmp = tmp->next; 76 | } 77 | cmd_param[i] = NULL; 78 | return (cmd_param); 79 | } 80 | -------------------------------------------------------------------------------- /src/utils/list_cmd.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* list_cmd.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/04/26 13:57:39 by reldnah #+# #+# */ 9 | /* Updated: 2023/05/11 22:49:07 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "../../include/minishell.h" 14 | 15 | static int cmd_new_elem(t_cmd **new, int infile, int outfile, char **cmd_param) 16 | { 17 | (*new) = malloc(sizeof(t_cmd)); 18 | if (*new == NULL) 19 | return (0); 20 | (*new)->skip_cmd = false; 21 | (*new)->infile = infile; 22 | (*new)->outfile = outfile; 23 | (*new)->cmd_param = cmd_param; 24 | (*new)->next = NULL; 25 | (*new)->prev = NULL; 26 | return (1); 27 | } 28 | 29 | int append_cmd(t_cmd **list, int infile, int outfile, char **cmd_param) 30 | { 31 | t_cmd *new; 32 | 33 | if (!cmd_new_elem(&new, infile, outfile, cmd_param)) 34 | return (0); 35 | if (!(*list)) 36 | { 37 | (*list) = new; 38 | (*list)->prev = *list; 39 | (*list)->next = *list; 40 | } 41 | else 42 | { 43 | new->prev = (*list)->prev; 44 | new->next = (*list); 45 | (*list)->prev->next = new; 46 | (*list)->prev = new; 47 | } 48 | return (1); 49 | } 50 | 51 | static void free_all_cmd(t_cmd *tmp) 52 | { 53 | if (tmp->infile > 0) 54 | close(tmp->infile); 55 | tmp->infile = -2; 56 | if (tmp->outfile > 0) 57 | close(tmp->outfile); 58 | tmp->outfile = -2; 59 | free_array(tmp->cmd_param); 60 | } 61 | 62 | void free_cmd(t_cmd **list) 63 | { 64 | t_cmd *tmp; 65 | t_cmd *current; 66 | 67 | if (!(*list)) 68 | return ; 69 | current = *list; 70 | while (current->next != *list) 71 | { 72 | tmp = current; 73 | current = current->next; 74 | free_all_cmd(tmp); 75 | free(tmp); 76 | } 77 | free_all_cmd(current); 78 | free(current); 79 | *list = NULL; 80 | } 81 | 82 | size_t len_cmd(t_cmd *list) 83 | { 84 | t_cmd *tmp; 85 | size_t i; 86 | 87 | if ((list)) 88 | { 89 | tmp = list; 90 | i = 1; 91 | while (tmp->next != list) 92 | { 93 | ++i; 94 | tmp = tmp->next; 95 | } 96 | return (i); 97 | } 98 | return (0); 99 | } 100 | -------------------------------------------------------------------------------- /Libft/src/ft_strnstr.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_strnstr.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/11/07 14:09:55 by handler #+# #+# */ 9 | /* Updated: 2022/11/09 14:33:14 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | static int ft_search(char *big, int index, char *little, size_t len) 16 | { 17 | size_t i; 18 | 19 | i = 0; 20 | while (big[i + index] == little[i] && big[i + index] && (i + index) < len) 21 | i++; 22 | if (little[i]) 23 | return (0); 24 | return (1); 25 | } 26 | 27 | char *ft_strnstr(const char *big, const char *little, size_t len) 28 | { 29 | size_t i; 30 | 31 | i = 0; 32 | if (little[0] == 0) 33 | return ((char *)big); 34 | while (i < len && (unsigned char)big[i]) 35 | { 36 | if (ft_search((char *)big, i, (char *)little, len)) 37 | return ((char *)big + i); 38 | i++; 39 | } 40 | return (0); 41 | } 42 | 43 | // int main(void) 44 | // { 45 | // printf("%s\n", ft_strnstr("Foo Bar Baz", "Bar", 10)); 46 | // printf("%s\n", strnstr("Foo Bar Baz", "Bar", 10)); 47 | // // printf("%s\n", strstr("Foo Bar Baz", "Bar")); 48 | // } 49 | 50 | // int main(void) 51 | // { 52 | // char haystack[30] = "aaabcabcd"; 53 | // char needle[10] = "aabc"; 54 | // char * empty = (char*)""; 55 | // char c = 0; 56 | // printf("%c\n", c); 57 | // printf("%s\n", ft_strnstr(haystack, needle, 0)); 58 | // printf("%s\n", ft_strnstr(haystack, needle, -1)); 59 | // printf("%s\n", ft_strnstr(haystack, "a", -1)); 60 | // printf("%s\n", ft_strnstr(haystack, "c", -1)); 61 | // printf("%s\n", ft_strnstr(empty, "", -1)); 62 | // printf("%s\n", ft_strnstr(empty, "", 0)); 63 | // printf("%s\n", ft_strnstr(empty, "coucou", -1)); 64 | // printf("%s\n", ft_strnstr(haystack, "aaabc", 5)); 65 | // printf("%s\n", ft_strnstr(empty, "12345", 5)); 66 | // printf("%s\n", ft_strnstr(haystack, "abcd", 9)); 67 | // printf("%s\n", ft_strnstr(haystack, "cd", 8)); 68 | // printf("%s\n", ft_strnstr(haystack, "a", 1)); 69 | // printf("%s\n", ft_strnstr("1", "a", 1)); 70 | // printf("%s\n", ft_strnstr("22", "b", 2)); 71 | // return (0); 72 | // } -------------------------------------------------------------------------------- /src/parsing/dollar_env.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* dollar_env.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/05/08 11:52:38 by handler #+# #+# */ 9 | /* Updated: 2023/05/11 22:49:07 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "../../include/minishell.h" 14 | 15 | static int ft_search(char *str, char c) 16 | { 17 | int i; 18 | 19 | i = -1; 20 | while (str[++i]) 21 | if (str[i] == c) 22 | return (i); 23 | return (0); 24 | } 25 | 26 | static int end_word(char *str, char *env) 27 | { 28 | int i; 29 | 30 | i = 0; 31 | while (str[i] && (ft_isalnum(str[i]) || str[i] == '_')) 32 | ++i; 33 | if (i == ft_search(env, '=')) 34 | return (i); 35 | return (0); 36 | } 37 | 38 | /* return 1 si $VAR dans env sinon 0 */ 39 | int exist_in_env(char *line, int *i, t_data *data) 40 | { 41 | t_list *tmp; 42 | int len; 43 | 44 | if (line[*i + 1] == '?' || line[*i + 1] == '$') 45 | return (2); 46 | tmp = data->env; 47 | len = len_list(tmp); 48 | while (len--) 49 | { 50 | if (ft_strncmp(tmp->str, &line[*i + 1], \ 51 | end_word(&line[*i + 1], tmp->str)) == 0) 52 | { 53 | *i += ft_strlen(tmp->str) - \ 54 | ft_strlen(ft_strchr(tmp->str, '=')) + 1; 55 | return (1); 56 | } 57 | tmp = tmp->next; 58 | } 59 | return (0); 60 | } 61 | 62 | char *get_elem_env(t_list *env, char *key) 63 | { 64 | t_list *tmp; 65 | int len; 66 | int t; 67 | 68 | if (!key) 69 | return (NULL); 70 | tmp = env; 71 | len = len_list(tmp); 72 | t = ft_strlen(key); 73 | while (len--) 74 | { 75 | if (ft_strncmp(tmp->str, key, t) == 0) 76 | { 77 | len = 0; 78 | while (tmp->str[len]) 79 | if (tmp->str[len++] == '=') 80 | break ; 81 | return (ft_strdup(&(tmp->str[len]))); 82 | } 83 | tmp = tmp->next; 84 | } 85 | return (NULL); 86 | } 87 | 88 | char *get_dollar_word(char *line, int size) 89 | { 90 | char *dollar; 91 | int i; 92 | 93 | dollar = malloc(sizeof(char) * size); 94 | if (!dollar) 95 | return (NULL); 96 | i = 0; 97 | while (line[++i] && i < size) 98 | dollar[i - 1] = line[i]; 99 | dollar[i - 1] = '\0'; 100 | return (dollar); 101 | } 102 | -------------------------------------------------------------------------------- /Libft/src/ft_split.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_split.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/11/10 09:30:27 by handler #+# #+# */ 9 | /* Updated: 2023/01/16 15:31:24 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | static int count_word(char *s, char c) 16 | { 17 | int i; 18 | int count; 19 | 20 | i = 0; 21 | count = 0; 22 | while (s[i]) 23 | { 24 | while (s[i] == c) 25 | i++; 26 | if (s[i]) 27 | count++; 28 | while (s[i] && s[i] != c) 29 | i++; 30 | } 31 | return (count); 32 | } 33 | 34 | static char **free_maloc(char **tab, int i) 35 | { 36 | while (tab[i] != NULL && i >= 0) 37 | { 38 | free(tab[i]); 39 | i--; 40 | } 41 | free(tab); 42 | return (NULL); 43 | } 44 | 45 | static char *between(char *str, char c, int index) 46 | { 47 | char *word; 48 | int start; 49 | int j; 50 | int tmp; 51 | 52 | start = index; 53 | tmp = ft_strlen(str); 54 | while (str[index] != c && index < tmp) 55 | index++; 56 | if (index == start) 57 | return (NULL); 58 | word = malloc(sizeof(char) * (index - start + 1)); 59 | if (!word) 60 | return (NULL); 61 | j = 0; 62 | while (start < index) 63 | { 64 | word[j] = str[start]; 65 | j++; 66 | start++; 67 | } 68 | word[j] = '\0'; 69 | return (word); 70 | } 71 | 72 | static char **make(char **res, char *s, char c, int len) 73 | { 74 | int i; 75 | int j; 76 | 77 | i = 0; 78 | j = 0; 79 | while (s[i] && j <= len) 80 | { 81 | while (s[i] == c) 82 | i++; 83 | if (s[i]) 84 | { 85 | res[j] = between(s, c, i); 86 | if (!res[j]) 87 | return (free_maloc(res, j)); 88 | j++; 89 | } 90 | while (s[i] != c && s[i]) 91 | i++; 92 | } 93 | res[j] = 0; 94 | return (res); 95 | } 96 | 97 | char **ft_split(char const *s, char c) 98 | { 99 | char **res; 100 | int len; 101 | 102 | len = count_word((char *)s, c); 103 | res = malloc(sizeof(char *) * (len + 1)); 104 | if (!res) 105 | return (NULL); 106 | res = make(res, (char *)s, c, len); 107 | return (res); 108 | } 109 | -------------------------------------------------------------------------------- /Libft/src/libft.h: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* libft.h :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/11/09 10:44:09 by handler #+# #+# */ 9 | /* Updated: 2022/11/09 14:17:52 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #ifndef LIBFT_H 14 | # define LIBFT_H 15 | 16 | # include 17 | // # include 18 | # include 19 | # include 20 | // # include "get_next_line.h" 21 | 22 | int ft_atoi(const char *nptr); 23 | void *ft_bzero(void *s, size_t n); 24 | void *ft_calloc(size_t nmemb, size_t size); 25 | int ft_isalnum(int c); 26 | int ft_isalpha(int c); 27 | int ft_isascii(int c); 28 | int ft_isdigit(int c); 29 | int ft_isprint(int c); 30 | char *ft_itoa(int n); 31 | void *ft_memchr(const void *s, int c, size_t n); 32 | int ft_memcmp(const void *s1, const void *s2, size_t n); 33 | void *ft_memcpy(void *dest, const void *src, size_t n); 34 | void *ft_memmove(void *dest, const void *src, size_t n); 35 | void *ft_memset(void *s, int c, size_t n); 36 | void ft_putchar_fd(char c, int fd); 37 | void ft_putendl_fd(char *s, int fd); 38 | void ft_putnbr_fd(int n, int fd); 39 | void ft_putstr_fd(char *s, int fd); 40 | char **ft_split(char const *s, char c); 41 | char *ft_strchr(const char *s, int c); 42 | char *ft_strdup(const char *s); 43 | void ft_striteri(char *s, void (*f)(unsigned int, char *)); 44 | char *ft_strjoin(char const *s1, char const *s2); 45 | size_t ft_strlcat(char *dest, const char *src, size_t size); 46 | size_t ft_strlcpy(char *dest, const char *src, size_t size); 47 | size_t ft_strlen(const char *str); 48 | char *ft_strmapi(char const *s, char (*f)(unsigned int, char)); 49 | int ft_strncmp(const char *s1, const char *s2, size_t n); 50 | char *ft_strnstr(const char *big, const char *little, size_t len); 51 | char *ft_strrchr(const char *s, int c); 52 | char *ft_strtrim(char const *s1, char const *set); 53 | char *ft_substr(char const *s, unsigned int start, size_t len); 54 | int ft_tolower(int c); 55 | int ft_toupper(int c); 56 | 57 | // t_list *ft_lstnew(void *content); 58 | // void ft_lstadd_front(t_list **lst, t_list *new); 59 | // int ft_lstsize(t_list *lst); 60 | // t_list *ft_lstlast(t_list *lst); 61 | // void ft_lstadd_back(t_list **lst, t_list *new); 62 | // void ft_lstdelone(t_list *lst, void (*del)(void *)); 63 | // void ft_lstclear(t_list **lst, void (*del)(void *)); 64 | // void ft_lstiter(t_list *lst, void (*f)(void *)); 65 | // t_list *ft_lstmap(t_list *lst, void *(*f)(void *), void (*del)(void *)); 66 | 67 | #endif -------------------------------------------------------------------------------- /src/exec/exec2.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* exec2.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: reldnah +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/05/08 16:27:38 by handler #+# #+# */ 9 | /* Updated: 2023/05/12 11:24:53 by reldnah ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "../../include/minishell.h" 14 | 15 | static bool check_dir(char **path, char *cmd, t_data *data) 16 | { 17 | struct stat path_stat; 18 | 19 | stat(*path, &path_stat); 20 | if (!S_ISREG(path_stat.st_mode)) 21 | { 22 | print_error(cmd); 23 | print_error(" : Is a directory\n"); 24 | data->exit_code = 126; 25 | return (false); 26 | } 27 | return (true); 28 | } 29 | 30 | static bool cmd_exist(char **path, t_data *data, char *cmd) 31 | { 32 | if (!ft_strchr(cmd, '/')) 33 | *path = find_cmd(data, cmd, data->env); 34 | else 35 | absolute_path(path, cmd, data); 36 | if (!(*path) && data->exit_code == -1) 37 | free_all(data, NULL, data->exit_code); 38 | if (!(*path)) 39 | { 40 | data->exit_code = 127; 41 | return (false); 42 | } 43 | if (access((*path), X_OK)) 44 | { 45 | perror(*path); 46 | free((*path)); 47 | (*path) = NULL; 48 | data->exit_code = 126; 49 | return (false); 50 | } 51 | if (!check_dir(path, cmd, data)) 52 | return (false); 53 | return (true); 54 | } 55 | 56 | static void redirect_in_out(t_data *data, t_cmd *cmd, int *pip) 57 | { 58 | close(pip[0]); 59 | if (cmd->infile >= 0) 60 | { 61 | dup2(cmd->infile, 0); 62 | close(cmd->infile); 63 | } 64 | if (cmd->outfile >= 0) 65 | { 66 | dup2(cmd->outfile, 1); 67 | close(cmd->outfile); 68 | } 69 | else if (cmd->next != data->cmd) 70 | dup2(pip[1], 1); 71 | close(pip[1]); 72 | } 73 | 74 | static void built(int *pip, t_cmd *cmd, t_data *data) 75 | { 76 | close(pip[0]); 77 | if (cmd->outfile < 0 && cmd->next != data->cmd) 78 | cmd->outfile = pip[1]; 79 | else 80 | close(pip[1]); 81 | launch_builtin(data, cmd); 82 | } 83 | 84 | void child_process(t_data *data, t_cmd *cmd, int *pip) 85 | { 86 | char *path; 87 | char **env; 88 | 89 | path = NULL; 90 | if (cmd->skip_cmd) 91 | data->exit_code = 1; 92 | else if (is_builtin(cmd->cmd_param[0])) 93 | built(pip, cmd, data); 94 | else if (cmd_exist(&path, data, cmd->cmd_param[0])) 95 | { 96 | redirect_in_out(data, cmd, pip); 97 | env = lst_to_arr(data->env); 98 | if (!env) 99 | free_all(data, ERR_MALLOC, EXT_MALLOC); 100 | rl_clear_history(); 101 | signals2(); 102 | execve(path, cmd->cmd_param, env); 103 | free(env); 104 | } 105 | if (path) 106 | free(path); 107 | free_all(data, NULL, data->exit_code); 108 | } 109 | -------------------------------------------------------------------------------- /src/exec/exec.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* exec.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: reldnah +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/05/02 14:02:35 by reldnah #+# #+# */ 9 | /* Updated: 2023/05/12 11:24:10 by reldnah ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "../../include/minishell.h" 14 | 15 | bool is_builtin(char *cmd) 16 | { 17 | if (!cmd) 18 | return (false); 19 | if (!ft_strncmp("echo", cmd, INT_MAX) || !ft_strncmp("cd", cmd, INT_MAX) \ 20 | || !ft_strncmp("pwd", cmd, INT_MAX) || !ft_strncmp("export", cmd, INT_MAX) \ 21 | || !ft_strncmp("unset", cmd, INT_MAX) || !ft_strncmp("env", cmd, INT_MAX) \ 22 | || !ft_strncmp("exit", cmd, INT_MAX)) 23 | return (true); 24 | return (false); 25 | } 26 | 27 | static void parent_process(t_data *data, t_cmd *cmd, int *pip) 28 | { 29 | close(pip[1]); 30 | if (cmd->infile >= 0) 31 | close(cmd->infile); 32 | if (cmd->infile == -2) 33 | cmd->infile = pip[0]; 34 | if (cmd->next != data->cmd && cmd->next->infile == -2) 35 | cmd->next->infile = pip[0]; 36 | else 37 | close(pip[0]); 38 | } 39 | 40 | static bool exec_cmd(t_data *data, t_cmd *cmd, int *pip) 41 | { 42 | g_signal_pid = fork(); 43 | if (g_signal_pid < 0) 44 | free_all(data, ERR_FORK, EXT_FORK); 45 | else if (!g_signal_pid) 46 | { 47 | if (cmd->cmd_param && cmd->cmd_param[0]) 48 | child_process(data, cmd, pip); 49 | else 50 | free_all(data, NULL, 0); 51 | } 52 | else 53 | parent_process(data, cmd, pip); 54 | return (true); 55 | } 56 | 57 | static void wait_all(t_data *data) 58 | { 59 | int status; 60 | int pid; 61 | int len; 62 | t_cmd *tmp; 63 | 64 | tmp = data->cmd; 65 | len = len_cmd(tmp); 66 | while (len--) 67 | { 68 | pid = waitpid(0, &status, 0); 69 | if (pid == g_signal_pid) 70 | { 71 | if (WIFEXITED(status)) 72 | data->exit_code = WEXITSTATUS(status); 73 | } 74 | if (tmp->outfile >= 0) 75 | close(tmp->outfile); 76 | if (tmp->infile >= 0) 77 | close(tmp->infile); 78 | tmp = tmp->next; 79 | } 80 | } 81 | 82 | bool exec(t_data *data) 83 | { 84 | t_cmd *tmp; 85 | int *pip; 86 | 87 | pip = data->pip; 88 | tmp = data->cmd; 89 | if (tmp && tmp->skip_cmd == false && tmp->next == tmp && tmp->cmd_param[0] \ 90 | && is_builtin(tmp->cmd_param[0])) 91 | return (launch_builtin(data, tmp)); 92 | if (pipe(pip) == -1) 93 | return (false); 94 | exec_cmd(data, tmp, pip); 95 | tmp = tmp->next; 96 | while (tmp != data->cmd) 97 | { 98 | if (pipe(pip) == -1) 99 | return (-1); 100 | exec_cmd(data, tmp, pip); 101 | tmp = tmp->next; 102 | } 103 | wait_all(data); 104 | return (true); 105 | } 106 | -------------------------------------------------------------------------------- /Libft/src/get_next_line.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* get_next_line.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/11/21 10:56:48 by handler #+# #+# */ 9 | /* Updated: 2023/05/08 11:28:29 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "get_next_line.h" 14 | 15 | int how_many(t_list_gnl *list, char **line) 16 | { 17 | t_list_gnl *tmp; 18 | int len; 19 | int i; 20 | 21 | tmp = list; 22 | len = 0; 23 | while (tmp->next != list) 24 | { 25 | len += ft_strlen(tmp->content); 26 | tmp = tmp -> next; 27 | } 28 | i = -1; 29 | while (tmp->content[++i]) 30 | { 31 | if (tmp->content[i] == '\n') 32 | { 33 | ++len; 34 | break ; 35 | } 36 | ++len; 37 | } 38 | *line = malloc(sizeof(char *) * (len + 1)); 39 | return (len); 40 | } 41 | 42 | int make_line(t_list_gnl *list, char **line) 43 | { 44 | int i; 45 | int j; 46 | int len; 47 | 48 | len = how_many(list, line); 49 | if (!line) 50 | return (free_list_gnl(&list)); 51 | j = 0; 52 | while (j < len) 53 | { 54 | i = -1; 55 | while (list -> content[++i]) 56 | { 57 | if (list -> content[i] == '\n') 58 | { 59 | (*line)[j++] = list -> content[i]; 60 | break ; 61 | } 62 | (*line)[j++] = list -> content[i]; 63 | } 64 | list = list -> next; 65 | } 66 | (*line)[j] = '\0'; 67 | return (1); 68 | } 69 | 70 | int new_line(t_list_gnl *list) 71 | { 72 | int i; 73 | t_list_gnl *current; 74 | 75 | if (!list) 76 | return (0); 77 | current = list->prev; 78 | i = -1; 79 | while (current -> content[++i]) 80 | if (current -> content[i] == '\n') 81 | return (1); 82 | return (0); 83 | } 84 | 85 | char *get_next_line(int fd) 86 | { 87 | static t_list_gnl *list = NULL; 88 | char *line; 89 | 90 | line = NULL; 91 | if (fd < 0 && list) 92 | free_list_gnl(&list); 93 | if (fd < 0 || BUFFER_SIZE < 0) 94 | return (NULL); 95 | if (!write_in_list_gnl(fd, &list) || !list) 96 | return (NULL); 97 | if (!make_line(list, &line) || !clear_list_gnl(&list)) 98 | return (NULL); 99 | if (line[0] == '\0') 100 | { 101 | free(line); 102 | free_list_gnl(&list); 103 | return (NULL); 104 | } 105 | return (line); 106 | } 107 | 108 | // #include 109 | 110 | // int main(void) 111 | // { 112 | // char *str; 113 | // int fd; 114 | 115 | // fd = open("big_line_with_nl", O_RDONLY); 116 | // while (1) 117 | // { 118 | // str = get_next_line(fd); 119 | // if (!str) 120 | // break; 121 | // printf("%s", str); 122 | // free(str); 123 | // } 124 | // // str = get_next_line(fd); 125 | // // printf("%d\n", ft_strlen(str)); 126 | // // free(str); 127 | // close(fd); 128 | // return (0); 129 | // } 130 | -------------------------------------------------------------------------------- /Libft/src/get_next_line_utils.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* get_next_line_utils.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/11/23 11:30:53 by handler #+# #+# */ 9 | /* Updated: 2023/05/08 11:28:06 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "get_next_line.h" 14 | 15 | static int list_new_elem_str(t_list_gnl **new, char *elem) 16 | { 17 | (*new) = malloc(sizeof(t_list_gnl)); 18 | if (*new == NULL) 19 | return (0); 20 | (*new)->content = elem; 21 | (*new)->next = NULL; 22 | (*new)->prev = NULL; 23 | return (1); 24 | } 25 | 26 | int add_to_list_gnl(t_list_gnl **list, char *buf) 27 | { 28 | t_list_gnl *new; 29 | 30 | if (!list_new_elem_str(&new, buf)) 31 | return (0); 32 | if (!(*list)) 33 | { 34 | (*list) = new; 35 | (*list)->prev = *list; 36 | (*list)->next = *list; 37 | } 38 | else 39 | { 40 | new->prev = (*list)->prev; 41 | new->next = (*list); 42 | (*list)->prev->next = new; 43 | (*list)->prev = new; 44 | } 45 | return (1); 46 | } 47 | 48 | int free_list_gnl(t_list_gnl **list) 49 | { 50 | t_list_gnl *tmp; 51 | t_list_gnl *current; 52 | 53 | current = *list; 54 | if (!*list) 55 | return (0); 56 | while (current->next != *list) 57 | { 58 | tmp = current; 59 | current = current->next; 60 | free(tmp->content); 61 | free(tmp); 62 | } 63 | free(current->content); 64 | free(current); 65 | *list = NULL; 66 | return (0); 67 | } 68 | 69 | int write_in_list_gnl(int fd, t_list_gnl **list) 70 | { 71 | char *buf; 72 | int r_res; 73 | 74 | r_res = 1; 75 | while (!new_line(*list) && r_res != 0) 76 | { 77 | buf = malloc(sizeof(char) * (BUFFER_SIZE + 1)); 78 | if (!buf) 79 | return (free_list_gnl(list)); 80 | r_res = read(fd, buf, BUFFER_SIZE); 81 | if (r_res <= 0 && !(*list)) 82 | { 83 | free(buf); 84 | return (free_list_gnl(list)); 85 | } 86 | buf[r_res] = '\0'; 87 | if (!add_to_list_gnl(list, buf)) 88 | { 89 | free(buf); 90 | return (free_list_gnl(list)); 91 | } 92 | } 93 | return (1); 94 | } 95 | 96 | int clear_list_gnl(t_list_gnl **list) 97 | { 98 | t_list_gnl *last; 99 | char *content; 100 | int i; 101 | int j; 102 | 103 | if (!list) 104 | return (0); 105 | last = (*list)->prev; 106 | i = 0; 107 | while (last -> content[i] != '\n' && last -> content[i]) 108 | i++; 109 | if (last -> content[i] == '\n' && last -> content[i]) 110 | i++; 111 | j = ft_strlen(last -> content); 112 | content = malloc(sizeof(char) * ((j - i) + 1)); 113 | if (!content) 114 | return (free_list_gnl(list)); 115 | j = 0; 116 | while (last -> content[i]) 117 | content[j++] = last -> content[i++]; 118 | content[j] = '\0'; 119 | free_list_gnl(list); 120 | add_to_list_gnl(list, content); 121 | return (1); 122 | } 123 | -------------------------------------------------------------------------------- /src/main.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* main.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/04/24 14:44:20 by reldnah #+# #+# */ 9 | /* Updated: 2023/05/18 23:26:06 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "../include/minishell.h" 14 | 15 | pid_t g_signal_pid; 16 | 17 | int make_env(t_data *data, char **env) 18 | { 19 | t_list *list; 20 | int i; 21 | char *tmp; 22 | 23 | if (!(*env)) 24 | return (make_env2(data)); 25 | i = -1; 26 | list = NULL; 27 | while (env[++i]) 28 | { 29 | tmp = ft_strdup(env[i]); 30 | if (!tmp) 31 | return (free_list(&list)); 32 | if (!append(&list, tmp)) 33 | return (free_list(&list)); 34 | } 35 | data->env = list; 36 | return (1); 37 | } 38 | 39 | void init_data(t_data *data, int argc, char **argv) 40 | { 41 | (void)argc; 42 | (void)argv; 43 | data->env = NULL; 44 | data->token = NULL; 45 | data->cmd = NULL; 46 | data->exit_code = 0; 47 | data->pip[0] = -1; 48 | data->pip[1] = -1; 49 | g_signal_pid = 0; 50 | signals(); 51 | } 52 | 53 | bool empty_line(char *line) 54 | { 55 | int i; 56 | 57 | i = 0; 58 | while (line[i] && is_space(line[i])) 59 | i++; 60 | if (i == (int)ft_strlen(line)) 61 | { 62 | free(line); 63 | return (true); 64 | } 65 | return (false); 66 | } 67 | 68 | bool parseline(t_data *data, char *line) 69 | { 70 | if (open_quote(data, line)) 71 | { 72 | free(line); 73 | return (false); 74 | } 75 | if (!replace_dollar(&line, data) || !create_list_token(&data->token, line)) 76 | { 77 | free(line); 78 | free_all(data, ERR_MALLOC, EXT_MALLOC); 79 | } 80 | free(line); 81 | print_token(data->token); 82 | if (data->token && data->token->prev->type == PIPE) 83 | { 84 | write(2, "Error: Unclosed pipe\n", 21); 85 | data->exit_code = 2; 86 | free_token(&data->token); 87 | return (false); 88 | } 89 | if (!data->token || !create_list_cmd(data)) 90 | { 91 | free_token(&data->token); 92 | free_cmd(&data->cmd); 93 | return (false); 94 | } 95 | return (check_pipe(data)); 96 | } 97 | 98 | int main(int argc, char **argv, char **env) 99 | { 100 | t_data data; 101 | char *line; 102 | 103 | init_data(&data, argc, argv); 104 | if (!make_env(&data, env)) 105 | free_all(&data, ERR_MALLOC, EXT_MALLOC); 106 | while (1) 107 | { 108 | line = readline("minishell> "); 109 | if (!line) 110 | free_all(&data, "exit\n", data.exit_code); 111 | if (empty_line(line)) 112 | continue ; 113 | add_history(line); 114 | if (!parseline(&data, line)) 115 | continue ; 116 | if (!exec(&data)) 117 | free_all(&data, ERR_PIPE, EXT_PIPE); 118 | free_cmd(&data.cmd); 119 | free_token(&data.token); 120 | g_signal_pid = 0; 121 | } 122 | rl_clear_history(); 123 | free_all(&data, NULL, -1); 124 | return (0); 125 | } 126 | -------------------------------------------------------------------------------- /src/parsing/dollar_replace.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* dollar_replace.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/05/08 11:53:44 by handler #+# #+# */ 9 | /* Updated: 2023/05/11 22:49:07 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "../../include/minishell.h" 14 | 15 | static int in_env(t_data *data, char *line, int size, char **str) 16 | { 17 | char *tmp; 18 | char *key; 19 | char *value; 20 | 21 | key = get_dollar_word(line, size); 22 | value = get_elem_env(data->env, key); 23 | if (key) 24 | free(key); 25 | tmp = ft_strjoin(*str, value); 26 | if (value) 27 | free(value); 28 | free(*str); 29 | if (!tmp) 30 | return (0); 31 | *str = tmp; 32 | return (1); 33 | } 34 | 35 | static int dollar_point_interrogation(t_data *data, char **str) 36 | { 37 | char *tmp; 38 | char *tmp2; 39 | 40 | tmp = ft_itoa(data->exit_code); 41 | if (!tmp) 42 | return (0); 43 | tmp2 = ft_strjoin(*str, tmp); 44 | free(tmp); 45 | free(*str); 46 | if (!tmp2) 47 | return (0); 48 | *str = tmp2; 49 | return (1); 50 | } 51 | 52 | int add_dollar(char *line, int *index, char **str, t_data *data) 53 | { 54 | int ctrl; 55 | int n; 56 | 57 | n = *index; 58 | ctrl = exist_in_env(line, index, data); 59 | if (ctrl == 1) 60 | return (in_env(data, &line[n], *index - n, str)); 61 | else if (ctrl == 2) 62 | { 63 | (*index) += 2; 64 | return (dollar_point_interrogation(data, str)); 65 | } 66 | else 67 | { 68 | ++(*index); 69 | while (line[*index] && \ 70 | (ft_isalnum(line[*index]) || line[*index] == '_')) 71 | ++(*index); 72 | return (1); 73 | } 74 | } 75 | 76 | int add_char(char *c, char **str, t_data *data, int *index) 77 | { 78 | char char_to_str[2]; 79 | char *tmp2; 80 | int i; 81 | 82 | i = 0; 83 | if (c[i] == '$' && !data->sq && exist_in_env(c, &i, data)) 84 | return (1); 85 | char_to_str[0] = *c; 86 | char_to_str[1] = '\0'; 87 | (*index)++; 88 | tmp2 = ft_strjoin(*str, char_to_str); 89 | free(*str); 90 | if (!tmp2) 91 | return (0); 92 | *str = tmp2; 93 | return (1); 94 | } 95 | 96 | int replace_dollar(char **line, t_data *data) 97 | { 98 | bool dq; 99 | int i; 100 | char *str; 101 | 102 | i = 0; 103 | dq = false; 104 | data->sq = false; 105 | str = ft_strdup(""); 106 | while ((*line)[i]) 107 | { 108 | quoting_choice(&dq, &data->sq, NULL, (*line)[i]); 109 | if ((*line)[i] && (*line)[i + 1] && (*line)[i] == '$' && \ 110 | ((*line)[i + 1] != '\'' && (*line)[i + 1] != '"') && \ 111 | (ft_isalpha((*line)[i + 1]) || (*line)[i + 1] == '?' || \ 112 | (*line)[i + 1] == '_') && !data->sq && \ 113 | !add_dollar((*line), &i, &str, data)) 114 | return (0); 115 | if ((*line)[i] && !add_char(&(*line)[i], &str, data, &i)) 116 | return (0); 117 | } 118 | free(*line); 119 | *line = str; 120 | return (1); 121 | } 122 | -------------------------------------------------------------------------------- /src/builtin/ft_unset.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_unset.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: reldnah +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/04/25 16:06:58 by reldnah #+# #+# */ 9 | /* Updated: 2023/05/10 15:59:30 by reldnah ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "../../include/minishell.h" 14 | 15 | //syntax 16 | static bool syntax(char *str) 17 | { 18 | int i; 19 | 20 | if (str[0] != '_' && !ft_isalpha(str[0])) 21 | return (false); 22 | i = 0; 23 | while (str[i]) 24 | { 25 | if (!ft_isalnum(str[i]) && str[i] != '_') 26 | return (false); 27 | i++; 28 | } 29 | return (true); 30 | } 31 | 32 | //checks if identifier already in env 33 | static int exist(char *str, t_list *env) 34 | { 35 | int i; 36 | int j; 37 | t_list *tmp; 38 | 39 | if (!env) 40 | return (-1); 41 | i = 0; 42 | while (str[i]) 43 | i++; 44 | j = 0; 45 | tmp = env; 46 | if (!ft_strncmp(tmp->str, str, i)) 47 | return (j); 48 | tmp = tmp->next; 49 | j++; 50 | while (tmp != env) 51 | { 52 | if (!ft_strncmp(tmp->str, str, i)) 53 | return (j); 54 | tmp = tmp->next; 55 | j++; 56 | } 57 | return (-1); 58 | } 59 | 60 | //static bool unset(char *str, t_list **env) 61 | //{ 62 | // int pos; 63 | // int i; 64 | // t_list **tmp; 65 | 66 | // if (!str || !(*str)) 67 | // return (false); 68 | // if (!syntax(str)) 69 | // { 70 | // print_error("unset: invalid identifier\n"); 71 | // return (true); 72 | // } 73 | // pos = exist(str, (*env)); 74 | // if (pos == -1) 75 | // return (false); 76 | // tmp = env; 77 | // i = 0; 78 | // while (i++ < pos) 79 | // (*env) = (*env)->next; 80 | // (*env)->prev->next = (*env)->next; 81 | // (*env)->next->prev = (*env)->prev; 82 | // free((*env)->str); 83 | // free((*env)); 84 | // (*env) = NULL; 85 | // env = tmp; 86 | // return (false); 87 | //} 88 | 89 | static void check_env(t_list *tmp, t_list **env) 90 | { 91 | if (tmp == (*env)) 92 | (*env) = tmp->next; 93 | if (tmp->next == tmp) 94 | (*env) = NULL; 95 | } 96 | 97 | static bool unset(char *str, t_list **env) 98 | { 99 | int pos; 100 | int i; 101 | t_list *tmp; 102 | 103 | if (!str || !(*str)) 104 | return (false); 105 | if (!syntax(str)) 106 | { 107 | print_error("unset: invalid identifier\n"); 108 | return (true); 109 | } 110 | pos = exist(str, (*env)); 111 | if (pos == -1) 112 | return (false); 113 | tmp = (*env); 114 | i = 0; 115 | while (i++ < pos) 116 | tmp = tmp->next; 117 | tmp->prev->next = tmp->next; 118 | tmp->next->prev = tmp->prev; 119 | free(tmp->str); 120 | check_env(tmp, env); 121 | free(tmp); 122 | tmp = NULL; 123 | return (false); 124 | } 125 | 126 | int ft_unset(char **str, t_list **env) 127 | { 128 | int exit_code; 129 | int i; 130 | 131 | exit_code = 0; 132 | i = 0; 133 | while (str[i]) 134 | { 135 | if (unset(str[i], env)) 136 | exit_code = 1; 137 | i++; 138 | } 139 | return (exit_code); 140 | } 141 | -------------------------------------------------------------------------------- /src/builtin/ft_export.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_export.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: reldnah +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/04/24 16:04:29 by reldnah #+# #+# */ 9 | /* Updated: 2023/05/10 13:24:37 by reldnah ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "../../include/minishell.h" 14 | 15 | //if export and no other args 16 | static bool export_no_args(t_list *env) 17 | { 18 | char **arr; 19 | int i; 20 | int j; 21 | 22 | arr = lst_to_arr(env); 23 | if (!arr) 24 | return (false); 25 | sort_array(arr, len_list(env)); 26 | i = 0; 27 | while (arr[i]) 28 | { 29 | printf("declare -x "); 30 | j = 0; 31 | while (arr[i][j] && arr[i][j] != '=') 32 | printf("%c", arr[i][j++]); 33 | if (arr[i][j] && arr[i][j] == '=') 34 | printf("=\"%s\"\n", &arr[i][j + 1]); 35 | else 36 | printf("\n"); 37 | i++; 38 | } 39 | free(arr); 40 | return (true); 41 | } 42 | 43 | //checks syntax 44 | static bool valid_identifier(char *str) 45 | { 46 | int i; 47 | 48 | i = 0; 49 | if (!str[0] || (str[0] != '_' && !ft_isalpha(str[0]))) 50 | return (false); 51 | while (str[i] && str[i] != '=') 52 | { 53 | if (!ft_isalnum(str[i]) && str[i] != '_') 54 | return (false); 55 | i++; 56 | } 57 | return (true); 58 | } 59 | 60 | //checks if identifier already in env 61 | static int exist(char *str, t_list *env) 62 | { 63 | int i; 64 | int j; 65 | t_list *tmp; 66 | 67 | if (!env) 68 | return (-1); 69 | i = 0; 70 | while (str[i] && str[i] != '=') 71 | i++; 72 | j = 0; 73 | tmp = env; 74 | if (!ft_strncmp(tmp->str, str, i) && (tmp->str[i] == '\0' || \ 75 | tmp->str[i] == '=')) 76 | return (j); 77 | tmp = tmp->next; 78 | j++; 79 | while (tmp != env) 80 | { 81 | if (!ft_strncmp(tmp->str, str, i) && (tmp->str[i] == '\0' || \ 82 | tmp->str[i] == '=')) 83 | return (j); 84 | tmp = tmp->next; 85 | j++; 86 | } 87 | return (-1); 88 | } 89 | 90 | //export but norm 91 | bool export(char *str, t_list **env) 92 | { 93 | int pos; 94 | int i; 95 | char *value; 96 | 97 | pos = exist(str, (*env)); 98 | value = ft_strdup(str); 99 | if (!value) 100 | return (false); 101 | if (pos >= 0) 102 | { 103 | i = 0; 104 | while (i < pos) 105 | { 106 | (*env) = (*env)->next; 107 | i++; 108 | } 109 | free((*env)->str); 110 | (*env)->str = value; 111 | } 112 | else if (pos == -1) 113 | if (!append(env, value)) 114 | return (false); 115 | return (true); 116 | } 117 | 118 | //export 119 | int ft_export(char **str, t_list **env) 120 | { 121 | int exit_code; 122 | int i; 123 | 124 | exit_code = 0; 125 | i = 1; 126 | if (!str || !str[i]) 127 | { 128 | if (*env && !export_no_args((*env))) 129 | return (print_error(ERR_MALLOC)); 130 | return (0); 131 | } 132 | while (str[i]) 133 | { 134 | if (!valid_identifier(str[i])) 135 | { 136 | print_error("export: invalid identifier\n"); 137 | exit_code = 1; 138 | } 139 | else if (!export(str[i], env)) 140 | return (print_error(ERR_MALLOC)); 141 | i++; 142 | } 143 | return (exit_code); 144 | } 145 | -------------------------------------------------------------------------------- /src/parsing/cmd_fd.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* cmd_fd.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/05/02 13:04:15 by reldnah #+# #+# */ 9 | /* Updated: 2023/05/11 22:49:07 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "../../include/minishell.h" 14 | 15 | static int open_file(t_data *data, char *filename, int type) 16 | { 17 | int fd; 18 | 19 | fd = -2; 20 | if (type == INPUT) 21 | fd = open(filename, O_RDONLY, 0644); 22 | else if (type == HEREDOC) 23 | fd = here_doc(data, filename); 24 | else if (type == TRUNC) 25 | fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0644); 26 | else if (type == APPEND) 27 | fd = open(filename, O_CREAT | O_WRONLY | O_APPEND, 0644); 28 | if (type != HEREDOC && fd < 0) 29 | perror(filename); 30 | return (fd); 31 | } 32 | 33 | static bool get_in(t_data *data, t_token *tmp, t_cmd *cmd) 34 | { 35 | if (tmp->type == INPUT) 36 | { 37 | if (cmd->infile >= 0) 38 | close(cmd->infile); 39 | if (tmp == tmp->next || tmp->next->type <= 5) 40 | return (print_error_token(tmp, data)); 41 | cmd->infile = open_file(data, tmp->next->str, INPUT); 42 | if (cmd->infile == -1) 43 | return (false); 44 | } 45 | else if (tmp->type == HEREDOC) 46 | { 47 | if (cmd->infile >= 0) 48 | close(cmd->infile); 49 | if (tmp == tmp->next || tmp->next->type <= 5) 50 | return (print_error_token(tmp, data)); 51 | cmd->infile = open_file(data, tmp->next->str, HEREDOC); 52 | if (cmd->infile == -1) 53 | return (false); 54 | } 55 | return (true); 56 | } 57 | 58 | bool get_infile(t_data *data, t_token *token, t_cmd *cmd) 59 | { 60 | t_token *tmp; 61 | 62 | tmp = token; 63 | if (tmp->type != PIPE && !get_in(data, tmp, cmd)) 64 | return (false); 65 | if (tmp->type == PIPE) 66 | return (true); 67 | tmp = tmp->next; 68 | while (tmp->type != PIPE && tmp != data->token) 69 | { 70 | if (!get_in(data, tmp, cmd)) 71 | return (false); 72 | tmp = tmp->next; 73 | } 74 | return (true); 75 | } 76 | 77 | static bool get_out(t_token *tmp, t_cmd *cmd, t_data *data) 78 | { 79 | if (tmp->type == TRUNC) 80 | { 81 | if (cmd->outfile >= 0) 82 | close(cmd->outfile); 83 | if (tmp == tmp->next || tmp->next->type <= 5) 84 | return (print_error_token(tmp, data)); 85 | cmd->outfile = open_file(NULL, tmp->next->str, TRUNC); 86 | if (cmd->outfile == -1) 87 | return (false); 88 | } 89 | else if (tmp->type == APPEND) 90 | { 91 | if (cmd->outfile >= 0) 92 | close(cmd->outfile); 93 | if (tmp == tmp->next || tmp->next->type <= 5) 94 | return (print_error_token(tmp, data)); 95 | cmd->outfile = open_file(NULL, tmp->next->str, APPEND); 96 | if (cmd->outfile == -1) 97 | return (false); 98 | } 99 | return (true); 100 | } 101 | 102 | bool get_outfile(t_token *token, t_cmd *cmd, t_data *data) 103 | { 104 | t_token *tmp; 105 | 106 | tmp = token; 107 | if (tmp->type != PIPE && !get_out(tmp, cmd, data)) 108 | return (false); 109 | tmp = tmp->next; 110 | while (tmp != data->token && tmp->type != PIPE) 111 | { 112 | if (!get_out(tmp, cmd, data)) 113 | return (false); 114 | tmp = tmp->next; 115 | } 116 | return (true); 117 | } 118 | -------------------------------------------------------------------------------- /src/parsing/create_token.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* create_token.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: handler +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/04/19 16:02:52 by reldnah #+# #+# */ 9 | /* Updated: 2023/05/11 22:49:07 by handler ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "../../include/minishell.h" 14 | 15 | static int length_cmd(char *command, int *quotes) 16 | { 17 | int i; 18 | 19 | i = 0; 20 | *quotes = 0; 21 | while (command[i] && !is_space(command[i]) && !is_special(command + i)) 22 | { 23 | if (command[i] == '"' || command[i] == '\'') 24 | { 25 | (*quotes)++; 26 | if (command[i++] == '"') 27 | while (command[i] && command[i] != '"') 28 | ++i; 29 | else 30 | while (command[i] && command[i] != '\'') 31 | ++i; 32 | if (command[i]) 33 | ++i; 34 | } 35 | if (command[i] && command[i] != '"' && command[i] != '\'' && \ 36 | !is_space(command[i]) && !is_special(command + i)) 37 | ++i; 38 | } 39 | return (i); 40 | } 41 | 42 | static void copy_token(char *command, int length, char *str, int i) 43 | { 44 | int j; 45 | 46 | j = 0; 47 | while (command[i + j] && i < length) 48 | { 49 | if (command[i + j] == '\'' && ++j) 50 | { 51 | while (command[i + j] != '\'' && ++i) 52 | str[i - 1] = command[(i - 1) + j]; 53 | j++; 54 | } 55 | else if (command[i + j] == '"' && ++j) 56 | { 57 | while (command[i + j] != '"' && ++i) 58 | str[i - 1] = command[(i - 1) + j]; 59 | j++; 60 | } 61 | else 62 | { 63 | str[i] = command[i + j]; 64 | i++; 65 | } 66 | } 67 | str[i] = 0; 68 | } 69 | 70 | static bool add_cmd(t_token **begin, char **command) 71 | { 72 | char *str; 73 | int length; 74 | int quotes; 75 | int i; 76 | 77 | i = 0; 78 | length = length_cmd(*command, "es); 79 | if (((length) - (2 * quotes)) < 0) 80 | return (true); 81 | str = malloc(sizeof(char) * ((length + 1) - (2 * quotes))); 82 | if (!str) 83 | return (false); 84 | copy_token(*command, length - (2 * quotes), str, i); 85 | if (!append_token(begin, str, 0)) 86 | return (false); 87 | if ((*begin)->prev == (*begin) || (*begin)->prev->prev->type == PIPE) 88 | (*begin)->prev->type = CMD; 89 | else 90 | (*begin)->prev->type = ARG; 91 | (*command) += length; 92 | return (true); 93 | } 94 | 95 | static bool add_special(t_token **begin, char **command) 96 | { 97 | int spe; 98 | 99 | spe = is_special(*command); 100 | if (!spe) 101 | return (false); 102 | if (spe == INPUT && !append_token(begin, ft_strdup("<"), INPUT)) 103 | return (false); 104 | else if (spe == HEREDOC && !append_token(begin, ft_strdup("<<"), HEREDOC)) 105 | return (false); 106 | else if (spe == TRUNC && !append_token(begin, ft_strdup(">"), TRUNC)) 107 | return (false); 108 | else if (spe == APPEND && !append_token(begin, ft_strdup(">>"), APPEND)) 109 | return (false); 110 | else if (spe == PIPE && !append_token(begin, ft_strdup("|"), PIPE)) 111 | return (false); 112 | if (spe == INPUT || spe == TRUNC || spe == PIPE) 113 | (*command)++; 114 | else if (spe == HEREDOC || spe == APPEND) 115 | (*command) += 2; 116 | return (true); 117 | } 118 | 119 | bool create_list_token(t_token **begin, char *command) 120 | { 121 | (*begin) = NULL; 122 | while (*command) 123 | { 124 | while (is_space(*command)) 125 | command++; 126 | if (*command && !is_special(command) && !add_cmd(begin, &command)) 127 | { 128 | if (*begin) 129 | free_token(begin); 130 | return (false); 131 | } 132 | else if (*command && is_special(command) && \ 133 | !add_special(begin, &command)) 134 | { 135 | if (*begin) 136 | free_token(begin); 137 | return (false); 138 | } 139 | } 140 | return (true); 141 | } 142 | -------------------------------------------------------------------------------- /include/minishell.h: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* minishell.h :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: reldnah +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2023/05/08 12:00:54 by handler #+# #+# */ 9 | /* Updated: 2023/05/12 11:25:15 by reldnah ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #ifndef MINISHELL_H 14 | # define MINISHELL_H 15 | 16 | # include 17 | # include 18 | # include 19 | # include 20 | # include 21 | # include 22 | # include 23 | # include 24 | # include 25 | # include 26 | # include "../Libft/src/libft.h" 27 | # include "../Libft/src/get_next_line.h" 28 | 29 | # define INPUT 1 //"<" 30 | # define HEREDOC 2 //"<<" 31 | # define TRUNC 3 //">" 32 | # define APPEND 4 //">>" 33 | # define PIPE 5 //"|" 34 | # define CMD 6 //"|" 35 | # define ARG 7 //"|" 36 | 37 | # define ERR_MALLOC "malloc error\n" 38 | # define ERR_PIPE "pipe error\n" 39 | # define ERR_FORK "fork error\n" 40 | 41 | # define EXT_MALLOC 1 42 | # define EXT_PIPE 1 43 | # define EXT_FORK 1 44 | 45 | extern pid_t g_signal_pid; 46 | 47 | typedef struct s_cmd 48 | { 49 | bool skip_cmd; 50 | int infile; 51 | int outfile; 52 | char **cmd_param; 53 | struct s_cmd *prev; 54 | struct s_cmd *next; 55 | } t_cmd; 56 | 57 | typedef struct s_token 58 | { 59 | char *str; 60 | int type; 61 | struct s_token *prev; 62 | struct s_token *next; 63 | } t_token; 64 | 65 | typedef struct s_list 66 | { 67 | char *str; 68 | struct s_list *prev; 69 | struct s_list *next; 70 | } t_list; 71 | 72 | typedef struct s_data 73 | { 74 | t_list *env; 75 | t_token *token; 76 | t_cmd *cmd; 77 | int exit_code; 78 | int pip[2]; 79 | bool sq; 80 | } t_data; 81 | 82 | /* main */ 83 | int make_env(t_data *data, char **env); 84 | 85 | /* List utils */ 86 | int free_list(t_list **list); 87 | int append(t_list **list, char *elem); 88 | size_t len_list(t_list *list); 89 | 90 | /* quote */ 91 | void quoting_choice(bool *dq, bool *sq, int *index, char c); 92 | int open_quote(t_data *data, char *line); 93 | 94 | /* dollar_env */ 95 | int exist_in_env(char *line, int *i, t_data *data); 96 | char *get_elem_env(t_list *env, char *key); 97 | char *get_dollar_word(char *line, int size); 98 | 99 | /* dollar_replace */ 100 | int add_dollar(char *line, int *index, char **str, t_data *data); 101 | int add_char(char *c, char **str, t_data *data, int *index); 102 | int replace_dollar(char **line, t_data *data); 103 | 104 | //signals.c 105 | void clear_rl_line(void); 106 | void signals(void); 107 | 108 | //create_token.c 109 | bool create_list_token(t_token **begin, char *command); 110 | 111 | //list_token.c 112 | int append_token(t_token **list, char *str, int type); 113 | void free_token(t_token **list); 114 | 115 | //ms_utils.c 116 | bool is_space(char c); 117 | int is_special(char *str); 118 | bool check_pipe(t_data *data); 119 | bool make_env2(t_data *data); 120 | void absolute_path(char **path, char *cmd, t_data *data); 121 | 122 | //ft_env.c 123 | int ft_env(t_list *env); 124 | //ft_export.c 125 | int ft_export(char **str, t_list **env); 126 | bool export(char *str, t_list **env); 127 | //ft_echo 128 | int ft_echo(char **args); 129 | //ft_unset.c 130 | int ft_unset(char **str, t_list **env); 131 | // ft_pwd 132 | int ft_pwd(void); 133 | // ft_cd 134 | int ft_cd(t_data *data, char **params); 135 | //ft_exit.c 136 | void ft_exit(t_data *data, char **args); 137 | 138 | //free.c 139 | void free_array(char **arr); 140 | bool print_error(char *str); 141 | void free_all(t_data *data, char *err, int ext); 142 | bool print_error_token(t_token *token, t_data *data); 143 | 144 | //array_utils.c 145 | char **lst_to_arr(t_list *env); 146 | void sort_array(char **arr, int len); 147 | 148 | //list_cmd.c 149 | int append_cmd(t_cmd **list, int infile, int outfile, char **cmd_param); 150 | void free_cmd(t_cmd **list); 151 | size_t len_cmd(t_cmd *list); 152 | 153 | //create_cmd.c 154 | bool create_list_cmd(t_data *data); 155 | 156 | //cmd_fd.c 157 | bool get_infile(t_data *data, t_token *token, t_cmd *cmd); 158 | bool get_outfile(t_token *token, t_cmd *cmd, t_data *data); 159 | 160 | //here_doc.c 161 | int here_doc(t_data *data, char *word); 162 | 163 | //cmd_param.c 164 | char **get_param(t_data *data, t_token *token); 165 | 166 | //exec.c 167 | bool exec(t_data *data); 168 | bool is_builtin(char *cmd); 169 | 170 | //launch_builtin.c 171 | bool launch_builtin(t_data *data, t_cmd *cmd); 172 | 173 | //find_cmd.c 174 | char *find_cmd(t_data *data, char *sample, t_list *env); 175 | 176 | //exec2.c 177 | void child_process(t_data *data, t_cmd *cmd, int *pip); 178 | 179 | //signals2.c 180 | void signals2(void); 181 | 182 | 183 | // ******** DEBUG ********** // 184 | void print_token(t_token *token); 185 | void print_tab(char **tab); 186 | void print_cmd(t_cmd *cmd); 187 | 188 | #endif 189 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Minishell (101 %) 2 | 3 | L’objectif de ce projet est de créer un shell minimaliste. 4 | 5 | # Préambule 6 | Minishell est à mon sens un projet qui est au antipodes de la définition du mot "fun", vous allez le détester, devenir fou et peut-être même backhole dessus...
7 | Ce projet ne vous apprendra pas grand chose si vous avez déjà fait pipex avant, avis à tout ceux qui ont fait minitalk : dommage vous avez choisi le mauvais projet pour préparer minishell.
8 | ### Le comportement de minishell doit être le même que sur bash, ça ne veut pas pour autant dire qu'il doit respecter la norme POSIX. Si vous voulez faire un minishell POSIX c'est 42sh qu'il faudra faire. 9 | # Comment bien commencer le projet ? 10 | Le plus dur dans minishell c'est de bien commencer et de savoir comment faire. Si vous voulez trouver par vous même fermez la fenetre tout de suite !
11 | Minishell est globalement un projet de parsing, execve() sera votre meilleure amie sur la partie de l'execution donc no stress là dessus.
12 | Il faudra par contre découper la chaine de charactère comme il se doit pour pouvoir la passer à execve, et c'est là que ça devient compliqué... 13 | # Les tokens 14 | Pour chaques lignes de commandes envoyée à votre programme, plein de choses seront faite mais la plus important des choses à faire est de se créer une liste chainée de token pour chaques éléments de la ligne de commande.
15 | La liste chainée aura une str et un int pour chaque maillon, la str sera le "mot" et l'int le token. 16 | Prenons l'exemple de la pire ligne de commande possible : `cat|ls` (on remarquera qu'il n'y a pas d'espace et c'est normal) 17 | - le premier token aura comme str "cat" avec CMD comme type (6). 18 | - le deuxieme token aura comme str "|" avec PIPE comme type (5). 19 | - le dernier token aura comme str "ls" avec CMD comme type (6). 20 | 21 | (se referer à [minishell.h](https://github.com/Hqndler/42-minishell/blob/main/include/minishell.h)) 22 | 23 | Les règles sont simple : 24 | - Si on croise une redirection (`<`, `>`, `<<` ou `>>`) alors le token sera soit INPUT (1), soit TRUNC (3), soit HEREDOC (2) ou soit APPEND (4) respectivement. 25 | - Le premier token sera CMD (6) si pas de redirection. 26 | - Les tokens après un CMD ou une redirection seront ARG (7). 27 | - Si "|" est la str avec il aura le type PIPE (5). 28 | - Après un pipe le prochain token sera soit une redirection soit CMD. 29 | 30 | Les tokens ne sont pas la première étape du parsing mais ils sont la clé d'un minishell simple à faire. 31 | 32 | # Comment on s'y est pris ? 33 | Premièrement plein de choses ne sont pas à gerer : les quotes ouvertes, les backslash, les points virgules ne sont pas à gerer.
34 | Le dérouler est simple : 35 | - check des quotes histoire de ne pas avoir de problème par la suite, message d'erreur si quote ouverte. 36 | - remplacement des variables d'environments s'il y en a. 37 | - création des tokens, check du dernier token, si c'est un pipe message d'erreur 38 | - création des différentes commandes (t_cmd). 39 | 40 | ## Sur les quotes 41 | L'interprétation des quotes n'est pas forcément celle que pous pensez avoir. Quand une quote est ouverte, elle sera fermer au moment où le charactère d'ouverture sera trouver dans la str.
42 | Dans `echo ""hello""` les doubles quotes sont ouvertes et fermées instantanément et il y a hello qui n'est pas entre quotes.
43 | `echo $USER` et `echo "$USER"` affichera la valeur de USER tandis que `echo '$USER'` affichera `$USER`. 44 | ### Tout ce qui est entre single quote ne doit pas être interprété. 45 | Donc `echo ''$USER''` affichera... La valeur de USER, vous suivez ?
46 | Le meilleur moyen est de tester avec bash et avec des variables d'environements.
47 | Au niveau des tokens, s'il y a des quotes alors la string sera l'entièreté du contenu de ce qu'il y a dans la quote, exemple :
48 | - `echo "cat | ls" lol` -> le deuxième token aura pour str `"cat | ls"` et ARG (7) comme type. 49 | - `echo "une phrase très longue avec l'arrivée d'une apostrophe" ''$?''` cette commande n'a pas de quote ouverte. Le deuxième token aura pour str `"une phrase très longue avec l'arrivée d'une apostrophe"` et le type ARG (7), le dernier token aura pour str itoa(exit->code) de la dernière commande puisque $? n'est pas entre quote. 50 | 51 | Pour faire simple, une fois les quotes ouvertes la str du token continue tant que la quote n'est pas fermée. Tout char dans les quotes à ce niveau là ne doit pas être interpreter que ça soit un pipe, une redirection, un point virgule ou que sais-je. 52 | 53 | ## Les t_cmd 54 | 55 | Un t_cmd est une liste chainée avec un fd d'infile, d'outfile et un tableau de chaine de charactères. Ce tableau sera le deuxième paramètres qu'on passera à execve().
56 | Nous avons decider de ne pas faire les bonus donc les t_cmd seront simple : il aura autant de maillon dans la liste chainée qu'il y a de commande dans la ligne de commandes.
57 | `echo lol` aura un seul maillon alors que `echo lol | cat -e` aura deux maillons.
58 | Les fd d'infile et d'outfile sont là pour les redirections. C'est à la création des t_cmd que les redirections sont ouvertes.
59 | C'est pour l'ouverture des redirections et la création du tableau de chaine de charactères que les tokens sont très important. Le token pipe servant de limiteur pour le tableau de char * et de création d'un nouveau maillon de t_cmd.
60 | 61 | ## L'execution 62 | 63 | Le sujet demande d'avoir des builtins, dans l'éventualité qu'on lance minishell avec `env -i` ou qu'on unset PATH il est impératif de les recoder entièrement et ne pas utiliser execve() pour ces builtins. 64 | #### Execve 65 | Pour toute les autres commandes execve sera la fonction qui fera le café. Execve prend trois paramètres : 66 | - le premier un char * path qui sera le chemin complet vers la commande demandée -> ls aura comme chemin /bin/ls 67 | - le deuxième un tableau de chaine de charactères se finisant par NULL, l'équivalent d'un ft_split("ls -ls", ' ') 68 | - le troisième un tableau de chaine de charactères **env, littéralement le char **env qu'on a dans le main, je vous conseille quand même de recréer un char **env si des modifications ont été apportées aux variables d'environments. 69 | 70 | #### Pourquoi recréer un env ? 71 | Prenons l'exemple d'un .sh, avant de vouloir le lancer dans notre minishell on aura export une nouvelle variable d'environment `export LOL=lolilol`, dans ce .sh on écrira $LOL. Si on venait à lancer execve sans avoir recréer un env, la variable d'environment LOL n'existe pas et ne sera pas affichée...
72 | Chose simple à savoir : vous n'êtes pas obliger de dup tout les str de votre env de minishell pour créer un char ** env pour execve, un char * est un pointeur vers le premier char de la chaine de charactère. Un char ** est un tableau de pointeur, il suffit de malloc ce tablau et d'y ajouter tout les pointeurs. Attention à ne pas free ce qu'il y a dans ce tableau : toutes les str de l'env du minishell seront free aussi. 73 | 74 | ## Les builtins 75 | 76 | Expérimentez un maximum tout les commandes des builtins pour comprendre leur comportements. 77 | - cd permet de changer de dossier, il update pwd et oldpwd en conséquence. 78 | - echo avec l'option -n affiche tout les arg qui suivent, avec ou sans retour à la ligne. (echo -nn -nnn -nnnn oui -> oui$) 79 | - env affiche les variables d'environments qui ont des valeurs associées. 80 | - exit permet de quitter avec le code erreur donner en argument (à tester en long en large et en travers) 81 | - export sans argument affiche l'env dans l'ordre ascii (testez `export a` puis faites export, `export a=` puis re export... tient c'est drôle), export avec argument permet d'export autant de fois qu'il faut. 82 | - pwd affiche le dossier dans le lequel le proccess se trouve. 83 | - unset permet de retirer une variable d'environment. 84 | 85 | Les exit code de ces builtins sont important, testez les de votre côté (`echo $?` pour rappel) 86 | 87 | ## Les signaux 88 | 89 | Pas grand chose à dire dessus, regardez comment utiliser la fonction signal() et les SIG code. De notre côté le ctrl + \ n'est pas parfaitement gerer, le message d'erreur est manquant, et le ctrl + C dans un heredoc est possible à faire mais on ne l'a pas fait. Le moyen de faire le ctrl + C dans un heredoc qu'on a trouvé était de mettre tout la partie écriture du heredoc dans le child d'un fork() pour exit et retourner au main ensuite. 90 | Petit rappel de ce que doivent faire les signaux : 91 | - ctrl + C redonne un prompt que la ligne soit vide ou pleine ou qu'on soit dans une commande bloquante comme `cat` 92 | - ctrl + D exit si la ligne est vide et redonne un prompt dans un commande bloquante comme `grep ""` 93 | - ctrl + \ ne fait rien sauf dans une commande bloquante, il permet de kill le process avec un message d'erreur. 94 | 95 | ## Les messages d'erreur et le projet en général 96 | 97 | Les messages ne sont pas demandé, vous pouvez ne pas les mettre, si vous voulez en mettre les tokens sont important pour ça aussi.
98 | Le plus dur dans ce projet se passe à la correction, si votre projet est solide et qu'on vous met faux sur une commande obscure, retentez avec le même code. Si segfault ou réel problème dans le code, le code devra être changer avant de retry, sinon vous êtes tomber sur un casse couille / minishell breaker. 99 | 100 | ## Disclaimer 101 | 102 | Notre projet n'est pas parfait mais on a réussi à le valider : $$ créer une boucle infinie, unset peut retirer la mauvaise variable, cd - / cd ~ n'est pas supporter. Les quotes imbriquée sont toute fois gérées ce qui permet d'avoir le dernier bonus pour la note de 101% WOW ! 103 | 104 | ## La bible 105 | 106 | [Cliquez c'est bien](https://docs.google.com/spreadsheets/d/1uJHQu0VPsjjBkR4hxOeCMEt3AOM1Hp_SmUzPFhAH-nA/edit#gid=0) 107 | --------------------------------------------------------------------------------