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?