Re: daemontools/foreground support in 1.3.*

2002-02-28 Thread Mike Gerdts

On Thu, 2002-02-28 at 04:00, Michael Handler wrote:
> 
> This is a tiny change, and the functionality already exists in 2.0.
> Lots of sysadmins are going to be stuck with 1.3.* for a while from
> now, and this is a clear benefit to those of us who utilize
> daemontools, without causing any harm to anyone.

> Am I reaching anyone here, or should I just be quiet?

This is a useful patch.  So useful to me that I just wrote an equivalent
one yesterday.  This is one time that I really should have read the list
archives before I started hacking.

http://marc.theaimsgroup.com/?l=apache-new-httpd&m=101484615220466&w=2

My aim was only for Cygwin, but should work on most unix-like platforms
with the removal of some ifdefs.  The implementation in
daemontools.patch appears to be a bit cleaner than the one I submitted.

Also, the patch that was put in place at
http://www.apache.org/dist/httpd/contrib/patches/1.3/daemontools.patch
is not readable.  Could someone do a chmod a+r on it?

Mike





[PATCH] Allow foreground operation without -X implications

2002-02-27 Thread Mike Gerdts

Under Cygwin, the apparent method to run a service is using
cygrunsrv.exe.  Unfortunately cygrunsrv's method of detecting if the
service stayed running or not is based on whether the process that it
spawned is still running or not.

The patch below adds an option -W (cygwin only) that modifies the
behavior of detach().  With this patch, httpd -W will keep an httpd
process running just waiting for httpd to exit or for it to be signalled
by cygrunsrv to shut down the service.

The only other behavior change that is introduced is SIGUSR2 is now
caught and ignored.  This is used to work around an apparent bug in
cygwin's waitpid() when the child process dies in a non-graceful way
(kill -9).

I welcome all comments.
Mike


Index: main/http_main.c
===
RCS file: /home/cvspublic/apache-1.3/src/main/http_main.c,v
retrieving revision 1.576
diff -c -r1.576 http_main.c
*** main/http_main.c26 Feb 2002 15:04:53 -  1.576
--- main/http_main.c27 Feb 2002 21:31:28 -
***
*** 341,346 
--- 341,357 
  
  static int one_process = 0;
  
+ /* parent_wait --- when running as a service under Cygwin, the first process
+  * should not die else cygrunsrv thinks that httpd has died when in reality it 
+  * has just gone into the background.  When parent_wait is non-zero
+  * (-W option, compiled under Cygnus only) the parent sits around just
+  * waiting for its first child to die.
+  */
+ 
+ #if defined(CYGWIN)
+ static int parent_wait = 0;
+ #endif
+ 
  /* set if timeouts are to be handled by the children and not by the parent.
   * i.e. child_timeouts = !standalone || one_process.
   */
***
*** 396,401 
--- 407,434 
  /* Global, alas, so http_core can talk to us */
  enum server_token_type ap_server_tokens = SrvTk_FULL;
  
+ /* parentwait_pid --- contains the PID of the master httpd so that kill
+  * signals sent from cygrunsrv to httpd can be delivered to the master
+  * httpd.  Only used when compiled under Cygnus and the -W runtime flag
+  * is used.
+  */
+ #if defined(CYGWIN)
+ static pid_t parentwait_pid;
+ #endif
+ 
+ /* 
+  * This is a signal handler that passes signals on from cygrunsrv to the
+  * master httpd..  Only used when compiled under Cygnus and the -W 
+  * runtime flag is used.
+  */
+ #if defined(CYGWIN)
+ static void parentwait_kill(int signum) {
+ printf("Caught signal %d and passing it on to pid %d\n",
+   parentwait_pid, signum);
+ kill(parentwait_pid, signum);
+ }
+ #endif
+ 
  /*
   * This routine is called when the pconf pool is vacuumed.  It resets the
   * server version string to a known value and [re]enables modifications
***
*** 1358,1363 
--- 1391,1399 
  #endif
  fprintf(stderr, "   %s [-C \"directive\"] [-c \"directive\"]\n", pad);
  fprintf(stderr, "   %s [-v] [-V] [-h] [-l] [-L] [-S] [-t] [-T]\n", pad);
+ #if defined(CYGWIN)
+ fprintf(stderr, "   %s [-W]\n", pad);
+ #endif
  fprintf(stderr, "Options:\n");
  #ifdef SHARED_CORE
  fprintf(stderr, "  -R directory : specify an alternate location for shared 
object files\n");
***
*** 1389,1394 
--- 1425,1434 
  fprintf(stderr, "  -k uninstall | -u: uninstall an Apache service\n");
  fprintf(stderr, "  -W service   : after -k config|install; Apache starts 
after 'service'\n");
  fprintf(stderr, "  -w   : holds the window open for 30 seconds for 
fatal errors.\n");
+ #else /* !WIN32 */
+ #if defined(CYGWIN)
+ fprintf(stderr, "  -W   : one process just waits for signals from 
+cygrunsrv\n");
+ #endif
  #endif
  
  #if defined(NETWARE)
***
*** 3369,3376 
  !defined(BONE)
  /* Don't detach for MPE because child processes can't survive the death of
 the parent. */
! if ((x = fork()) > 0)
exit(0);
  else if (x == -1) {
perror("fork");
fprintf(stderr, "%s: unable to fork new process\n", ap_server_argv0);
--- 3409,3469 
  !defined(BONE)
  /* Don't detach for MPE because child processes can't survive the death of
 the parent. */
! #if defined(CYGWIN)
! if ( parent_wait ) {
!   signal(SIGUSR2, SIG_IGN);
! }
! #endif
! if ((x = fork()) > 0) {
! #if defined(CYGWIN)
! int status, exitval = 0;
! if ( parent_wait == 0 ) {
! exit(0);
! }
! parentwait_pid = x;
! signal(SIGHUP, parentwait_kill);
! signal(SIGINT, parentwait_kill);
! signal(SIGQUIT, parentwait_kill);
! signal(SIGTERM, parentwait_kill);
!   while ( 1 ) {
! waitpid(x, &status, WNOHANG);
! if ( WIFEXITED(status) ) {
! exitval = WEXITSTATUS(status);
! printf("Child pid %d exited with status %d\n", x, exitval);
!   if ( WIFSIGNALED(status) ) {
!   printf("Child pid %d received signal %d\n", x, 
!