Front page | perl.perl5.porters |
Postings from February 2007
Re: system() behavior with $SIG{CHLD} = IGNORE (was Re: [perl #36976])
Thread Previous
|
Thread Next
From:
Alan Ferrency
Date:
February 5, 2007 12:50
Subject:
Re: system() behavior with $SIG{CHLD} = IGNORE (was Re: [perl #36976])
Message ID:
Pine.BSF.4.58.0702051523370.51169@smx.pair.com
> > the situation as described seems to me highly sub-optimal. Here's a note
> > to include in perlipc to document the situation:
> >
> >
> >
> > --- perlipc.pod.orig 2007-02-05 13:09:29.000000000 -0600
> > +++ perlipc.pod 2007-02-05 13:13:18.000000000 -0600
> > @@ -69,6 +69,10 @@
> > Calling C<wait()> with C<$SIG{CHLD}> set to C<'IGNORE'> usually returns
> > C<-1> on such platforms.
> >
> > +Perl program control flow on
> > +some BSD platforms will not return from C<system()> or backticks invocation
> > +until all child processes have ended, when C<$SIG{CHLD}> is set to C<'IGNORE'>.
> > +
>
> Isn't that exactly what the spec says it should do when it says in the
> wait/waidpid docs:
>
> "If the calling process has SA_NOCLDWAIT set or has SIGCHLD set to
> SIG_IGN, and the process has no unwaited for children that were
> transformed into zombie processes, the calling thread will block until
> all of the children of the process containing the calling thread
> terminate, and wait() and waitpid() will fail and set errno to
> [ECHILD]."
This may be so. However, it's not the whole story, due to the "no
unwaited for zombie children" clause.
The above snippet does not specify whether zombie children should be
created or not, when SIGCHLD is set to SIG_IGN (but SA_NOCLDWAIT is
unset). I believe this is the behavior that changed in FreeBSD.
In older FreeBSD, SIGCHLD was not enough to suppress zombies;
SA_NOCLDWAIT was also required for that. SIGCHLD only determined whether
signals were generated or not. The FreeBSD patch changes this, and makes
SIGCHLD also suppress zombie children, by reporting process exit to PID
1 instead of the parent process.
If SIGCHLD set to SIG_IGN allows a zombie to be created, as I believe it
did in the older FreeBSD, then waitpid() is still a valid request; and,
Perl works as I expected it to.
Other comments:
> http://www.unix.org/version2/sample/wait.html
- Reality doesn't always match the specifications you quoted. And, they
aren't the only specifications. If the behavior of all unix-like OSes
matched, then I think it's unlikely there would be any problem or
ambiguity here in the first place.
- According to the Fedora man page for sigaction(), POSIX specification
(B.3.3.1.3) disallows setting SIGCHLD to SIG_IGN at all. (I can't seem
to find the actual section text, unfortunately.) From a Perl
perspective, does this mean it's illegal for Perl to set SIGCHLD to
SIG_IGN, or that it's illegal for me to set $SIG{CHLD} = 'IGNORE' in
my Perl code?
- In the presence of arbitrary CPAN modules which may or may not modify
$SIG{CHLD} and/or make backtick or system() calls, it seems dangerous
to play with either of these in your own code. (In practice, the only
wounds we have so far are self-inflicted, but we haven't migrated
the bulk of our code onto adequately new FreeBSD platforms yet,
either.)
I won't complain if it is decided that "whatever the OS does is right,
even if it's different in different OSes." I just want to make sure this
is a well-informed, conscious decision and not a decision-by-default.
Thanks again for your time,
Alan Ferrency
pair Networks, Inc.
alan@pair.com
Thread Previous
|
Thread Next