#!/usr/bin/perl # EventsTest.pl # Version 1.0, 25 April 2020 use Sys::HostIP; use Daemon::Daemonize qw( :all ); use IO::Socket::INET; use Event; use AnyEvent; use Date::Calc qw( Today_and_Now ); use strict; use warnings; $|++; # ********************************************************** # # ************** Variables to be set by user *************** # # ********************************************************** # base path/name for log files (e.g. /home/anita2r/events.log) my $base = "/home/anita2R/events"; # port for socket connection my $port = 55129; # ********************************************************** # # ****************** Create log files etc. ***************** # # ********************************************************** # # Setup log, error and pid files my $error_log = "$base.err"; my $pid_file = "$base.pid"; my $msg_log = "$base.log"; # clear error and log files truncate $error_log, 0; truncate $msg_log, 0; # ********************************************************** # # ************* Create a communications socket ************* # # ********************************************************** # # create a socket and log port number my $hostip = Sys::HostIP->new; my $ip = $hostip->ip; # save port to log file my $DtTm = DtTmStmp(); open( my $fh, '>>', $msg_log ); print $fh "$DtTm, Port: $port\n"; close $fh; # setup socket my $skt = IO::Socket::INET->new( Listen => 1, LocalAddr => $ip, LocalPort => $port, Proto => 'tcp', Reuse => 1, ) or die "$! ... Can't open socket on port $port\n"; # ********************************************************** # # ******************** Signal handlers ********************* # # ********************************************************** # # ********************************************************** # # HUP signal handler # for this test HUP will log and close the script my $wtforhup = AnyEvent->signal( signal => "HUP", cb => sub { my $DtTm = DtTmStmp(); open( my $fh, '>>', $msg_log ); print $fh "$DtTm, Hangup\n"; close $fh; # clear the pid file and stop the daemon delete_pidfile( $pid_file ); exit 1; } ); # ********************************************************** # # USR1 signal handler # for this test USR1 will just add an entry to the log my $wtforusr1 = AnyEvent->signal( signal => "USR1", cb => sub{ my $DtTm = DtTmStmp(); open( my $fh, '>>', $msg_log ); print $fh "$DtTm, User 1 signal received\n"; close $fh; } ); # ********************************************************** # # IO socket handler # read data, log receive # and pass it on for additional processing my $data; my $iocv = AnyEvent->condvar; my $wtforio = AnyEvent->io( fh => \*$skt, poll => 'r', cb => sub{ my $lskt = $skt->accept(); while( <$lskt> ) { $data = $_; chomp $data; my $hostip = $lskt->peerhost(); # log received data my $DtTm = DtTmStmp(); open( my $fh, '>>', $msg_log ); print $fh "$DtTm, Connection received from $hostip\n"; print $fh "Data: $data\n"; close $fh; } close( $lskt ); # send data for further processing # $iocv->recv is in main loop $iocv->send( $data ); } ); # ********************************************************** # # *********************** Daemonize ************************ # # ********************************************************** # # daemonize, redirect errors & save new pid daemonize( close => 'std', stderr => $error_log, ); write_pidfile( $pid_file ); # ********************************************************** # # ********************* Initialization ********************* # # ********************************************************** # # In the real program, various initialization routines # are carried out before entering the main program loop # ********************************************************** # # ******************* Main Program Loop ******************** # # ********************************************************** # my $loop = 1; my $a = 0; while( $loop ) { # just to show whether the loop is running # one entry every 5 seconds if( $a % 5 == 0) { open( $fh, '>>', $msg_log ); print $fh "looping $a\n"; close $fh; } $a++; sleep 1; # $iocv-recv blocks until an $iorecv->send my $data = $iocv->recv; open( $fh, '>>', $msg_log ); print $fh "loop data: $data\n"; close $fh; # done with this cv undef $iocv; # setup a fresh cv - loop will be blocked until next send $iocv = AnyEvent->condvar; } exit 0; # ********************************************************** # # ****************** General subroutines ******************* # # ********************************************************** # # ********************************************************** # # date/time stamp sub DtTmStmp { my( $yr, $mo, $dy, $hr, $mi, $se ) = Today_and_Now(); my $DtTm = sprintf( "%02d-%02d-%04d %02d:%02d:%02d", $dy, $mo, $yr, $hr, $mi, $se ); return $DtTm; } # ********************************************************** #