Reputation: 9354
I have a perl script which emulates a tee command so I can get output written to the terminal and a log file. It works something like this (error checking &c omitted).
$pid = open(STDOUT, '-|');
# Above is perl magic that forks a process and sets up a pipe with the
# child's STDIN being one end of the pipe and the parent's STDOUT (in
# this case) being the other.
if ($pid == 0)
{
# Child.
# Open log file
while (<STDIN>)
{
# print to STDOUT and log file
}
#close log files
exit;
}
# parent
open STDERR, '>&STDOUT';
# do lots of system("...") calls
close STDERR;
close STDOUT;
exit;
This sometimes hangs, and invariably if you look at the processes and the stacks of said processes, the parent is hanging in one of the closes, waiting for the child to exit, whereas the child is hanging reading something from a file (which has to be STDIN, because there's no other file).
I'm rather at a loss as to how to deal with this. The problem seems to happen if you are running the program from a shell that isn't attached to a console - running the script in a normal shell works fine - and the only piece of code that has changed recently in that script is the addition of an open/close of a file just to touch it (and it's before the script gets to this 'tee' code).
Has anybody had problems like this before and/or have a suggestion as to what I can do to fix this? Thanks.
Upvotes: 2
Views: 1145
Reputation: 9354
Well, after some experimentation it seems that opening STDOUT
directly appears to be at least part of the reason. My code now reads like this:
$pid = open($handle, '|-');
if ($pid == 0)
{
# Child.
# Open log file
while (<STDIN>)
{
# print to STDOUT and log file
}
#close log files
exit;
}
# parent
open my $oldout, '>&STDOUT';
open my $olderr, '>&STDERR';
open STDOUT, '>&', $handle;
open STDERR, '>&', $handle;
# do lots of system("...") calls
open STDOUT, '>&', $oldout;
open STDERR, '>&', $olderr;
close $handle or die "Log child exited unexpectedly: $!\n";
exit;
which if nothing else, looks cleaner (but still messier than I'd like as I don't know what to do if any of those dups has an error). But I'm still unclear as to why opening and closing a handle much earlier in the code made such a difference to this bit.
Upvotes: 0