Reproduce the pipe command

Viewed 30

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.

0 Answers
Related