SIgnal help

D

Dave Saville

I am developing a script that uses Net::ping

I need to be able to CTRL-C it and have my END block run.

I have $SIG{INT} = \&catch; at the top of the script;

sub catch
{
$int++;
$SIG{INT} = 'DEFAULT' if $int > 3;
}


In the main program I check for $int being no-zero and exit.
The actual ping is issued from a subroutine.

If the other end is responding then a CTRL-C will stop it and run my
END block. However if the other end is *not* responding then I get
this:

..........

CTRL-C Nothing happens, if I leave it it stays that way and no more
output appears.

CTRL-C
Bad arg length for Socket::unpack_sockaddr_in, length is 0, should be
16 at D:/u
sr/lib/perl/lib/5.8.2/os2/Socket.pm line 370.

Followed by the print from my END block.

What's going on and what have I missed? I am guessing that the
Net::ping code has installed another handler?

TIA
 
D

Dave Saville

Hi Ben
Quoth "Dave Saville said:
I am developing a script that uses Net::ping

I need to be able to CTRL-C it and have my END block run.

I have $SIG{INT} = \&catch; at the top of the script;

sub catch
{
$int++;
$SIG{INT} = 'DEFAULT' if $int > 3;
}


In the main program I check for $int being no-zero and exit.
The actual ping is issued from a subroutine.

If the other end is responding then a CTRL-C will stop it and run my
END block. However if the other end is *not* responding then I get
this:

.........

CTRL-C Nothing happens, if I leave it it stays that way and no more
output appears.

CTRL-C
Bad arg length for Socket::unpack_sockaddr_in, length is 0, should be
16 at D:/u
sr/lib/perl/lib/5.8.2/os2/Socket.pm line 370.

Followed by the print from my END block.

What's going on and what have I missed? I am guessing that the
Net::ping code has installed another handler?

Net::ping does not install a SIGINT handler. You may be falling foul of
'safe signals', or this may be an inconsistency in the way OS/2 handles
signals. I can't reproduce this with this program:

use 5.012;
use Net::ping;

my $int = 0;
$SIG{INT} = sub {
warn "SIGINT ($int)";
if (++$int > 3) {
warn "CLEARING SIGINT";
$SIG{INT} = "DEFAULT";
}
};

$| = 1;
my $P = Net::ping->new;
while (1) {
print "SENDING PING...";
my $p = $P->ping($ARGV[0]);
say $p ? "ALIVE" : "DEAD";
sleep 5;
}

even if I time the ^C so it comes while a ping is in progress, which
suggests the latter; can you post a minimal program which exhibits the
problem to confirm whether this is OS-dependent?

Running the above on 5.16.0

[T:\tmp]try.pl 192.168.0.2
SENDING PING...ALIVE
SIGINT (0) at try.pl line 6.
SENDING PING...ALIVE
SIGINT (1) at try.pl line 6.
SENDING PING...ALIVE
SIGINT (2) at try.pl line 6.
SENDING PING...ALIVE
SIGINT (3) at try.pl line 6.
CLEARING SIGINT at try.pl line 8.
SENDING PING...ALIVE

[T:\tmp]try.pl 192.168.0.5
SENDING PING...DEAD
SENDING PING...SIGINT (0) at try.pl line 6.
select: Interrupted system call at u:/perl5/lib/5.16.0/Net/Ping.pm
line 633.
DEAD
SENDING PING...SIGINT (1) at try.pl line 6.
select: Interrupted system call at u:/perl5/lib/5.16.0/Net/Ping.pm
line 633.
DEAD
SIGINT (2) at try.pl line 6.
SENDING PING...SIGINT (3) at try.pl line 6.
CLEARING SIGINT at try.pl line 8.
select: Interrupted system call at u:/perl5/lib/5.16.0/Net/Ping.pm
line 633.
DEAD

And another thing :)

A "real" ping seems to be about once a second here. If I start a ping
to a host, let it return a few times and pull the ethernet cable it
obviously stops printing returns.If I then put the cable back it
starts again. CTRL-C and I get a summary of pings sent, received and
lost.

Trying to do the same thing with Net::ping and it stops printing
returns and starts again when I replace the cable - but it sees *no*
dropped packets. It would appear that it blocks until it gets a
return. I just tried your program doing the same thing and it hangs at
SENDING PING... until I plug it in again when it takes almost 20
seconds before it prints ALIVE.
 
D

Dave Saville

I just tried my script again under 5.16.0 and it is OK with CTRL-C
when pinging a non exisitant IP. So it is something in my "normal use"
5.8.2 perl Net::ping or the underlying socket code.

5.8.2 Net::ping is version 2.31 and 5.16.0 is 2.38 - Diff shows a lot
of changes.

However, the "pulling the plug hang" remains under 5.16.0.
 
D

Dave Saville

I get the same results, so there's something different about your
program which is causing the hang and the failed unpack_sockaddr_in. You
will need to start cutting it down until you get something small enough
to post.

As I said in another reply it would seem to the difference between
5.8.2 and 5.16.0
ping(1) sends ICMP pings by default, which (at least on Unix) require
privilege. In order to avoid making you run your script as root,
Net::ping uses TCP 'pings' by default, which actually just attempt a TCP
connection to the echo port (port 4) and return 'reachable' if either
the connection succeeds or we get a definite ECONNREFUSED. This will
lead to different behaviour on failure: in particular, a TCP connection
attempt can take several minutes to time out, so if you pull the cable
it will take that long before the host is reported dead. The delay when
the cable is plugged back in is likely due to the kernel's exponential
backoff of connection retries.

I don't know what OS/2's security model is like.

Hasn't got one :)

I *am* using ICMP. My point is "real" ping gets a reject or something
when the cable is pulled but keeps trying as when it is plugged in
again it not only starts printing status lines immediately but also
knows how many failed. I know it is still pinging because the lights
on the switch blink.

PC <cable> switch <cable> router ie I pull the second cable.

I slowly modifed your code to match mine and it behaves as "real" ping
all the time. Just tried mine again and it worked. Hmmm.

I said:
You could also try Net::ping::External, though again you will need to
patch it for OS/2. (Or, you know, you could just run 'ping -c1' or
whatever the equivalent is and check the exit status.)

LOL that was my first thought. The actual problem I am trying to solve
is a drop out on VOIP. It has been suggested to run a ping during the
call to see if packets are dropping or getting long response times.
Ping on its own only gives the packet loss at program end. I wanted it
continuous and thought running a completely fresh copy of ping every
second was a bit much. :)
 
D

Dave Saville

Hi Ben

It would seem to be a timing issue. Using your code from previous post
I can reprduce the error.

SENDING PING... <timeout delay> DEAD
<sleep delay>
SENDING PING...

If you CTRL-C during the sleep delay it works as expected but if you
do it during the timeout delay you get the error. As I was running
with a sleep of 1 it was always in the timeout delay. Works OK on
5.16.0. You can CTLR-C any time and no error
 
C

C.DeRykus

On Saturday, October 26, 2013 2:54:01 AM UTC-7, Dave Saville wrote:

[ ... ]
CTRL-C

Bad arg length for Socket::unpack_sockaddr_in, length is 0, should be 16 at D:/u

sr/lib/perl/lib/5.8.2/os2/Socket.pm line 370.

Not to minimize all the nuances but there was a
distinct feeling of "deja vu all over again" on
seeing that particular Socket.pm error. It may be of
interest to google the message (and some of the early
patches) since it was problematic for Net::ping and
other modules of that era :)
 

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

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top