ac8676
diff -up vsftpd-2.1.1/standalone.c.daemonize_plus vsftpd-2.1.1/standalone.c
ac8676
--- vsftpd-2.1.1/standalone.c.daemonize_plus	2009-05-10 22:11:24.000000000 +0200
ac8676
+++ vsftpd-2.1.1/standalone.c	2009-05-10 22:11:24.000000000 +0200
ac8676
@@ -26,6 +26,8 @@ static unsigned int s_ipaddr_size;
ac8676
 
ac8676
 static void handle_sigchld(void*  duff);
ac8676
 static void handle_sighup(void*  duff);
ac8676
+static void handle_sigusr1(int sig);
ac8676
+static void handle_sigalrm(int sig);
ac8676
 static void prepare_child(int sockfd);
ac8676
 static unsigned int handle_ip_count(void* p_raw_addr);
ac8676
 static void drop_ip_count(void* p_raw_addr);
ac8676
@@ -46,11 +48,23 @@ vsf_standalone_main(void)
ac8676
   }
ac8676
   if (tunable_background)
ac8676
   {
ac8676
+    vsf_sysutil_sigaction(kVSFSysUtilSigALRM, handle_sigalrm);
ac8676
+    vsf_sysutil_sigaction(kVSFSysUtilSigUSR1, handle_sigusr1);
ac8676
+
ac8676
     int forkret = vsf_sysutil_fork();
ac8676
     if (forkret > 0)
ac8676
     {
ac8676
       /* Parent, just exit */
ac8676
-      vsf_sysutil_exit(0);
ac8676
+      vsf_sysutil_set_alarm(3);
ac8676
+      vsf_sysutil_pause();
ac8676
+
ac8676
+      vsf_sysutil_exit(1);
ac8676
+    }
ac8676
+    else if (forkret == 0)
ac8676
+    {
ac8676
+      // Son, restore original signal handler
ac8676
+      vsf_sysutil_sigaction(kVSFSysUtilSigALRM, 0L);
ac8676
+      vsf_sysutil_sigaction(kVSFSysUtilSigUSR1, 0L);
ac8676
     }
ac8676
     /* Son, close standard FDs to avoid SSH hang-on-exit */
ac8676
     vsf_sysutil_reopen_standard_fds();
ac8676
@@ -98,6 +112,10 @@ vsf_standalone_main(void)
ac8676
     {
ac8676
       die("could not bind listening IPv4 socket");
ac8676
     }
ac8676
+    if (tunable_background)
ac8676
+    {
ac8676
+      vsf_sysutil_kill(vsf_sysutil_getppid(), kVSFSysUtilSigUSR1);
ac8676
+    }
ac8676
   }
ac8676
   else
ac8676
   {
ac8676
@@ -127,6 +145,10 @@ vsf_standalone_main(void)
ac8676
     {
ac8676
       die("could not bind listening IPv6 socket");
ac8676
     }
ac8676
+    if (tunable_background)
ac8676
+    {
ac8676
+      vsf_sysutil_kill(vsf_sysutil_getppid(), kVSFSysUtilSigUSR1);
ac8676
+    }
ac8676
   }
ac8676
   vsf_sysutil_close(0);
ac8676
   vsf_sysutil_close(1);
ac8676
@@ -252,6 +274,20 @@ handle_sighup(void* duff)
ac8676
   vsf_parseconf_load_file(0, 0);
ac8676
 }
ac8676
 
ac8676
+static void
ac8676
+handle_sigalrm(int sig)
ac8676
+{
ac8676
+  (void)sig; // avoid unused parameter error
ac8676
+  vsf_sysutil_exit(1);
ac8676
+}
ac8676
+
ac8676
+static void
ac8676
+handle_sigusr1(int sig)
ac8676
+{
ac8676
+  (void)sig; // avoid unused parameter error
ac8676
+  vsf_sysutil_exit(0);
ac8676
+}
ac8676
+
ac8676
 static unsigned int
ac8676
 hash_ip(unsigned int buckets, void* p_key)
ac8676
 {
ac8676
diff -up vsftpd-2.1.1/sysutil.c.daemonize_plus vsftpd-2.1.1/sysutil.c
ac8676
--- vsftpd-2.1.1/sysutil.c.daemonize_plus	2009-05-10 22:11:24.000000000 +0200
ac8676
+++ vsftpd-2.1.1/sysutil.c	2009-05-10 22:11:59.000000000 +0200
ac8676
@@ -202,6 +202,9 @@ vsf_sysutil_translate_sig(const enum EVS
ac8676
     case kVSFSysUtilSigHUP:
ac8676
       realsig = SIGHUP;
ac8676
       break;
ac8676
+    case kVSFSysUtilSigUSR1:
ac8676
+      realsig = SIGUSR1;
ac8676
+      break;
ac8676
     default:
ac8676
       bug("unknown signal in vsf_sysutil_translate_sig");
ac8676
       break;
ac8676
@@ -539,6 +542,12 @@ vsf_sysutil_getpid(void)
ac8676
   return (unsigned int) s_current_pid;
ac8676
 }
ac8676
 
ac8676
+unsigned int
ac8676
+vsf_sysutil_getppid(void)
ac8676
+{
ac8676
+  return (unsigned int)getppid();
ac8676
+}
ac8676
+
ac8676
 int
ac8676
 vsf_sysutil_fork(void)
ac8676
 {
ac8676
@@ -2807,3 +2816,53 @@ vsf_sysutil_set_no_fds()
ac8676
     s_sig_details[i].pending = 0;
ac8676
   }
ac8676
 }
