Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

No child processes

by Jonathan (Curate)
on Sep 13, 2002 at 10:24 UTC ( [id://197500]=perlquestion: print w/replies, xml ) Need Help??

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

I have a process that runs as a daemon forking off child processes when requests come in. To control zombies I have the standard
# Install signal handler for child processes $SIG{'CHLD'} = sub { while (waitpid(-1,WNOHANG) > 0) {} };
However, the child processes then have to make a system call and I need to trap the exit code eg..
my $res = system $cmd, $arg; unless ($res == 0) { ... }
$? now contains -1 and $! 'No child processes', I understand that this is because of my $SIG{'CHLD'} handler. But how can I get the true exit code and message? I've tried 'local $SIG{'CHLD'} = '' prior to the sys call and that seems to work but looks very clumsy.

What is the best way to get at the exit code?

Replies are listed 'Best First'.
Re: No child processes
by RMGir (Prior) on Sep 13, 2002 at 11:29 UTC
    If local $SIG{CHLD} is clumsy, why not hide it?
    # or whatever name you like, my_system, systemx, # safe_system, sig_system... sub wrapped_system { # Use local signal handler so global handler # does not result in bad values in $? and $! local $SIG{CHLD}=''; return system @_; }
    If you run into this problem in more than one place in your code, moving this into a subroutine would make all that much more sense.
    --
    Mike
Re: No child processes
by slife (Scribe) on Sep 13, 2002 at 13:22 UTC

    If you are really determined that you don't want to un-set your CHLD signal handler, you need to bear in mind two things:

    i) your 'standard' handler is throwing away the child pid and return code values and
    ii) system() is, in effect, shorthand for the traditional UNIX fork/exec/wait idiom.

    You may, therefore, want to set the signal handler to do something useful like:
    my %pid; $SIG{CHLD} = sub { while((my $kid = waitpid(-1,WNOHANG))>0 ) { warn "PID $kid returned $?"; } };

    (this is based Lincoln Stein's 'Network Programming with Perl' p305).
    .....

    and replace $res = system @args;
    with exec @args;

    Though, you will need to consider the usual caveats regarding signal handlers in perls prior to 5.8.0 ...

Re: No child processes
by PodMaster (Abbot) on Sep 13, 2002 at 11:14 UTC
    Why is local $SIG{CHLD}; clumsy?

    ____________________________________________________
    ** The Third rule of perl club is a statement of fact: pod is sexy.

Re: No child processes
by Jonathan (Curate) on Sep 13, 2002 at 13:36 UTC
    Thanks for all replies - duly up-voted.
    I raised the question because I felt I'd missed a subtle finesse. Guess I haven't apologies extended.
Re: No child processes
by Anonymous Monk on Jun 07, 2018 at 15:33 UTC
    local $SIG{CHLD} = sub { local ($!, $?); while (waitpid(-1, WNOHANG) > 0) {} };
    seems to fix this issue

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://197500]
Approved by claree0
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (8)
As of 2024-04-19 09:38 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found