We have such Perl code:
if (fork==0) {
# in child process close STDOUT и STDERR, for the parent process didn't wait a response from the child and finished quickly
close(STDOUT);
if (!defined fileno(CGI::Carp::SAVEERR)) {close(STDERR)} # TODO learn to close redirected STDERR
else { close(CGI::Carp::SAVEERR); }
# ...
}
We had the problem described in Perl: STDOUT reopened as FH only for input - To solve it I was recommended not to close STDOUT and instead to reopen it as '/dev/null'.
Should I replace in the above code ALL calls of close
with open
/dev/null
? or only close(STDOUT)
and close(STDERR)
?
Won't this replacement break "parent process didn't wait a response from the child and finished quickly"?
There seem to be a few things to clear up.
The parent does need to reap its child processes (wait
or waitpid
on SIGCHLD
), if that is what you mean by "wait a response from the child". However, if parent exits first the child is re-parented by init
and all is well. This is not affected by the child's closing (reopening) of its streams.
As for "closing" the streams, they should be redirected (reopened) to /dev/null
instead. See, for instance, Complete disassociation of child from parent in perlipc for how the streams are shut down for daemonization, and an answer in the post linked in the question.
Finally, it appears that STDERR
was saved and redirected to a file in CGI::Carp
. Whether you now want to close or restore it is up to intent/design. If the log to which STDERR
is going and the stream itself should be closed you should first close the log, on what the module should restore STDERR
(check please), and then redirect the stream to /dev/null
.
Altogether, perhaps
my $pid = fork // die "Can't fork: $!"; #/
if ($pid == 0)
{
open STDOUT, '>', '/dev/null' or die "Can't write to /dev/null: $!";
if (defined(fileno(CGI::Carp::SAVEERR))
{
close $fh_log_to_which_STDERR_was_redirected or die $!;
close CGI::Carp::SAVEERR or die $!;
}
open STDERR, '>', '/dev/null' or die "Can't write to /dev/null: $!";
...
}
but check your CGI::Carp
handling since there is no information on that in the question.
Context of fork
isn't given but consider IPC::Run3 or IPC::Run to launch and manage processes.