Author: msergeant
Date: Thu Oct  4 08:18:57 2007
New Revision: 807

Modified:
   trunk/qpsmtpd-async

Log:
Allow qpsmtpd-async to detatch (Chris Lewis).


Modified: trunk/qpsmtpd-async
==============================================================================
--- trunk/qpsmtpd-async (original)
+++ trunk/qpsmtpd-async Thu Oct  4 08:18:57 2007
@@ -41,6 +41,8 @@
 my $PAUSED      = 0;
 my $NUMACCEPT   = 20;
 my $ACCEPT_RSET = Danga::Socket->AddTimer(30, \&reset_num_accept);
+my $PID_FILE   = '';
+my $DETACH;       # daemonize on startup
 
 # make sure we don't spend forever doing accept()
 use constant ACCEPT_MAX => 1000;
@@ -59,6 +61,9 @@
  -p, --port P              : listen on a specific port; default 2525
  -u, --user U              : run as a particular user; defualt 'smtpd'
  -j, --procs J             : spawn J processes; default 1
+ -d, --detach              : detach from controlling terminal (daemonize)
+     --pid-file P          : print main servers PID to file P
+ 
  -h, --help                : this page
      --use-poll            : force use of poll() instead of epoll()/kqueue()
 EOT
@@ -71,6 +76,8 @@
     'j|procs=i'             => \$PROCS,
     'd|debug+'              => \$DEBUG,
     'u|user=s'              => \$USER,
+    'pid-file=s'            => \$PID_FILE,
+    'd|detach'              => \$DETACH,
     'h|help'                => \&help,
 ) || help();
 
@@ -92,6 +99,17 @@
 my $CONFIG_SERVER;
 
 my %childstatus = ();
+if ($PID_FILE && -r $PID_FILE) {
+    open PID, "<$PID_FILE"
+       or die "open_pidfile $PID_FILE: $!\n";
+    my $running_pid = <PID> || ''; chomp $running_pid;
+    if ($running_pid =~ /^(\d+)/) {
+       if (kill 0, $running_pid) {
+           die "Found an already running qpsmtpd with pid $running_pid.\n";
+       }
+    }
+    close(PID);
+}
 
 run_as_server();
 exit(0);
@@ -164,6 +182,9 @@
 sub HUNTSMAN {
     $SIG{CHLD} = 'DEFAULT';
     kill 'INT' => keys %childstatus;
+    if ($PID_FILE && -e $PID_FILE) {
+        unlink $PID_FILE or ::log(LOGERROR, "unlink: $PID_FILE: $!");
+    }
     exit(0);
 }
 
@@ -193,6 +214,21 @@
     IO::Handle::blocking($CONFIG_SERVER, 0);
     binmode($CONFIG_SERVER, ':raw');
 
+    if ($DETACH) {
+       open STDIN, '/dev/null' or die "/dev/null: $!";
+       open STDOUT, '>/dev/null' or die "/dev/null: $!";
+       open STDERR, '>&STDOUT' or die "open(stderr): $!";
+       defined (my $pid = fork) or die "fork: $!";
+       exit 0 if $pid;
+       POSIX::setsid or die "setsid: $!";
+    }
+
+    if ($PID_FILE) {
+       open PID, ">$PID_FILE" || die "$PID_FILE: $!";
+           print PID $$,"\n";
+        close PID;
+    }
+ 
     # Drop priviledges
     my (undef, undef, $quid, $qgid) = getpwnam $USER or
           die "unable to determine uid/gid for $USER\n";

Reply via email to