Subject: | [PATCH] use IO::Socket to improve socket operations |
the patch makes Sphinx::Search use IO::Socket for the socket operations.
(we couldn't find an email address, so we sent you the patch this way)
Subject: | sphinx-search.patch |
diff --git a/lib/Sphinx/Search.pm b/lib/Sphinx/Search.pm
index 67c4a6e..8f3dcb0 100644
--- a/lib/Sphinx/Search.pm
+++ b/lib/Sphinx/Search.pm
@@ -2,13 +2,15 @@ package Sphinx::Search;
use warnings;
use strict;
+
+use base 'Exporter';
+
use Carp;
use Socket;
use Config;
use Math::BigInt;
-use base 'Exporter';
-use Fcntl qw(:DEFAULT);
-use Errno;
+use English qw($INPUT_RECORD_SEPARATOR);
+use IO::Socket::INET;
=head1 NAME
@@ -322,61 +324,15 @@ sub _Connect {
return $self->{_connection} if $self->{_connection};
# connect socket
- my $fp;
- socket($fp, PF_INET, SOCK_STREAM, getprotobyname('tcp')) || Carp::croak("socket: ".$!);
+ my $fp = IO::Socket::INET->new( PeerPort => $self->{"_port"},
+ PeerAddr => $self->{"_host"},
+ Proto => 'tcp',
+ Timeout => $self->{"_timeout"},
+ ) or croak("Failed to open connection: $!");
binmode($fp, ':bytes');
- my $dest = sockaddr_in($self->{_port}, inet_aton($self->{_host}));
-
- if ($self->{_timeout}) {
- my $flags = fcntl($fp, F_GETFL, 0) or do {
- $self->_Error("Can't get flags for socket: $!");
- return 0;
- };
- fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or do {
- $self->_Error("Can't set flags for socket: $!");
- return 0;
- };
-
- if (! connect($fp, $dest)) {
- if (! $!{EINPROGRESS}) {
- $self->_Error("connect to {$self->{_host}}:{$self->{_port}} failed: $!");
- return 0;
- }
- my $count = 0;
- while ($count < 2) { # until timeout or data received
- my $vec = '';
- vec($vec, fileno($fp), 1) = 1;
- my $n = select($vec, undef, undef, $self->{_timeout});
- if ($n < 0) {
- $self->_Error("connection to {$self->{_host}}:{$self->{_port}} failed: $!");
- return 0;
- }
- elsif ($n == 0) {
- $self->_Error("connection to {$self->{_host}}:{$self->{_port}} timed out");
- return 0;
- }
- else {
- my $tmpbuf = 0;
- my $ret = recv($fp, $tmpbuf, 4, MSG_PEEK);
- last if $tmpbuf;
- }
- $count++;
- }
- }
- fcntl($fp, F_SETFL, $flags) or do {
- $self->_Error("Can't set flags for socket: $!");
- return 0;
- };
- }
- else {
- connect($fp, $dest) or do {
- $self->_Error("connection to {$self->{_host}}:{$self->{_port}} failed: $!");
- return 0;
- };
- }
# check version
my $buf = '';
- croak("recv: ".$!) unless defined recv($fp, $buf, 4, 0);
+ $fp->read($buf, 4) or croak("read failed: $!");
my $v = unpack("N*", $buf);
$v = int($v);
if($v < 1) {
@@ -387,7 +343,7 @@ sub _Connect {
$self->{_log}->debug("Sending version") if $debug;
# All ok, send my version
- send($fp, pack("N", 1),0);
+ $fp->write( pack( "N", 1 ) );
$self->{_connection} = $fp;
@@ -404,18 +360,19 @@ sub _GetResponse {
my $fp = shift;
my $client_ver = shift;
- my $header;
- croak("recv: ".$!) unless defined recv($fp, $header, 8, 0);
+ my $response;
+ {
+ # read everything till the end-of-file (close)
+ local $INPUT_RECORD_SEPARATOR = undef;
+ $response = $fp->getline;
+ }
+ my $header = substr($response, 0, 8, q{});
my ($status, $ver, $len ) = unpack("n2N", $header);
- my ($chunk, $response);
- while(defined($chunk = <$fp>)) {
- $response .= $chunk;
- }
$self->_Disconnect unless $self->{_persistent_connection};
# check response
- if ( !$response || length($response) != $len ) {
+ if ( length($response) != $len ) {
$self->_Error( $len
? "failed to read searchd response (status=$status, ver=$ver, len=$len, read=". length($response) . ")"
: "received zero-sized searchd response");
@@ -1349,7 +1306,7 @@ sub RunQueries {
my $nreqs = @{$self->{_reqs}};
my $req = pack("Na*", $nreqs, join("", @{$self->{_reqs}}));
$req = pack ( "nnN/a*", SEARCHD_COMMAND_SEARCH, VER_COMMAND_SEARCH, $req); # add header
- send($fp, $req ,0);
+ $fp->write($req);
$self->{_reqs} = [];
@@ -1578,7 +1535,7 @@ sub BuildExcerpts {
##########################
$req = pack ( "nnN/a*", SEARCHD_COMMAND_EXCERPT, VER_COMMAND_EXCERPT, $req); # add header
- send($fp, $req ,0);
+ $fp->write( $req );
my $response = $self->_GetResponse($fp, VER_COMMAND_EXCERPT);
return 0 unless ($response);