More on 5.8 and signals

Ask a Question related to PERL Miscellaneous, Design and Development.

  1. #1

    Default More on 5.8 and signals

    Hi,

    I am pretty desparate to get this working, and if anyone wants to earn
    some cash helping me fix things PLEASE call me at 250 655-9513.

    Thanks to a guy on comp.lang.perl.misc I know that there is a change in
    how signals are handled, they call it deferred signal handling because
    Perl now is suppose to wait until the Interpeter is in a safe state. As
    I understand it this might avoid some things like core dumps or other
    errors related to dieing while trying to do something besides dieing.

    The thing is somehow this ends up killing off my parent process, just
    like in this post:

    [url]http://www.mail-archive.com/beginners@perl.org/msg43989.html[/url]

    So this is happening to me as well, however the guy in the above example
    had his problem solved by using Errno and looking for EINTR if that
    error is raised then catch it and move on. This isn't working for me, or
    else I don't know how to use the advice I was given about it.

    I did get one maybe helpfull thing from my log:

    Erro was %! --------
    ../franken_socket.pl 8607: got - CHLD
    at Tue Sep 16 02:17:42 2003
    I got forked
    ../franken_socket.pl 8599: begat 8607 at Tue Sep 16 02:17:40 2003
    begat 8607
    ../franken_socket.pl 8599: got - CHLD
    at Tue Sep 16 02:17:54 2003
    ../franken_socket.pl 8599: main 8607 -- reaped 1 at Tue Sep 16 02:17:54
    2003
    reaped 1Erro was No child processes %! --------

    So it looks like the parent got killed on that error "No child process"
    This code works just fine on 5.6 since it is about 150% from examples :)
    The above is the result of connecting, doing a "who", and doing "dienow"
    to test the alarm.

    I also found this:

    [url]http://archive.develooper.com/macosx@perl.org/msg03022.html[/url]

    Which totaly describes my problem as well, but shows it happening with
    perl 5.8.1..

    >I'd imagine that your accept() isn't being restarted. How does it work
    >if you change the loop to look like this?
    > use Errno;
    > while (1) {
    > my $client = $server->accept or do {
    > next if $!{EINTR};
    > last;
    > };
    > spawn(\&function, "whatever");
    > }
    #!/usr/bin/perl -w

    ## new frankenstein!

    use strict;
    use POSIX ();
    use POSIX 'WNOHANG';
    use Errno;
    use IO::Socket;
    use FindBin ();
    use File::Basename ();
    use File::Spec::Functions;
    use Net::hostent;
    use Carp;


    $|=1;
    my $pid;

    open (DIED, ">>/var/log/daemon_log") or warn "$!";
    sub logmsg { print DIED "$0 $$: @_ at ", scalar localtime, "\n" }

    my $listen_socket = IO::Socket::INET->new(LocalPort => 1081,
    LocalAddr => '127.0.0.1',
    Proto => 'tcp',
    Listen => SOMAXCONN,
    Reuse => 1 )
    or die "can make a tcp server on port 1080 $!";


    # make the daemon cross-platform, so exec always calls the script
    # itself with the right path, no matter how the script was invoked.
    my $script = File::Basename::basename($0);
    my $SELF = catfile $FindBin::Bin, $script;
    # POSIX unmasks the sigprocmask properly
    my $sigset = POSIX::SigSet->new();
    my $action = POSIX::SigAction->new('sigHUP_handler',
    $sigset,
    &POSIX::SA_NODEFER);
    my $action_alrm = POSIX::SigAction->new('sigALRM_handler',
    $sigset,
    &POSIX::SA_NODEFER);


    POSIX::sigaction(&POSIX::SIGHUP, $action);
    POSIX::sigaction(&POSIX::SIGALRM, $action_alrm);

    sub sigHUP_handler {
    print "got SIGHUP\n";
    exec($SELF, @ARGV) or die "Couldn't restart: $!\n";
    }
    sub sigALRM_handler {
    print "got ALARM timeout\n";

    }

    $SIG{CHLD} = \&REAPER_NEW;

    sub REAPER {
    $SIG{CHLD} = \&REAPER; # loathe sysV
    my $waitedpid = wait;
    logmsg "reaped $waitedpid" . ($? ? " with exit $?" : '');
    }

    sub REAPER_NEW {
    logmsg "got - @_\n";
    my $wpid = undef;
    while ($wpid = waitpid(-1,WNOHANG)>0) {

    logmsg "main $pid -- reaped $wpid" . ($? ? " with exit
    $?" : '')
    ;
    print DIED "reaped $wpid" . ($? ? " with exit $?" : '');

    }
    }


    print "PID: $$\n";
    print "ARGV: @ARGV\n";
    print "[Server $0 accepting clients]\n";

    #while (my $connection = $listen_socket->accept()) {
    while (1) {
    my $connection = $listen_socket->accept() or do {
    next if $!{EINTR};
    last;
    };

    print DIED "Erro was $! %! --------\n";
    $connection->autoflush(1); ## missing seemed to cause client problem,
    but not telnet

    if (!defined($pid = fork)) {
    logmsg "cannot fork: $!";

    }elsif ($pid) {
    logmsg "begat $pid";
    print DIED "begat $pid\n";
    }else{
    # else i'm the child -- go spawn
    print $connection "Command?";

    while ( <$connection> ){

    my $return_value = undef;

    if (/quit|exit/i) {
    last; }
    elsif (/closeme/i )
    {$connection->close(); }
    elsif (/date|time/i) { printf $connection "%s\n",
    scalar localtime; }
    elsif (/who/i ) { print $connection `who
    2>&1`;}
    elsif (/dienow/i ) { alarm 2; }
    elsif (/dieT/i ) {
    die; }



    #REAPER_NEW($pid) if $return_value;

    print $connection "Command?";

    print DIED "I got forked\n";
    }
    exit(0);

    #STDIN->fdopen($connection,"r") || die "can't dup client to
    stdin";
    #STDOUT->fdopen($connection,"w") || die "can't dup client to
    stdout"
    ;
    #STDERR->fdopen($connection,"w") || die "can't dup stdout to
    stderr";

    ### FORKed code here..

    } ## end while <$connection>

    } ## end else

    close ($listen_socket);
    Eric Frazier Guest

  2. Similar Questions and Discussions

    1. Net::Telnet, fork and signals..
      Hello, I've been trying to figure this out for the past couple of days but am hitting a wall. I am using Net::Telnet 3.03 with a modification...
    2. Signals and Net::Telnet::command
      Hello, I had a question regarding signals and Net::Telnet and was wondering if someone had an insight into it. My script looks like:...
    3. Usable signals for own needs
      On 22 Jul 2003, Peteris Krumins wrote: Not portably. BTW, SIGHUP is the usual "reload config" signal. Maybe you need to rethink your...
    4. initialize all signals to SIG_DFL
      is there a way to initialize all signals to SIG_DFL? the only way i can think of is to loop thru all possible signals and install the SIG_DFL...
    5. Communication between 2 processes by using signals
      How 2 independent processes can communicate ( say to passing some chunk of data) with "signals". Is it possible ? Are signals is counted in IPC...
  3. #2

    Default Re: More on 5.8 and signals

    Eric Frazier <eric@dmcontact.com> wrote:
    > I am pretty desparate to get this working, and if anyone wants to earn
    > some cash helping me fix things PLEASE call me at 250 655-9513.
    >
    > Erro was No child processes %! --------
    >
    > So it looks like the parent got killed on that error "No child process"
    That's because you're looping in the CHLD handler now --
    > sub REAPER_NEW {
    > logmsg "got - @_\n";
    > my $wpid = undef;
    > while ($wpid = waitpid(-1,WNOHANG)>0) {
    This calls waitpid() until it fails, and the eventual failure
    clobbers $!. It was EINTR after the SIGCHLD, but now it's ECHILD.

    You could retry accept() on either ECHILD or EINTR, I think. Or
    you could set a flag in the handler:

    my $reaped;

    $SIG{CHLD} = sub {
    $reaped = 1;
    1 while waitpid(-1, WNOHANG) > 0;
    };

    while (1) {
    my $con = $sock->accept or do {
    next if $!{EINTR} or $reaped;
    last;
    };

    # ...

    }
    continue {
    $reaped = 0;
    }

    And on many systems, you can just set $SIG{CHLD} = "IGNORE" and the
    children will be reaped automatically.

    --
    Steve
    Steve Grazzini Guest

  4. #3

    Default Re: More on 5.8 and signals

    Hi Steve,

    That worked for me! But using $SIG{CHLD} = 'IGNORE'; also worked.

    I seem to now be having problems with keeping my database connection,
    but the server is staying live. I tried connecting at the top globaly,
    and I also tried connecting in the subs that get run by commands. Same
    result, after the first connect and close I loose my db connection.

    But that is problem I will most likely be able to solve on my own, so
    thanks for your help...


    Eric



    Steve Grazzini wrote:
    > Eric Frazier <eric@dmcontact.com> wrote:
    >
    >>I am pretty desparate to get this working, and if anyone wants to earn
    >>some cash helping me fix things PLEASE call me at 250 655-9513.
    >>
    >>Erro was No child processes %! --------
    >>
    >>So it looks like the parent got killed on that error "No child process"
    >
    >
    > That's because you're looping in the CHLD handler now --
    >
    >
    >> sub REAPER_NEW {
    >> logmsg "got - @_\n";
    >> my $wpid = undef;
    >> while ($wpid = waitpid(-1,WNOHANG)>0) {
    >
    >
    > This calls waitpid() until it fails, and the eventual failure
    > clobbers $!. It was EINTR after the SIGCHLD, but now it's ECHILD.
    >
    > You could retry accept() on either ECHILD or EINTR, I think. Or
    > you could set a flag in the handler:
    >
    > my $reaped;
    >
    > $SIG{CHLD} = sub {
    > $reaped = 1;
    > 1 while waitpid(-1, WNOHANG) > 0;
    > };
    >
    > while (1) {
    > my $con = $sock->accept or do {
    > next if $!{EINTR} or $reaped;
    > last;
    > };
    >
    > # ...
    >
    > }
    > continue {
    > $reaped = 0;
    > }
    >
    > And on many systems, you can just set $SIG{CHLD} = "IGNORE" and the
    > children will be reaped automatically.
    >
    bob Guest

Posting Permissions

  • You may not post new threads
  • You may post replies
  • You may not post attachments
  • You may not edit your posts

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139