I was experimenting with fork()
and re-direction to check whether the re-directions done in the parent apply to the child too. I wrote the following simple program
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
int main ()
{
freopen( "error.txt", "w+t", stdout ); // From now on, stdout = error.txt
printf (" ERROR! WHY DONT U UNDERSTAND?\n");
if ( fork() == 0 )
{
printf(" I AM CHILD\n");
exit(0);
}
else-
{
printf (" EITHER I AM A PARENT OR SOMETHING GOT SCREWED\n");
}
return 0;
}
The output ( error.txt
) I got is
ERROR! WHY DONT U UNDERSTAND?
EITHER I AM A PARENT OR SOMETHING GOT SCREWED
ERROR! WHY DONT U UNDERSTAND?
I AM CHILD
Surprisingly, ERROR! WHY DONT U UNDERSTAND?
is printing twice even though it appears much before the fork()
is called and should only be printed once by the parent.
Can anyone shed some light on this?
Because both the parent and child process are outputting their results.
Normally Nagios will fork() twice when it executes host and service checks. This is done to (1) ensure a high level of resistance against plugins that go awry and segfault and (2) make the OS deal with cleaning up the grandchild process once it exits.
fork() && fork() || fork(); printf will go a total of 5 times.
Both sides of the fork inherit the unflushed buffer, so when each side of the fork hits the return statement and ends, it gets flushed twice. Before you fork, you should fflush(stdout); which will flush the buffer so that the child doesn't inherit it.
Since after reopen
the stream is non-interactive, it's fully buffered and doesn't flush on '\n'
. Before fork
is called the buffer still contains the message, and after fork
this buffered message was duplicated (because both processes got their own copies of stdout
) and then flushed by both the parent and the child. See part 7.19.3 of C standard.
You can avoid such behavior by calling fflush
just before fork
.
It's because of buffering. Do a fflush
right after printf
.
Both processes end up with the same copy of stdio
's internal stuff and both proceed to flush it at exit
. You might also prevent it from happening if you call _exit
in the child.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With