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

I keep getting the following runtime warning, before reaping the first child process:
Argument "CHLD" isn't numeric in subroutine entry at /usr/lib/perl5/5. +6.0/i386-linux/POSIX.pm line 38.
There seems to be no side effects. The code that causes it (if I'm not mistaken) is as follows:
use POSIX qw( :sys_wait_h ); $SIG{CHLD} = \&REAPER; sub REAPER { my $kid; while (($kid = waitpid (-1, &WNOHANG)) > 0) { if (exists $Children{$kid}) { $::logger->info ("Process: $Children{$kid} rea +ped"); $children --; delete $Children{$kid}; } } $SIG{CHLD} = \&REAPER; }
Any ideas out there?

Replies are listed 'Best First'.
(tye)Re: SIGCHLD not properly defined
by tye (Sage) on Dec 21, 2000 at 22:06 UTC

    When you get an error with line 38 of POSIX.pm, it often helps for us to be able to see line 38 of POSIX.pm. Well, you got lucky in that I felt like looking and my POSIX.pm is probably close enough to yours that I figured out the problem.

    Don't write &WNOHANG when you should be writing WNOHANG() or, (if you use strict.pm, which you always do, right?) just WNOHANG.

    See (tye)Re: A question of style for info about what &WNOHANG does. It causes two minor problems here. First, it disables the prototype so that this can't be made a compile-time constant (if POSIX.pm ever gets fixed to declare constants correctly). Second, it reuses @_ which POSIX.pm isn't smart enough to ignore since it was written back when "constants" still had the option of taking a single integer argument for some reason that no one can now explain.

    The warning has to do with the code at line 38 passing the first argument of @_ to XS code that looks up the value for the constant WNOHANG. Since it just happens that your $_[0] isn't a number, that XS routine wants a number, and you (correctly) have warnings enabled, the result is a warning.

    You might also check the "Specifying constants in your Perl code" section of the Win32::TieRegistry manual for more information. Heck, I'll just include it here (even though some of it doesn't really apply to this case):

    Specifying constants in your Perl code

    This module was written with a strong emphasis on the convenience of the module user. Therefore, most places where you can specify a constant like REG_SZ() also allow you to specify a string containing the name of the constant, "REG_SZ". This is convenient because you may not have imported that symbolic constant.

    Perl also emphasizes programmer convenience so the code REG_SZ can be used to mean REG_SZ() or "REG_SZ" or be illegal. Note that using &REG_SZ (as we've seen in much Win32 Perl code) is not a good idea since it passes the current @_ to the constant() routine of the module which, at the least, can give you a warning under "-w".

    Although greatly a matter of style, the "safest" practice is probably to specifically list all constants in the use Win32::TieRegistry statement, specify use strict (or at least use strict qw(subs)), and use bare constant names when you want the numeric value. This will detect mispelled constant names at compile time.

    use strict; my $Registry; use Win32::TieRegistry 0.20 ( TiedRef => \$Registry, Delimiter => "/", ArrayValues => 1, SplitMultis => 1, AllowLoad => 1, qw( REG_SZ REG_EXPAND_SZ REG_DWORD REG_BINARY REG_MULTI_SZ KEY_READ KEY_WRITE KEY_ALL_ACCESS ), ); $Registry->{"LMachine/Software/FooCorp/"}= { "FooWriter/" => { "/Fonts" => [ ["Times","Courier"], REG_MULTI_SZ ], "/WindowSize" => [ pack("LL",24,80), REG_BINARY ], "/TaskBarIcon" => [ "0x0001", REG_DWORD ], }, } or die "Can't create Software/FooCorp/: $^E\n";

    If you don't want to use strict qw(subs), the second safest practice is similar to the above but use the REG_SZ() form for constants when possible and quoted constant names when required. Note that qw() is a form of quoting.

    use Win32::TieRegistry 0.20 qw( TiedRef $Registry Delimiter / ArrayValues 1 SplitMultis 1 AllowLoad 1 REG_SZ REG_EXPAND_SZ REG_DWORD REG_BINARY REG_MULTI_SZ KEY_READ KEY_WRITE KEY_ALL_ACCESS ); $Registry->{"LMachine/Software/FooCorp/"}= { "FooWriter/" => { "/Fonts" => [ ["Times","Courier"], REG_MULTI_SZ() ], "/WindowSize" => [ pack("LL",24,80), REG_BINARY() ], "/TaskBarIcon" => [ "0x0001", REG_DWORD() ], }, } or die "Can't create Software/FooCorp/: $^E\n";

    The examples in this document mostly use quoted constant names ("REG_SZ") since that works regardless of which constants you imported and whether or not you have use strict in your script. It is not the best choice for you to use for real scripts (vs. examples) because it is less efficient and is not supported by most other similar modules.

    (End quote)

            - tye (but my friends call me "Tye")
Re: SIGCHLD not properly defined
by cat2014 (Monk) on Dec 21, 2000 at 17:57 UTC
    If you're positive that the warning has no real effect & you just don't want to see it being printed, you can always use a hack like this:

    {local $^W=0; #stuff that throws the warning here }

    of course, it's always better to figure out why the warning is being thrown than just suppressing it because you don't want to see it, and there's probably a much better way to deal with this.

    You migh want to check this out: Switch off warning for UNIVERSAL::AUTOLOAD

Re: SIGCHLD not properly defined
by merlyn (Sage) on Dec 21, 2000 at 20:00 UTC
    One idea is not to use the unreliable SIGCHLD. I have some code in a few of my columns that simply polls at opportune points in the top level loop looking for any kids that have died on the previous round.

    With your code (which you dutifully copied from someone who also didn't have this same clue), you will crash sooner or later, or miss a kid until the next kid dies. Just take your while loop out and put it into the top loop of your program, and ignore the "signal handler" concept entirely. Or use Event or POE, which have taken this out into the proper realm.

    -- Randal L. Schwartz, Perl hacker

Re: SIGCHLD not properly defined
by ChOas (Curate) on Dec 21, 2000 at 17:50 UTC
    Dunno if it helps, but: CHLD is an acronym for(sorry guys,
    I'm not English, don't get me on this one) (analogue to) CLD.
    I remember one of the two being POSIX and the other ...
    Hmmm how do I say this... 'not' ? ... 'different' ?

    Same behaviour when you declare it like this ?
    $SIG{CLD} = \&REAPER;