I have a school project which consists of reproducing the shell pipe command between two commands that the operator will choose as it pleases.
./pipex infile "ls -l" "wc -l" outfile
should be equivalent to
< infile ls -l | wc -l > outfile
Here is my way of doing it:
void first_child(char **argv, char **envp, int pipefd[2], int fd[2])
{
char **cmd_and_options1;
char *path_ultime1;
int pid1;
pipefd[0] = open(argv[1], O_RDONLY);
pid1 = fork();
if (pid1 == -1)
error();
if (pid1 == 0)
{
dup2(fd[1], STDOUT_FILENO);
dup2(pipefd[0], STDIN_FILENO);
close(pipefd[0]);
close(fd[1]);
execve(path_ultime1, cmd_and_options1, envp);
}
}
void second_child(char **argv, char **envp, int pipefd[2], int fd[2])
{
char **cmd_and_options2;
char *path_ultime2;
int pid2;
pipefd[1] = open(argv[4], O_CREAT | O_WRONLY | O_TRUNC, 0777);
pid2 = fork();
if (pid2 == -1)
error();
if (pid2 == 0)
{
dup2(fd[0], STDIN_FILENO);
dup2(pipefd[1], STDOUT_FILENO);
close(pipefd[1]);
close(fd[0]);
execve(path_ultime2, cmd_and_options2, envp);
}
}
int main(int argc, char *argv[], char **envp)
{
int pipefd[2];
int fd[2];
char **cmd_and_options1;
char **cmd_and_options2;
char *path_ultime1;
char *path_ultime2;
(void)argc;
cmd_and_options1 = ft_split(argv[2], ' ');
cmd_and_options2 = ft_split(argv[3], ' ');
path_ultime1 = find_path(cmd_and_options1[0], envp);
path_ultime2 = find_path(cmd_and_options2[0], envp);
if (pipe(fd) == -1)
error();
first_child(&argv[1], envp, &pipefd[0], &fd[0]);
second_child(&argv[4], envp, &pipefd[1], &fd[1]);
close(pipefd[0]);
close(pipefd[1]);
close(fd[0]);
close(fd[1]);
waitpid(-1, NULL, 0);
waitpid(-1, NULL, 0);
return (0);
}
Roles of my find_path function:
- extract the contents of PATH from the envp
- use split() to delimit the paths according to ":" and store them in a double pointer
- use strjoin() to append a "/" to the end of each path, and add the user command
- test each path with access() then return the valid path
char *find_path(char *cmd, char **envp)
{
char **array_of_paths;
char *path_ultime;
int i;
char *temp;
i = 0;
while (ft_strnstr(envp[i], "PATH=", 5) == 0)
i++;
array_of_paths = ft_split(envp[i] + 5, ':');
i = 0;
while (array_of_paths[i])
{
temp = ft_strjoin(array_of_paths[i], "/");
path_ultime = ft_strjoin(temp, cmd);
free(temp);
if (access(path_ultime, F_OK | X_OK) == 0)
return (path_ultime);
i++;
}
return (0);
}
When I put all my code in the main(), my program worked. But when I try to separate it into functions it doesn't work anymore and I don't understand what the problem is.