I try to understand the topic of redirection of child processes Standard Output to pipe, that parent process could read it and face with very strange behavior. In the example parent process fork 3 child processes that do simple file search and want to get the output. I receive only first result. What could be wrong with this example?
The code looks like this:
char * searches[] = {
".bashrc",
"NM34_x64.exe",
"blacklist.sh"
};
int fd[2];
if (pipe(fd) == -1) {
error("Can't create the pipe");
}
__pid_t pids[sizeof(searches)/sizeof(char*)];
for(int i = 0; i < sizeof(searches)/sizeof(char*); i++){
__pid_t pid = fork();
switch (pid) {
case -1 :
// ERROR CASE
error("Failed to make a child process");
break;
case 0 :
// CHILD CASE
// 1. Redirect Standard Output to pipe
dup2(fd[1], 1);
close(fd[0]);
// 2. Execute command
if (execl("/usr/bin/find", "/usr/bin/find", "/home", "-name", searches[i], NULL) == -1)
error("Failed to execute the command in the child process");
break;
default:
// PARENT CASE
printf("Created child process with pid %d\n", pid);
pids[i] = pid;
// 1. Wait for PID to finish
int status;
waitpid(pids[0], &status, 0);
if (status == -1)
error("Failed to wait the child PID");
printf("Process %d finish his work\n", pids[i]);
// 2. Redirect pipe to Standard Input
dup2(fd[0],0);
close(fd[1]);
// 3. Read Standard Input
char line[255];
while (fgets(line,255,stdin)) {
printf("%s", line);
}
break;
}
}
return 0;
Here is the output:
Created child process with pid 5063
Process 5063 finish his work
/home/user/.bashrc
Created child process with pid 5064
Process 5064 finish his work
Created child process with pid 5065
Process 5065 finish his work
close(fd[0]); dup2(fd[1], 1); close(fd[1])
. You are leaving file descriptors open. – William Pursellfd[1]
after waiting for the first child. When the second child is forked,fd[1]
is already closed and can't be written to. You can run this understrace -f
to watch the 2nd and 3rd child processes failing to write – Useless