in reply to Detecting a port "in use" on localhost:$port
eval { local $SIG{ALRM} = sub { die "timeout" }; alarm($timeout); connect(SOCKET, $paddr) || error(); alarm(0); };
What is happening is (most likely) this: when there's nothing listening on the port in question, the connect() fails more or less immediately ("connection refused") and the (non-existent) routine error() is being called. This dies with "Undefined subroutine &main::error called at...", so the alarm(0) isn't getting executed. As the latter is supposed to reset the timer set up with the initial alarm($timeout), the timer keeps running and then fires later, outside of the eval{} scope, where the localized $SIG{ALRM} handler is no longer in effect...
In other words, the uncaught ALRM exception (on Windows emulated via SetTimer()/Windows Messages) is being reported as "Terminating on signal SIGALRM(14)".
Simplified demo:
#!perl eval { local $SIG{ALRM} = sub { die "timeout" }; alarm(1); error(); # not found -> dies alarm(0); }; print "\$@: $@\n" if $@; # do something that takes longer than a sec, # without itself being implemented via SetTimer() rand for 1..2e7; __END__ H:\PM>perl 759131.pl $@: Undefined subroutine &main::error called at 759131.pl line 6. Terminating on signal SIGALRM(14)
Solution: either move the alarm(0) outside of the eval{} (so it's always being executed), or set $SIG{ALRM} ='IGNORE' outside of the eval{} to ignore the timer 'signal'.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: Detecting a port "in use" on localhost:$port
by freddo411 (Chaplain) on Apr 22, 2009 at 18:18 UTC |