Search code examples
perlfile-iofilehandlezombie-process

Perl: creating zombies through open() without close()


Here is the problem: I've a daemon which get requests from a client, executes a function (from some module) due to the request and returns an answer to the client. After the fork() I close STDIN,STDOUT and STDERR. One function is to check dmesg. For this I get the dmesg output through open(DMESG, "/bin/dmesg |"). I don't close this fh after reading from it, because I thought that it would close automatically after the function finished. But this doesn't happen and I get a zombie for each call of dmesg.

On How can I reinitialize Perl's STDIN/STDOUT/STDERR? I found "The problem with closing STDOUT instead of reopening is that if you open other files, they might get fd 0,1 or 2 - preventing you from reopening STDOUT in the future." by jmanning2k And I think that it has something to do with it but I don't really get it. I hope that someone can explain it to me.

I know that I can avoid the the problem e.g. by calling dmesg via qx(); or simply closing the fh but I want to understand where the zombies are coming from.


Solution

  • The form

    open DMESG, "/bin/dmesg|";
    

    Opens the pipe and assigns it to the dynamically scoped variable DMESG. Dynamically scoped variables actually live "forever" in Perl, being saved as necessary whenever a local is seen.

    If you instead use the form

    open my $dmesg, "/bin/dmesg|";
    

    The lexical filehandle variable $dmesg will be closed on scope exit, assuming there's no other reason to keep it alive (i.e. it's not passed back or otherwise stored in a global variable).