I have some code practicing forking processes(mocking the (|) in command line). However, the output is not the same every time. For example, for the input of ./pipe ls cat wc, it should be the same as ls | cat | wc . However, sometimes my code will output
Child with PID 12126 exited with status 0x0.
Child with PID 12127 exited with status 0x0.
7 7 52
Child with PID 12128 exited with status 0x0.
But sometimes it will also ouutput:
Makefile
pipe
#pipe.c#
pipe.c
pipe.o
README.md
test
Child with PID 12138 exited with status 0x0.
Child with PID 12139 exited with status 0x0.
0 0 0
Child with PID 12140 exited with status 0x0.
Which the first output is the correct one(compared with ls | cat | wc). I figured that by the second output, the output of the piping of the programs ls and cat is not being processed by wc. I am wondering what went wrong with my programs because seems like I set up the piping correctly - first program will take the input from stdin and output to the write end of the pipe and the last program will take the input from the read end of the pipe and output to stdout. Any inputs are appreciated.
Code(./pipe):
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
int fd[2];
if (pipe(fd) == -1) {
int err = errno;
perror("pipe");
return err;
}
pid_t pid[argc-1];
int n = argc;
if(argc <= 1){
return EINVAL;
}
for (int i = 1; i < argc; i++){
if ((pid[i] = fork()) == -1){
int err = errno;
perror("fork");
return err;
}else if(pid[i] == 0){
//open(fd[1]);
if(i == 1){
dup2(fd[1],STDOUT_FILENO);
if (execlp(argv[i], argv[i], NULL) == -1) {
printf("failed to search for the provided executed program. \n");
return errno;
}
}else if(i == argc-1){
dup2(fd[0],STDIN_FILENO);
if (execlp(argv[i], argv[i], NULL) == -1) {
printf("failed to search for the provided executed program. \n");
return errno;
}
}else{
dup2(fd[0],STDIN_FILENO);
dup2(fd[1],STDOUT_FILENO);
if (execlp(argv[i], argv[i], NULL) == -1) {
printf("failed to search for the provided executed program. \n");
return errno;
}
}
}
close(fd[1]);
}
int wstatus;
pid_t pids;
while (n > 1) {
pids = wait(&wstatus);
printf("Child with PID %ld exited with status 0x%x.\n", (long)pids, wstatus);
--n;
}
}