Link to home
Start Free TrialLog in
Avatar of AgentFriday
AgentFridayFlag for United States of America

asked on

Output from child process goes to "bit bucket" (using printf)

I'm writing a program in C++ for linux platform.  The program uses fork() to run a certain task as a child process.

When I place printf() calls in the child process, that output never shows up anywhere.  From everything I've found on the web, it seems that stdin and stdout are supposed to work the same in the child process as in the parent, and the child should inherit the parent's stdin, stdout, and stderr.  Doesn't printf go to stdout by default?  I've found that I can output messages using sprinf() / write(STDOUT_FILENO,...), but this is somewhat inconvenient.  More importantly, it's a sign that there's something I'm not getting about how this is supposed to work.

Where is the printf output is going, and how would I make it work from within a child process?  (I'm a veteran programmer, but new to linux.)

if (fork() == 0)
{
   // In child process

   printf( "This message goes nowhere\n");
   
   char buf[200] = "This message goes to the console\n";
   write( STDOUT_FILENO, buf, strlen(buf));
   _exit(0);
}


Thanks!
ASKER CERTIFIED SOLUTION
Avatar of sunnycoder
sunnycoder
Flag of India image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of AgentFriday

ASKER

> Is there a reason you're using _exit() and not exit()?

All the documentation I've read says that you should use _exit() to end a child process, not exit().
>  try flushing the buffer

Actually, I did discover fflush(stdout) yesterday... and it does seem to cause printf() output to go to the screen.  I had heard that printf output was line buffered, but the level of buffering and out-of-order output I am seeing is far more than 1 line at a time.  I changed the child process to only use write(), since that works.  I also added a printf() message just before and after the child process gets created.  The child process output (from write()) shows up 20 or 30 lines _before_ the pre-child printf().

> > that output never shows up anywhere
> Double check that ...
I did.  It doesn't show up anywhere... until I add the fflush() before the child calls _exit().  Apparently, unlike exit, _exit will NOT flush the stdio buffers.

I had given up on fflush() earlier, since I tried it with the descriptor (STDOUT_FILENO), and it wants a FILE*.  Didn't know stdout worked on the same file.  Also got side-tracked on sync(), which supposed flushes all the buffers, but doesn't seem to apply to printf output.

I think this just about takes care of this one...  I have a few more reality checks to do to make sure things are working right.

Can you suggest a good reference for the C standard library that spells out some of the caveats?  The information I've found by googling has been sparse and incomplete.

Thanks!
CONCLUSIONS:

  - printf() output to stdout is buffered, while write() is not.
  - Piping output to anoth app (such as with myprog | sort) increases the amount of buffering to more than one line at a time.
  - _exit() does not flush the printf output, but discards it.  Call fflush(stdout) before _exit() when ending a child process
  - If you do not call fflush(stdout) just before spawning the child (using fork()), then the child will get a copy of all the buffered output of the parent, causing a certain amount of duplicated output.

I would not have run into many of these problems if I had not been piping the output of the program through another one, since the printf output would have been flushed after each line.