summaryrefslogtreecommitdiff
path: root/storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Util/IO.pm
diff options
context:
space:
mode:
Diffstat (limited to 'storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Util/IO.pm')
-rw-r--r--storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Util/IO.pm213
1 files changed, 213 insertions, 0 deletions
diff --git a/storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Util/IO.pm b/storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Util/IO.pm
new file mode 100644
index 00000000000..34f4d0a150d
--- /dev/null
+++ b/storage/ndb/tools/old_dirs/ndbnet/lib/NDB/Util/IO.pm
@@ -0,0 +1,213 @@
+package NDB::Util::IO;
+
+use strict;
+use Carp;
+
+require NDB::Util::Base;
+
+use vars qw(@ISA);
+@ISA = qw(NDB::Util::Base);
+
+# constructors
+
+my $log;
+
+sub initmodule {
+ $log = NDB::Util::Log->instance;
+}
+
+NDB::Util::IO->attributes(
+ readbuf => sub { defined },
+ readend => sub { defined },
+ writebuf => sub { defined },
+ writeend => sub { defined },
+ iosize => sub { $_ > 0 },
+ timeout => sub { /^\d+$/ },
+ fh => sub { ref($_) eq 'GLOB' && defined(fileno($_)) },
+);
+
+sub desc {
+ my $io = shift;
+ my $fileno = $io->hasfh ? fileno($io->getfh) : -1;
+ return "fd=$fileno";
+}
+
+sub new {
+ my $class = shift;
+ @_ % 2 == 0 or confess 0+@_;
+ my(%attr) = @_;
+ my $io = $class->SUPER::new(%attr);
+ $io->setreadbuf("")
+ or $log->push, return undef;
+ $io->setreadend(0)
+ or $log->push, return undef;
+ $io->setwritebuf("")
+ or $log->push, return undef;
+ $io->setwriteend(0)
+ or $log->push, return undef;
+ $io->setiosize(1024)
+ or $log->push, return undef;
+ $io->settimeout(0)
+ or $log->push, return undef;
+ if (defined($attr{fh})) {
+ $io->setfh($attr{fh})
+ or $log->push, return undef;
+ }
+ return $io;
+}
+
+# input / output
+
+sub read {
+ my $io = shift;
+ @_ == 0 or confess 0+@_;
+ if ($io->getreadend) {
+ return "";
+ }
+ my $size = $io->getiosize;
+ my $timeout = $io->hastimeout ? $io->gettimeout : 0;
+ my $fh = $io->getfh;
+ my $n;
+ my $data;
+ eval {
+ if ($^O ne 'MSWin32' && $timeout > 0) {
+ local $SIG{ALRM} = sub { die("timed out\n") };
+ alarm($timeout);
+ $n = sysread($fh, $data, $size);
+ alarm(0);
+ }
+ else {
+ $n = sysread($fh, $data, $size);
+ }
+ };
+ if ($@) {
+ $log->put("read error: $@")->push($io);
+ return undef;
+ }
+ if (! defined($n)) {
+ $log->put("read failed: $!")->push($io);
+ return undef;
+ }
+ if ($n == 0) {
+ $io->setreadend(1)
+ or $log->push, return undef;
+ $log->put("read EOF")->push($io)->debug;
+ return "";
+ }
+ (my $show = $data) =~ s!\n!\\n!g;
+ $log->put("read: $show")->push($io)->debug;
+ return $data;
+}
+
+sub readbuf {
+ my $io = shift;
+ @_ == 0 or confess 0+@_;
+ my $data = $io->read;
+ defined($data) or
+ $log->push, return undef;
+ if (length($data) == 0) {
+ return 0;
+ }
+ $io->setreadbuf($io->getreadbuf . $data)
+ or $log->push, return undef;
+ return 1;
+}
+
+sub readupto {
+ my $io = shift;
+ @_ == 1 or confess 0+@_;
+ my($code) = @_;
+ ref($code) eq 'CODE' or confess 'oops';
+ my $k = &$code($io->getreadbuf);
+ if (! defined($k)) {
+ $log->push($io);
+ return undef;
+ }
+ if ($k == 0) {
+ my $n = $io->readbuf;
+ defined($n) or
+ $log->push, return undef;
+ if ($n == 0) {
+ if ($io->getreadbuf eq "") {
+ return "";
+ }
+ $log->put("incomplete input: %s", $io->getreadbuf)->push($io);
+ return undef;
+ }
+ $k = &$code($io->getreadbuf);
+ if (! defined($k)) {
+ $log->push($io);
+ return undef;
+ }
+ if ($k == 0) {
+ return "";
+ }
+ }
+ my $head = substr($io->getreadbuf, 0, $k);
+ my $tail = substr($io->getreadbuf, $k);
+ $io->setreadbuf($tail)
+ or $log->push, return undef;
+ return $head;
+}
+
+sub readline {
+ my $io = shift;
+ @_ == 0 or confess 0+@_;
+ my $code = sub {
+ my $i = index($_[0], "\n");
+ return $i < 0 ? 0 : $i + 1;
+ };
+ return $io->readupto($code);
+}
+
+sub write {
+ my $io = shift;
+ @_ == 1 or confess 0+@_;
+ my($data) = @_;
+ my $timeout = $io->hastimeout ? $io->gettimeout : 0;
+ my $fh = $io->getfh;
+ (my $show = $data) =~ s!\n!\\n!g;
+ $log->put("write: $show")->push($io)->debug;
+ my $n;
+ my $size = length($data);
+ eval {
+ local $SIG{PIPE} = sub { die("broken pipe\n") };
+ if ($^O ne 'MSWin32' && $timeout > 0) {
+ local $SIG{ALRM} = sub { die("timed out\n") };
+ alarm($timeout);
+ $n = syswrite($fh, $data, $size);
+ alarm(0);
+ }
+ else {
+ $n = syswrite($fh, $data, $size);
+ }
+ };
+ if ($@) {
+ $log->put("write error: $@")->push($io);
+ return undef;
+ }
+ if (! defined($n)) {
+ $log->put("write failed: $!")->push($io);
+ return undef;
+ }
+ if ($n > $size) {
+ $log->put("impossible write: $n > $size")->push($io);
+ return undef;
+ }
+ if ($n != $size) { # need not be error
+ $log->put("short write: $n < $size")->push($io);
+ }
+ return $n;
+}
+
+sub close {
+ my $io = shift;
+ @_ == 0 or confess 0+@_;
+ if (! close($io->delfh)) {
+ $log->put("close failed: $!")->push($io);
+ return undef;
+ }
+ return 1;
+}
+
+1;