Daemonize (--[no]daemon).
authorHeiko Schlittermann <hs@schlittermann.de>
Wed, 28 Jan 2009 23:19:24 +0100
changeset 20 8b2d5135c8d8
parent 19 efcdb2e4ac21
child 21 14d3ce5c503f
Daemonize (--[no]daemon).
hlog
--- a/hlog	Wed Jan 28 22:23:54 2009 +0100
+++ b/hlog	Wed Jan 28 23:19:24 2009 +0100
@@ -23,11 +23,13 @@
 use Getopt::Long;
 use IO::Socket::INET;
 use Pod::Usage;
-use POSIX qw(:sys_wait_h);
+use POSIX qw(:sys_wait_h setsid);
+use Cwd;
 
 my $opt_addr  = "0.0.0.0";
 my $opt_port  = 8080;
 my $opt_lines = 10;
+my $opt_daemon = 1;
 my $logfile   = "hlog.log";
 my %FILE;
 
@@ -44,6 +46,7 @@
         "lines=i" => \$opt_lines,
         "help"    => sub { pod2usage(-verbose => 1, -exitval => 0) },
         "man"     => sub { pod2usage(-verbose => 2, -exitval => 0) },
+	"daemon!" => \$opt_daemon,
     ) or pod2usage();
 
     open(LOG, ">>$logfile");
@@ -56,6 +59,7 @@
         my ($tag, $file) = split /=/, $_, 2;
         die "tag $tag already exists with file $FILE{$tag}\n"
           if exists $FILE{$tag};
+	$file = getcwd() . "/$file" if $file !~ /^\//;
         $FILE{$tag} = $file;
     }
 
@@ -67,13 +71,31 @@
         ReuseAddr => 1,
     ) or die "Can't create listener socket: $!\n";
 
+    # go daemon
+    chdir("/") or die "Can't chdir to /: $!\n";
+
+    if ($opt_daemon) {
+	open(STDIN, "/dev/null") or die "Can't read /dev/null: $!\n";
+	open(STDOUT, ">/dev/null") or die "Can't write to /dev/null: $!\n";
+	defined(my $pid = fork()) or die "Can't fork: $!\n";
+
+	if ($pid) {
+	    warn "listener $pid $opt_addr:$opt_port\n";
+	    exit 0;
+	}
+
+	# child
+
+	setsid() or die "Can't start a new session: $!\n";
+	open(STDERR, ">&STDOUT") or die "Can't dup stdout: $!\n";
+    }
+
     $SIG{CHLD} = sub {
         while ((my $pid = waitpid(-1, WNOHANG)) > 0) {
             print LOG localtime() . " child $pid died\n";
         }
     };
 
-    warn "listener $$ $opt_addr:$opt_port\n";
 
     while (1) {
         my $client = $listener->accept;
@@ -85,8 +107,6 @@
           . $client->peerhost . ":"
           . $client->peerport . "\n";
 
-        warn $_;
-
         my $pid = fork();
         die "Can't fork: $!\n" if not defined $pid;
         if ($pid == 0) {
@@ -228,8 +248,11 @@
 
 =head1 SYNOPSIS
     
-    hlog [-p|--port port] [-a|--address address] [--lines n] file
-    hlog [-p|--port port] [-a|--address address] [--lines n] tag=file ...
+    hlog [--[no]daemon] 
+         [-a|--address address] [-p|--port port]
+	 [--lines n] 
+	 {file|tag=file ...}
+
     hlog [-h|--help] [-m|--man]
 
 =head1 DESCRIPTION
@@ -241,18 +264,22 @@
 
 =over
 
-=item B<-p>|B<--port> I<port>
-
-The port to listen on. (default: 8080)
-
 =item B<-a>|B<--address> I<address>
 
 The address to listen on. (default: 0.0.0.0)
 
+=item B<--[no]daemon>
+
+Do (or do not) daemonize. (default: do)
+
 =item B<--lines> I<lines>
 
 The number of lines to show. (default: 10)
 
+=item B<-p>|B<--port> I<port>
+
+The port to listen on. (default: 8080)
+
 =back
 
 =head1 EXAMPLES