Reproduce the shell pipe command

Viewed 53

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

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);
}

My main takes care of:

  • split the argv[2] and the argv[3] with a space as delimiter, to keep only the command "ls" or "wc", and not the options
  • classic stuff like pipe(), fork(), execve() …
int main(int argc, char *argv[], char **envp)
{
    (void)argc;

    pid_t   pid1;
    pid_t   pid2;
    int     fd[2];
    char    **cmd_and_options1;
    char    **cmd_and_options2;
    char    *path_ultime1;
    char    *path_ultime2;

    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)
        return (1);

    pid1 = fork();

    if (pid1 == -1)
        return (1);

    if (pid1 == 0) // First child
    {
        dup2(fd[1], STDOUT_FILENO);
        close(fd[0]);
        close(fd[1]);
        execve(path_ultime1, cmd_and_options1, envp);
    }

    pid2 = fork();
    
    if (pid2 == -1)
        return (1);

    if (pid2 == 0) // Second child
    {
        dup2(fd[0], STDIN_FILENO);
        close(fd[0]);
        close(fd[1]);
        execve(path_ultime2, cmd_and_options2, envp);
    }

    close(fd[0]);
    close(fd[1]);

    waitpid(pid1, NULL, 0);
    waitpid(pid2, NULL, 0);

    return (0);
}

A friend told me that I lacked the management of the input and output file (argv[1] and argv[4]) that the operator will enter but I don't really understand what that means.

I know I have to use open() somewhere...

Can you give me some clues?

0 Answers
Related