147 lines
2.3 KiB
C
147 lines
2.3 KiB
C
//
|
|
// Made by lejulien
|
|
//
|
|
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
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
|