fng has asked for the wisdom of the Perl Monks concerning the following question:

I have a daemon that closes STDOUT:
fork ...etc close(STDOUT); ...etc setsid();
Later on, my daemon wants to fork itself to do some background work, and have the worker process notify the parent via a "Safe Pipe Open" , so I have something like:
$kidpid=open($fh,"-|"); #err handling omitted if ($kidpid) { while(<$fh>) {print;} close($fh); # implicit waitpid } else { print "hello parent\n"; exit; }
but i never see the output in the parent b/c the child inherits a closed STDOUT. What is the right way to both close STDOUT for the parent's daemonization sake, but still use the nice open($fh,"-|") to allow the code to talk?

Replies are listed 'Best First'.
Re: right way to reopen STDOUT in a child
by almut (Canon) on May 24, 2007 at 00:43 UTC

    You could save/dup STDOUT before closing it, and then reopen it when required:

    open my $saved_stdout, ">&STDOUT"; close STDOUT; # ... open STDOUT, ">&", $saved_stdout or die "can't reopen STDOUT: $!"; my $kidpid = open my $fh, "-|"; # ...

    Note that you need to reopen STDOUT before doing the forking pipe open (i.e. not in the child), otherwise you'd get in conflict with Perl implicitly redirecting STDOUT to the pipe...

    Update: actually, you could also just reopen it to anything, say /dev/null (then you wouldn't need to save it first). As STDOUT is being redirected anyway in the child, it doesn't matter much... as long as it's open when you open the pipe.