commit 2d894da46e7ef6e9a1f46ce1cc67efecf0f7efdc Author: lejulien Date: Fri Jan 9 15:48:36 2026 +0100 Initial commit diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..cedc378 --- /dev/null +++ b/Makefile @@ -0,0 +1,36 @@ +# **************************************************************************** # +# # +# ::: :::::::: # +# Makefile :+: :+: :+: # +# +:+ +:+ +:+ # +# By: lejulien +#+ +:+ +#+ # +# +#+#+#+#+#+ +#+ # +# Created: 2020/07/05 18:43:38 by lejulien #+# #+# # +# Updated: 2021/07/26 05:54:14 by lejulien ### ########.fr # +# # +# **************************************************************************** # + +SRCS = ./main.c + +SRCS_OBJS = ${SRCS:.c=.o} + +FLAGS = -Wall -Wextra -Werror -lpthread + +.c.o: + gcc -c $< -o $(<:.c=.o) + +NAME = macroshell + +$(NAME): $(SRCS_OBJS) + gcc -o $(NAME) $(SRCS_OBJS) $(FLAGS) + +clean: + rm -f $(SRCS_OBJS) + +fclean: clean + rm -f $(NAME) + +re: fclean $(NAME) + +.PHONY: clean fclean re + diff --git a/main.c b/main.c new file mode 100644 index 0000000..dd7a812 --- /dev/null +++ b/main.c @@ -0,0 +1,146 @@ +// +// Made by lejulien +// + +#include +#include +#include +#include + +int + ft_strlen(char *str) +{ + int i = 0; + while (str[i]) + i++; + return (i); +} + +int + ft_put_error(char *str) +{ + write(2, str, ft_strlen(str)); + return (1); +} + +char + *get_next_sep(char **av) +{ + int i = 0; + while (av[i] && strcmp(av[i], "|") != 0 && strcmp(av[i], ";") != 0) + i++; + return (av[i]); +} + +int + get_next_sep_pos(char **av) +{ + int i = 0; + while (av[i] && strcmp(av[i], "|") != 0 && strcmp(av[i], ";") != 0) + i++; + return (i); +} + +int + get_next_cmd(char **av) +{ + int i = 0; + while (av[i] && strcmp(av[i], "|") != 0 && strcmp(av[i], ";") != 0) + i++; + while (av[i] && (strcmp(av[i], "|") == 0 || strcmp(av[i], ";") == 0)) + i++; + return (i); +} + +void + do_cd(char **av) +{ + if (av[1] && strcmp(av[1], "|") != 0 && strcmp(av[1], ";") != 0) + { + if (av[2] == NULL || (av[2] && strcmp(av[2], ";") == 0)) + { + if (chdir(av[1]) < 0) + { + ft_put_error("error: cd: canot chang directory to "); + ft_put_error(av[1]); + ft_put_error("\n"); + } + } + else + ft_put_error("error: cd: bad arguments"); + } + else + ft_put_error("error: cd: bad arguments"); +} + +int pip[2]; +int prev_pip[2]; +void + exec(char **av, char **envp) +{ + pid_t pid; + int status; + int is_pipe = 0; + int ret; + char *tmp; + + if (get_next_sep(av) != NULL && strcmp(get_next_sep(av), "|") == 0) + { + if (pipe(pip)) + exit(ft_put_error("error: fatal\n")); + is_pipe = 1; + } + if ((pid = fork()) < 0) + exit(ft_put_error("error: fatal\n")); + if (pid == 0) + { + if (is_pipe) + { + if (dup2(pip[1], 1) < 0) + exit(ft_put_error("error: fatali\n")); + } + if (strcmp(av[-1], "|") == 0) + { + if (dup2(prev_pip[0], 0) < 0) + exit(ft_put_error("error: fatal\n")); + } + tmp = get_next_sep(av); + av[get_next_sep_pos(av)] = NULL; + if ((ret = execve(*av, av, envp)) == -1) + { + ft_put_error("error: cannot execute "); + ft_put_error(*av); + exit(ft_put_error("\n")); + } + av[get_next_sep_pos(av)] = tmp; + } + else + { + if (is_pipe) + close(pip[1]); + if (strcmp(av[-1], "|") == 0) + close(prev_pip[0]); + waitpid(pid, &status, 0); + } + prev_pip[0] = pip[0]; + prev_pip[1] = pip[1]; + is_pipe = 0; +} + +int + main(int ac, char **av, char **envp) +{ + av = &av[1]; + + while (*av) + { + if (strcmp(*av, "cd") == 0) + do_cd(av); + else + exec(av, envp); + av = &av[get_next_cmd(av)]; + } + return (0); +} + +// Made by lejulien@42