e62b4a51ccbc0588f3bbe78a30aec351b52a97bf
[profile.git] / opt / bin / ktmux_helper
1 #!/usr/bin/perl
2 #
3 # ktmux_helper: Run krenew in the background for tmux.
4 # Notes: Doesn't handle multiple sessions properly.
5 #
6
7 use FindBin;
8 use POSIX ":sys_wait_h";
9
10 my $PROG = $FindBin::Script;
11
12 # Ensure tmux is our parent and find its PID.
13 my $tmux_pid = &get_tmux_pid;
14 unless ($tmux_pid) {
15   print STDERR "$PROG: Not a child of tmux!\n";
16   exit 100;
17 }
18
19 # Ensure there isn't already a helper running for this tmux.
20 my $tmux_helper = &get_tmux_helper;
21 exit 0 if $tmux_helper;
22
23 my $exitasap = 0;
24 my $pid = 0;
25
26 $SIG{INT} = \&cleanup;
27 $SIG{QUIT} = \&cleanup;
28 $SIG{TERM} = \&cleanup;
29
30 LOOP: while (&ping_tmux) {
31   $pid = fork;
32   die "$PROG: Can't fork: $!\n" unless defined $pid;
33
34   if ($pid) {
35     while (&ping_tmux) {
36       my $exited = waitpid $pid, WNOHANG;
37       goto LOOP if $exited == $pid || $exited < 0;
38       sleep 1;
39     }
40
41     # tmux is dead so kill krenew.
42     kill 3, $pid;
43     waitpid $pid, 0;
44     exit 0;
45   }
46   else {
47     exec "krenew", "-K", "60";
48     print "$PROG: Can't run krenew: $!\n";
49     exit 111;
50   }
51 }
52
53 sub get_tmux_pid {
54   my $pid = getppid;
55   my $cmd = `/bin/ps -o args= -p $pid`;
56   return $pid if $cmd =~ /\btmux\b/;
57   return undef;
58 }
59
60 sub get_tmux_helper {
61   my $pid = undef;
62   if (open IN, "pgrep -x -P $tmux_pid $PROG | ") {
63     while (<IN>) {
64       chomp;
65       s/[^\d]//g;
66       next if $_ == $$;
67       $pid = $_;
68       last;
69     }
70     close IN;
71   }
72   return $pid;
73 }
74
75 sub ping_tmux {
76   return kill 0, $tmux_pid;
77 }
78
79 sub cleanup {
80   unless ($exitasap) {
81     $exitasap = 1;
82     kill $pid;
83     waitpid $pid, WNOHANG;
84     exit 0;
85   }
86 }