system not returning correct return code.

O

omi

Please see following snip of the code:

$SIG{CHLD} = 'IGNORE';

my $ret1 = `ls jjsjds`;
my $ret = $?;


If we see the value of return code, that is not correctly set.
and this problem is coming because of the "$SIG{CHLD} = 'IGNORE';"
flag is set.
we if remove that everything is working fine, but that is requirement
of the code, since we are using this code with perl socket server
code, which should not have to create "defunct" processes.

Please suggest solution on this, where both setting a flag and getting
output with system can hold in the code.

Thanks,
OMkar
 
O

omi

Please see following snip of the code:

$SIG{CHLD} = 'IGNORE';

my $ret1 = `ls jjsjds`;
my $ret = $?;

If we see the value of return code, that is not correctly set.
and this problem is coming because of the "$SIG{CHLD} = 'IGNORE';"
flag is set.
we if remove that everything is working fine, but that is requirement
of the code, since we are using this code with perl socket server
code, which should not have to create "defunct" processes.

Please suggest solution on this, where both setting a flag and getting
output with system can hold in the code.

Thanks,
OMkar

Moreover this code perfectly work, if server [which includes this
snip] is running on the Windows BOX.
 
R

RedGrittyBrick

omi said:
Please see following snip of the code:

$SIG{CHLD} = 'IGNORE';

my $ret1 = `ls jjsjds`;
my $ret = $?;

If we see the value of return code, that is not correctly set.
and this problem is coming because of the "$SIG{CHLD} = 'IGNORE';"
flag is set.
we if remove that everything is working fine, but that is requirement
of the code, since we are using this code with perl socket server
code, which should not have to create "defunct" processes.

Please suggest solution on this, where both setting a flag and getting
output with system can hold in the code.

Thanks,
OMkar

Moreover this code perfectly work, if server [which includes this
snip] is running on the Windows BOX.

perldoc perlipc:

"On most Unix platforms, the CHLD (sometimes also known as CLD) signal
has special behavior with respect to a value of 'IGNORE'. ... Calling
wait() with $SIG{CHLD} set to 'IGNORE' usually returns -1 on such
platforms."


perldoc perlvar

"$? ... is just the 16-bit status word returned by the wait() system call"


Since SIGCHLD is "Notification to parent on child stop or exit" I'm not
entirely surprised that ignoring it leads to the parent not knowing the
child's exit code.

Does SIGCHLD mean anything on Windows? Presumably the mechanism for
communicating exit codes might differ?
 
E

Eric Pozharski

Yes. From the $? entry in perldoc perlvar:

If you have installed a signal handler for "SIGCHLD", the value
of $? will usually be wrong outside that handler.

On systems that honour "IGNORE" for SIGCHLD, it counts as a signal
handler. So don't do that.

I would like that quote to be verified. Look, right now I have a big
deal of coding (testing mostly) about childs, pipes, etc. While
experimenting I've set C<$SIG{CHLD} = sub { warn $? }>. And I was
surprised to see C<0> as the inside value. I<$?> is set, and has proper
value, but only after B<waitpid>. Wouldn't like some kind perlist with
deeper insight comment on this?

*CUT*
 
X

Xho Jingleheimerschmidt

omi said:
Please see following snip of the code:

$SIG{CHLD} = 'IGNORE';

my $ret1 = `ls jjsjds`;
my $ret = $?;


If we see the value of return code, that is not correctly set.
and this problem is coming because of the "$SIG{CHLD} = 'IGNORE';"
flag is set.
we if remove that everything is working fine, but that is requirement
of the code, since we are using this code with perl socket server
code, which should not have to create "defunct" processes.

Please suggest solution on this, where both setting a flag and getting
output with system can hold in the code.

I'd probably make it double fork when it does the (non-backtick) forks,
so zombies are cleaned up by the OS.

Or you could put a { local $SIG{CHLD}; .... } around the backticks, then
use waitpid with the no wait option to clean up anything that exited in
the mean time.

Xho
 
X

Xho Jingleheimerschmidt

Eric said:
I would like that quote to be verified.

Which aspect?
Look, right now I have a big
deal of coding (testing mostly) about childs, pipes, etc. While
experimenting I've set C<$SIG{CHLD} = sub { warn $? }>. And I was
surprised to see C<0> as the inside value. I<$?> is set, and has proper
value, but only after B<waitpid>. Wouldn't like some kind perlist with
deeper insight comment on this?

$? is only set after the thing that sets it, yes. Being inside the
handler doesn't automatically cause $? to get set, it just means that
the sig handler that you are already in won't get in the way of it being
set, like it would if a sig handler exists but were you not in the sig
handler. (Which is not to say that other things couldn't get in the way
of $? being set correctly when inside a sig handler, just not the sig
handle itself.)


Xho
 
E

Eric Pozharski

Which aspect?

"If you have ... that handler."
$? is only set after the thing that sets it, yes. Being inside the
handler doesn't automatically cause $? to get set, it just means that
the sig handler that you are already in won't get in the way of it being
set, like it would if a sig handler exists but were you not in the sig
handler. (Which is not to say that other things couldn't get in the way
of $? being set correctly when inside a sig handler, just not the sig
handle itself.)

(that seems my english is a way bad still) Did I got that right? The
perldoc wants to say that even if I'm in B<waitpid> and I get SIGCHLD
then the I<$?> still would be unset?

p.s. Look, I can experimentally get what's going on, I just want to get
what perldoc wants to say.
 
E

Eric Pozharski

No. What the perldoc is saying is

If you have a SIGCHLD handler, then any code *outside* that handler
will not see the correct value for $?.

That is:

#!/usr/bin/perl

# $? is useless here.

$SIG{CHLD} = sub {

# $? is still useless here, because nothing inside this handler
# has set it yet.

waitpid ...; # or something else that sets $?

# $? has the correct value here.
};

# $? is useless again here.

One consequence of this is that if you have $SIG{CHLD} = "IGNORE", $? is
*never* useful, since there is none of your code running inside the
handler.

Thanks, I see the light now.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,045
Latest member
DRCM

Latest Threads

Top