App-BCVI-NotifyClient
view release on metacpan or search on metacpan
lib/App/BCVI/NotifyClient.pm view on Meta::CPAN
package App::BCVI::NotifyClient;
use warnings;
use strict;
our $VERSION = '2.00';
use POSIX qw(setsid);
my $default_idle_time = 20; # seconds
my $default_poll_interval = 5; # seconds
sub send_command {
my($self, @args) = @_;
my $command = $self->opt('command') || $self->default_command();
if($command eq 'notify') {
# Check for TTY monitoring options; handle them and exit
$self->_notify_handle_tty_monitoring(@args);
# Otherwise drop through for default handling
}
return $self->SUPER::send_command(@args);
}
sub _notify_handle_tty_monitoring {
my($self, @args) = @_;
my %opt = $self->_notify_get_options(@args) or return;
$opt{tty} ||= $self->_notify_current_tty;
if($opt{idle}) {
print "Starting background process to monitor $opt{tty} for $opt{idle} second idle period\n";
print "Kill monitor with: bnotify --kill\n";
$opt{output} = $default_poll_interval;
$self->_notify_fork_bg_tty_monitor(sub {
while(1) {
$self->_notify_wait_for_idle(\%opt);
$self->SUPER::send_command("terminal is idle");
$self->_notify_exit if $opt{once};
$self->_notify_wait_for_output(\%opt);
}
});
}
elsif($opt{output}) {
print "Starting background process to monitor $opt{tty} for output\n";
print "Kill monitor with: bnotify --kill\n";
$opt{idle} = $default_idle_time;
$self->_notify_fork_bg_tty_monitor(sub {
$self->_notify_wait_for_idle(\%opt);
while(1) {
$self->_notify_wait_for_output(\%opt);
$self->SUPER::send_command("output received");
$self->_notify_exit if $opt{once};
$self->_notify_wait_for_idle(\%opt);
}
});
}
elsif($opt{kill}) {
$self->App::BCVI::Server::kill_current_listener();
exit;
}
}
sub _notify_wait_for_idle {
my($self, $opt) = @_;
my $sleep_time = $opt->{idle};
while(1) {
sleep($sleep_time);
my $mtime = $self->_notify_tty_mtime($opt);
my $idle = time() - $mtime;
$sleep_time = $opt->{idle} - $idle;
return if $sleep_time <= 0;
}
}
sub _notify_wait_for_output {
my($self, $opt) = @_;
my $mtime = $self->_notify_tty_mtime($opt);
while(1) {
sleep($opt->{output});
return if $self->_notify_tty_mtime($opt) != $mtime;
}
}
sub _notify_tty_mtime {
my($self, $opt) = @_;
my @stat = stat($opt->{tty}) or die "stat($opt->{tty}): $!";
return $stat[9];
}
sub _notify_current_tty {
my $tty = readlink("/proc/self/fd/0");
if(!$tty) {
chomp( $tty = `tty` );
}
die "Unable to determine TTY\n" unless $tty;
return $tty;
}
sub _notify_get_options {
my($self, @args) = @_;
local(@ARGV) = @args;
my %opt = ();
( run in 0.687 second using v1.01-cache-2.11-cpan-0bb4e1dffa6 )