ac8676
+
ac8676
+static struct sigaction sigalr, sigusr1;
ac8676
+
ac8676
+void
ac8676
+vsf_sysutil_sigaction(const enum EVSFSysUtilSignal sig, void (*p_handlefunc)(int))
ac8676
+{
ac8676
+  int realsig = vsf_sysutil_translate_sig(sig);
ac8676
+  int retval;
ac8676
+  struct sigaction sigact, *origsigact=NULL;
ac8676
+  if (realsig==SIGALRM)
ac8676
+  {
ac8676
+    origsigact = &sigalr;
ac8676
+  }
ac8676
+  else if (realsig==SIGUSR1)
ac8676
+  {
ac8676
+    origsigact = &sigusr1;
ac8676
+  }
ac8676
+  vsf_sysutil_memclr(&sigact, sizeof(sigact));
ac8676
+  if (p_handlefunc != NULL)
ac8676
+  {
ac8676
+    sigact.sa_handler = p_handlefunc;
ac8676
+    retval = sigfillset(&sigact.sa_mask);
ac8676
+    if (retval != 0)
ac8676
+    {
ac8676
+      die("sigfillset");
ac8676
+    }
ac8676
+    retval = sigaction(realsig, &sigact, origsigact);
ac8676
+  }
ac8676
+  else
ac8676
+  {
ac8676
+    retval = sigaction(realsig, origsigact, NULL);
ac8676
+  }
ac8676
+  if (retval != 0)
ac8676
+  {
ac8676
+    die("sigaction");
ac8676
+  }
ac8676
+}
ac8676
+
ac8676
+int
ac8676
+vsf_sysutil_kill(int pid, int sig)
ac8676
+{
ac8676
+  int realsig = vsf_sysutil_translate_sig(sig);
ac8676
+  return kill(pid, realsig);
ac8676
+}
ac8676
+
ac8676
+int
ac8676
+vsf_sysutil_pause()
ac8676
+{
ac8676
+  return pause();
ac8676
+}
ac8676
diff -up vsftpd-2.1.1/sysutil.h.daemonize_plus vsftpd-2.1.1/sysutil.h
ac8676
--- vsftpd-2.1.1/sysutil.h.daemonize_plus	2009-05-10 22:11:24.000000000 +0200
ac8676
+++ vsftpd-2.1.1/sysutil.h	2009-05-10 22:11:24.000000000 +0200
ac8676
@@ -29,7 +29,8 @@ enum EVSFSysUtilSignal
ac8676
   kVSFSysUtilSigCHLD,
ac8676
   kVSFSysUtilSigPIPE,
ac8676
   kVSFSysUtilSigURG,
ac8676
-  kVSFSysUtilSigHUP
ac8676
+  kVSFSysUtilSigHUP,
ac8676
+  kVSFSysUtilSigUSR1
ac8676
 };
ac8676
 enum EVSFSysUtilInterruptContext
ac8676
 {
ac8676
@@ -165,6 +165,7 @@ void vsf_sysutil_free(void* p_ptr);
ac8676
 
ac8676
 /* Process creation/exit/process handling */
ac8676
 unsigned int vsf_sysutil_getpid(void);
ac8676
+unsigned int vsf_sysutil_getppid(void);
ac8676
 void vsf_sysutil_post_fork(void);
ac8676
 int vsf_sysutil_fork(void);
ac8676
 int vsf_sysutil_fork_failok(void);
ac8676
@@ -182,6 +184,9 @@ int vsf_sysutil_wait_exited_normally(
ac8676
   const struct vsf_sysutil_wait_retval* p_waitret);
ac8676
 int vsf_sysutil_wait_get_exitcode(
ac8676
   const struct vsf_sysutil_wait_retval* p_waitret);
ac8676
+void vsf_sysutil_sigaction(const enum EVSFSysUtilSignal sig, void (*p_handlefunc)(int));
ac8676
+int vsf_sysutil_kill(int pid, int sig);
ac8676
+int vsf_sysutil_pause();
ac8676
 
ac8676
 /* Various string functions */
ac8676
 unsigned int vsf_sysutil_strlen(const char* p_text);