00001 #!perl -I C:\MMAperl
00002 #
00003 # MMAgic/Log/Pipe.pl
00004 #
00005 # Utility program for reading from a named pipe and printing it.
00006 #
00007
00008 use IO::Socket::INET;
00009 use IO::Pipe;
00010 use IO::Select;
00011 use Win32::Pipe;
00012
00013 $name = $ARGV[0] || 'trace';
00014 $port = 10382;
00015
00016 ###########################################################################
00017 sub indent # $code
00018 #
00019 {
00020 my $code = shift || ' ';
00021 my ($sec, $min, $hour, $mday, $mon, $year) = localtime(time);
00022
00023 return sprintf "<%s> %04d/%02d/%02d %02d:%02d:%02d ",
00024 $code, $year, $mon, $mday, $hour, $min, $sec;
00025 }
00026
00027 ###########################################################################
00028 sub pipeError # $pip, $intro
00029 #
00030 {
00031 my $pip = shift;
00032 my ($err, $msg) = $pip->Error;
00033
00034 return $err ? "[$err] $msg" : '{no pipe error registered}';
00035 }
00036
00037 ###########################################################################
00038 sub play # $i
00039 #
00040 {
00041 my $i = shift; # child number
00042
00043 my $socket = new IO::Socket::INET
00044 (PeerAddr => 'localhost',
00045 PeerPort => $port,
00046 Proto => 'tcp',
00047 Type => SOCK_STREAM);
00048
00049 print $socket indent('I'), "Child $i started\n";
00050 $socket->flush;
00051
00052 while (1)
00053 {
00054 my $namePipe = new Win32::Pipe($name);
00055
00056 $namePipe->ResizeBuffer(1024);
00057
00058 unless (ref($namePipe) eq 'Win32::Pipe')
00059 {
00060 print $socket
00061 indent('E'), "Unable to allocate named pipe:\n",
00062 indent('E'), " $!";
00063 $socket->flush;
00064 return;
00065 }
00066
00067 while (1)
00068 {
00069 unless ($namePipe->Connect())
00070 {
00071 # print $socket
00072 # indent('E'), "Unable to connect named pipe:\n",
00073 # indent('E'), ' ', pipeError($namePipe), "\n",
00074 # indent('E'), " $!";
00075 $socket->flush;
00076 last;
00077 }
00078
00079 print $socket indent('+'), "Connected\n";
00080 $socket->flush;
00081
00082 while (1)
00083 {
00084 my $data = $namePipe->Read();
00085
00086 unless (defined($data))
00087 {
00088 # print $socket
00089 # indent('E'), "Error reading from named pipe:\n",
00090 # indent('E'), ' ', pipeError($namePipe), "\n",
00091 # indent('E'), " $!\n";
00092 $socket->flush;
00093 last;
00094 }
00095
00096 # Whoa!!! Time to print some data...
00097 print $socket $data;
00098 $socket->flush;
00099 }
00100
00101 $namePipe->Disconnect();
00102
00103 print $socket indent('-'), "Disconnected\n";
00104 $socket->flush;
00105 }
00106
00107 $namePipe->Close();
00108 $namePipe = undef;
00109 }
00110
00111 $socket->close;
00112 }
00113
00114 ###########################################################################
00115 ###########################################################################
00116 #
00117 # Main program:
00118 #
00119
00120 # Start a bunch of child processes for named pipe:
00121 for (my $i = 0; $i < 5; $i++)
00122 {
00123 my $pid = fork;
00124
00125 if (! defined($pid))
00126 {
00127 print indent('C'), "Unable to fork child process:\n",
00128 indent('C'), " $!\n";
00129 exit;
00130 }
00131
00132 if (! $pid)
00133 {
00134 # Child fork:
00135 play($i);
00136 exit;
00137 }
00138
00139 # Parent fork:
00140 }
00141
00142 # Capture socket data and prints it:
00143 $server = new IO::Socket::INET
00144 (LocalPort => $port,
00145 Type => SOCK_STREAM,
00146 Reuse => 1,
00147 Listen => 10);
00148
00149 unless ($server)
00150 {
00151 print indent('C'), "Unable to create server socket:\n",
00152 indent('C'), " $!\n";
00153 exit;
00154 }
00155
00156 $switch = new IO::Select($server);
00157
00158 unless ($switch)
00159 {
00160 print indent('C'), "Unable to create select object:\n",
00161 indent('C'), " $!\n";
00162 exit;
00163 }
00164
00165 print indent('I'), "Server started on port $port\n";
00166
00167 while (1)
00168 {
00169 # print indent('T'), "Check for ", $switch->count(), " handles\n";
00170
00171 my @handles = $switch->can_read;
00172
00173 for my $handle (@handles)
00174 {
00175 if ($handle == $server)
00176 {
00177 # Accept and create another connection:
00178 my $connection = $server->accept;
00179
00180 $switch->add($connection); # now wait for this one too.
00181
00182 # print indent('T'), "Accepted connection\n";
00183 }
00184
00185 else
00186 {
00187 my $data = undef;
00188 my $done = $handle->recv($data, 1024);
00189
00190 if (defined($done))
00191 {
00192 print $data if $data;
00193 next;
00194 }
00195
00196 # An error, connection probably dead:
00197 $switch->remove($handle);
00198 $handle->close();
00199 }
00200 }
00201 }