minor amendment to FAQ
[spider.git] / perl / Msg.pm
index eb6892a8f1f3568f41bbda4dd3316fe78f63ee98..ec07d61da6878851f6b8f11f19aba403e5729cbd 100644 (file)
@@ -15,8 +15,6 @@ use IO::Select;
 use IO::Socket;
 use DXDebug;
 use Timer;
-use Errno qw(EWOULDBLOCK EAGAIN EINPROGRESS);
-use POSIX qw(F_GETFL F_SETFL O_NONBLOCK);
 
 use vars qw(%rd_callbacks %wt_callbacks %er_callbacks $rd_handles $wt_handles $er_handles $now %conns $noconns);
 
@@ -28,6 +26,27 @@ $wt_handles   = IO::Select->new();
 $er_handles   = IO::Select->new();
 
 $now = time;
+my $blocking_supported = 0;
+
+BEGIN {
+    # Checks if blocking is supported
+    eval {
+        require POSIX; POSIX->import(qw (F_SETFL F_GETFL O_NONBLOCK));
+    };
+    $blocking_supported = 1 unless $@;
+
+       # import as many of these errno values as are available
+       eval {
+               require Errno; Errno->import(qw(EAGAIN EINPROGRESS EWOULDBLOCK));
+       };
+}
+
+my $w = $^W;
+$^W = 0;
+my $eagain = eval {EAGAIN()};
+my $einprogress = eval {EINPROGRESS()};
+my $ewouldblock = eval {EWOULDBLOCK()};
+$^W = $w;
 
 #
 #-----------------------------------------------------------------
@@ -71,6 +90,8 @@ sub set_rproc
 
 sub blocking
 {
+       return unless $blocking_supported;
+       
        my $flags = fcntl ($_[0], F_GETFL, 0);
        if ($_[1]) {
                $flags &= ~O_NONBLOCK;
@@ -135,10 +156,9 @@ sub connect {
        
        blocking($sock, 0);
        my $ip = gethostbyname($to_host);
-       my $r = $sock->connect($to_port, $ip);
-       unless ($r) {
-               return undef unless $! == EINPROGRESS;
-       }
+#      my $r = $sock->connect($to_port, $ip);
+       my $r = connect($sock, pack_sockaddr_in($to_port, $ip));
+       return undef unless $r || _err_will_block($!);
        
        $conn->{sock} = $sock;
     
@@ -263,8 +283,25 @@ sub _send {
     1;  # Success
 }
 
+sub dup_sock
+{
+       my $conn = shift;
+       my $oldsock = $conn->{sock};
+       my $rc = $rd_callbacks{$oldsock};
+       my $wc = $wt_callbacks{$oldsock};
+       my $ec = $er_callbacks{$oldsock};
+       my $sock = $oldsock->new_from_fd($oldsock, "w+");
+       if ($sock) {
+               set_event_handler($oldsock, read=>undef, write=>undef, error=>undef);
+               $conn->{sock} = $sock;
+               set_event_handler($sock, read=>$rc, write=>$wc, error=>$ec);
+               $oldsock->close;
+       }
+}
+
 sub _err_will_block {
-       return ($_[0] == EAGAIN || $_[0] == EWOULDBLOCK || $_[0] == EINPROGRESS);
+       return 0 unless $blocking_supported;
+       return ($_[0] == $eagain || $_[0] == $ewouldblock || $_[0] == $einprogress);
 }
 
 sub close_on_empty