I am new in Perl and trying to understand this cod in Link : http://codepaste.ru/1374/but I have some problem in understanding this part of code:
while($client || $target) {
my $rin = "";
vec($rin, fileno($client), 1) = 1 if $client;
vec($rin, fileno($target), 1) = 1 if $target;
my($rout, $eout);
select($rout = $rin, undef, $eout = $rin, 120);
if (!$rout && !$eout) { return; }
my $cbuffer = "";
my $tbuffer = "";
if ($client && (vec($eout, fileno($client), 1) || vec($rout, fileno($client), 1))) {
my $result = sysread($client, $tbuffer, 1024);
if (!defined($result) || !$result) { return; }
}
if ($target && (vec($eout, fileno($target), 1) || vec($rout, fileno($target), 1))) {
my $result = sysread($target, $cbuffer, 1024);
if (!defined($result) || !$result) { return; }
}
if ($fh && $tbuffer) { print $fh $tbuffer; }
while (my $len = length($tbuffer)) {
my $res = syswrite($target, $tbuffer, $len);
if ($res > 0) { $tbuffer = substr($tbuffer, $res); } else { return; }
}
while (my $len = length($cbuffer)) {
my $res = syswrite($client, $cbuffer, $len);
if ($res > 0) { $cbuffer = substr($cbuffer, $res); } else { return; }
}
}
can any body explain to me exactly whats happen in these lines:
vec($rin, fileno($client), 1) = 1 if $client;
vec($rin, fileno($target), 1) = 1 if $target;
and
select($rout = $rin, undef, $eout = $rin, 120);
Basically, the select
operator is used to find which of your file descriptors are ready (readable, writable or there's an error condition). It will wait until one of the file descriptors is ready, or timeout.
select RBITS, WBITS, EBITS, TIMEOUT
RBITS
is a bit mask, usually stored as a string, representing a set of file descriptors that select
will wait for readability. Each bit of RBITS
represent a file descriptor, and the offset of the file descriptor in this bit mask should the file descriptor number in system. Thus, you could use vec
to generate this bit mask.
vec EXPR, OFFSET, BITS
The vec
function provides storage of lists of unsigned integers. EXPR
is a bit string, OFFSET
is the offset of bit in EXPR
, and BITS
specifies the width of each element you're reading from / writing to EXPR
.
So these 2 lines:
vec($rin, fileno($client), 1) = 1;
vec($rin, fileno($target), 1) = 1;
They made up a bit mask string $rin
with setting the bit whose offset equals the file descriptor number of $client
, as well as the one of $target
.
Put it into select
operator:
select($rout = $rin, undef, $eout = $rin, 120);
Then select
will monitor the readability of the two file handlers ($client
and $target
), if one of them is ready, select
will return. Or it will return after 120s if no one is ready.
WBITS
, EBITS
use the same methodology. So you could infer that the above select
line will also return when the two file handler have any exceptions.