wgnd-watch.pl
changeset 19 a9b77650cbc4
parent 14 7b4903ebdee8
child 22 bba8b3344c26
--- a/wgnd-watch.pl	Mon Apr 30 12:57:15 2012 +0200
+++ b/wgnd-watch.pl	Thu May 03 13:33:14 2012 +0200
@@ -25,17 +25,17 @@
 
 my $VERSION = '0.1';
 my $ME = $0;
+
+use File::Basename;
+# File::Rsync in squeeze does not support --xattrs yet
+#use File::Rsync;
 use Getopt::Long;
 use Pod::Usage;
 use Linux::Inotify2;
-# File::Rsync in squeeze does not support --xattrs yet
-#use File::Rsync;
-
-my $map = 'wgnd-watch.map.pl';
+use Sys::Syslog;
 
 BEGIN {
 
-    use Sys::Syslog;
     openlog($ME, 'ndelay,nowait,pid', 'LOG_USER');
     $SIG{__WARN__} = sub {
         warn @_ if not defined $^S;
@@ -48,16 +48,25 @@
         syslog('err', "@_");
         exit $?;
     };
-
     sub dolog { print "@_"; syslog('info', "@_"); }
     sub trace { print @_ if $ENV{DEBUG}; }
 
+    use sigtrap qw(die normal-signals);
+
 }
 
+my %opts = (
+    daemon => 1,
+    map =>  'wgnd-watch.map.pl',
+    pidfile => '/var/run/wgnd-watch.pid'
+);
+
 GetOptions(
-    "map=s"  => \$map,
-    "h|help" => sub { pod2usage( -verbose => 0, -exitval => 0 ) },
-    "m|man"  => sub {
+    "map=s"  => \$opts{map},
+    "daemon!" => \$opts{daemon},
+    "pidfile=s" => \$opts{pidfile},
+    "h|help!" => sub { pod2usage( -verbose => 0, -exitval => 0 ) },
+    "m|man!"  => sub {
         pod2usage(
             -verbose   => 2,
             -exitval   => 0,
@@ -68,10 +77,35 @@
 
 our $source;
 use lib ('.', $ENV{HOME}, '/etc'); 
-require $map;
+require $opts{map};
+
+$0 = "$ME @ARGV";
+
+chdir("/") or die "Can't chdir to /: $!\n";
+
+if ($opts{daemon}) {
+
+    open STDIN,  "</dev/null" or die "Can't redir STDIN: $!\n";
+    open STDOUT, ">/dev/null" or die "Can't redir STDOUT: $!\n";
+
+    defined (my $pid = fork) or die "Can't fork: $!\n";
+    if ($pid) {
+        dolog "Child is [$pid]";
+        exit 0;
+    }
+    POSIX::setsid()
+        or die "Can't setsid: $!\n";
+    open(STDERR, ">&STDOUT") or die "Can't dup stdout: $!\n";
+
+    open(P, '>', $opts{pidfile})
+        or die "Can't open '>', '$opts{pidfile}': $!\n";
+    print P $$;
+    close P;
+
+}
 
 my $inotify = new Linux::Inotify2
-    or die "Can't create new inotify object: $!";
+    or die "Can't create new inotify object: $!\n";
 my @rsync = qw(/usr/bin/rsync -ihv -aAX);
 
 for (keys %{$source}) {
@@ -102,13 +136,17 @@
     $inotify->poll;
     while (-1 != (my $pid = wait)) {
         my $e = $? >> 8;
-        dolog "child ${ME}[$pid]: exit $e\n";
+        dolog "Child ${ME}[$pid]: exit $e\n";
     }
 
 }
 
 END {
+
+    unlink $opts{pidfile} if $opts{daemon};
+    dolog "exit";
     closelog;
+
 }
 
 __END__
@@ -135,11 +173,20 @@
 
 =over
 
+=item B<--[no]daemon>
+
+[Don't] run as a daemon. Default: do.
+
 =item B<--map> I<filename>
 
 Name of a file containing mappings between templates and directories. Defaults
 to F<wgnd-watch.map.pl>.
 
+=item B<--pidfile> I<filename>
+
+Location of the pid file. This is ignored unless we are running as a daemon.
+Defaults to F</var/run/wgnd-watch.pid>.
+
 =back
 
 =head1 FILES
@@ -150,6 +197,10 @@
 
 default for B<--map>
 
+=item F</var/run/wgnd-watch.pid>
+
+default for B<--pidfile>
+
 =back
 
 =head1 AUTHOR