#turn off the posix sigterm handler $SIG{TERM} = 'DEFAULT'; #### #!/usr/bin/perl -w -t #!/usr/local/bin/perl -w -t #this is the script that is loaded first #load support for strict variables use strict; #load support for printing to the screen - testing only use CGI; use CGI::Carp qw(fatalsToBrowser); my $q = CGI->new; print $q->header; print "

start: $$

"; #load support for sockets use IO::Socket; #load posix support for named pipes use POSIX qw(mkfifo); #load support for finding the path to the process folder use FindBin(); use File::Basename(); use File::Spec::Functions; #load posix support for trapping signals use POSIX(); #determine the current script path and name my $script = File::Basename::basename($0); my $SELF = catfile $FindBin::Bin, $script; #create a new signal set my $sigset = POSIX::SigSet->new(); #create the action you want performed on terminate signals my $termAction = POSIX::SigAction->new('sigTERM_handler', $sigset, &POSIX::SA_NODEFER); #attach the signal to the action you want performed POSIX::sigaction(&POSIX::SIGTERM, $termAction); #start of the sub to run when the terminate signal arrives sub sigTERM_handler { #store the signal sent by the system my $HTPad_signalCaught = shift; #run the handler for all exit signals &HTPad_exitSignalHandler("Terminate", $HTPad_signalCaught); } #end of the sub to run when the terminate signal arrives #start of the handler for all exit signals sub HTPad_exitSignalHandler { #reinstate the passed variables my $HTPad_exitType = shift; my $HTPad_signalCaught = shift; unless (exec($SELF, @ARGV)) { Die "Could not restart the script after a $HTPad_signalCaught signal was received: $!"; } } #end of the handler for all exit signals #turn on auto flush $|=1; #load required files require './HTPadProcess_subs.pl'; #ignore child signals in order to do automatic child reaping $SIG{CHLD} = 'IGNORE'; #enter the web server &HTPad_webSserver(); #start of the web server sub HTPad_webSserver { my %HTPad = (); my ($HTPad_server , $HTPad_client); #define the in out port $HTPad{port} = 5814; #define the server pipe names $HTPad{serverReadPipeName} = '.serverReadPipe.txt'; $HTPad{serverWritePipeName} = '.serverWritePipe.txt'; #open the TCP connection $HTPad_server = IO::Socket::INET->new( LocalPort => $HTPad{port}, Type => SOCK_STREAM, Reuse => 1, Listen => SOMAXCONN) or die "There is no tcp server on port $HTPad{port}: $!\n"; #start of the parent server accepting clients while ($HTPad_client = $HTPad_server->accept()) { #auto flush the client $HTPad_client->autoflush(1); #start of forking a write child for the client unless ($HTPad{clientWritePID} = fork()) { #write child #turn off the posix sigterm handler $SIG{TERM} = 'DEFAULT'; #turn off the posix sigint handler $SIG{INT} = 'DEFAULT'; #turn off the posix sighup handler $SIG{HUP} = 'DEFAULT'; #turn off the posix sigpipe handler $SIG{PIPE} = 'DEFAULT'; #the read childcloses the unused server handle close ($HTPad_server); #get the pipe name from the parent server $HTPad{pipeName} = &HTPad_readFromPipe($HTPad{serverWritePipeName}); #start of continuously wait for data from the read child while (1) { #get data from the read child $HTPad{ringData} = &HTPad_readFromPipe($HTPad{pipeName}); #add test text #$HTPad{ringData} = $HTPad{ringData}; #start of process test data if ($HTPad{ringData} =~ m/are you there/i) { #send the data to the client print $HTPad_client "The web server confirms your write test:" . $HTPad{ringData} . "\015\12"; #end of process test data #start of process normal web server data } else { #send the data to the client print $HTPad_client "This is the server and you wrote: " . $HTPad{ringData} . "\015\12"; } #end of process normal web server data } #end of continuously wait for data from the read child #close the write child connection close($HTPad_client); #exit the write child to keep it from accepting new clients exit(1); } #end of forking a write child for the client #start of checking the success of the forked write child if ($HTPad{clientWritePID} > 0) { #start of forking a read child for the client unless ($HTPad{clientReadPID} = fork()) { #read child #turn off the posix sigterm handler $SIG{TERM} = 'DEFAULT'; #turn off the posix sigint handler $SIG{INT} = 'DEFAULT'; #turn off the posix sighup handler $SIG{HUP} = 'DEFAULT'; #turn off the posix sigpipe handler $SIG{PIPE} = 'DEFAULT'; #the read childcloses the unused server handle close ($HTPad_server); #get the pipe name from the parent server $HTPad{pipeName} = &HTPad_readFromPipe($HTPad{serverReadPipeName}); #start of listen for data untill client connection closes while (defined ($HTPad{ringData} = <$HTPad_client>)) { #start of send the new data to the write child if ($HTPad{ringData} ne '') { #add test data to the data $HTPad{ringData} = $HTPad{pipeName} . " " . $HTPad{ringData}; #send the data to the write child &HTPad_writeToPipe($HTPad{pipeName}, $HTPad{ringData}); } #end of send the new data to the write child } #end of listen for data untill client connection closes #send sig term to write child when client closes connection kill ("TERM", $HTPad{clientWritePID}); #close the read child connection close($HTPad_client); #exit the read child to keep it from accepting new clients exit(1); } #end of forking a read child for the client } #end of checking the success of the forked write child #start of checking the success of the forked write and read child if ($HTPad{clientWritePID} > 0 and $HTPad{clientReadPID} > 0) { #parent server #the server closes the unused read child handle close ($HTPad_client ); #define the new clients pipe name $HTPad{pipeNameFromServer} = '.puppy_' . $HTPad{clientReadPID} . '.txt'; #send the pipe name to the read child &HTPad_writeToPipe($HTPad{serverReadPipeName}, $HTPad{pipeNameFromServer}); #send the pipe name to the write child &HTPad_writeToPipe($HTPad{serverWritePipeName}, $HTPad{pipeNameFromServer}); #close the TCP connection after x connections - only when not waiting for more clients. if (++$HTPad{clientCount} >= 2) { close($HTPad_server); } } #end of checking the success of the forked write and read child #initialize the read and write pids $HTPad{clientWritePID} = 0; $HTPad{clientReadPID} = 0; } #end of the parent server accepting clients #close the parent server close($HTPad_server); } #end of the web server __END__