On Thu, Dec 27, 2001 at 05:44:22PM -0800, Jos Backus wrote: > I'm willing to code a patch which allows Apache to run in the foreground in > its own session. Currently it kills the pgrp it is in even though it didn't > create it (bad practice imo - only destroy what you create). That is, if there > is any interest. A previous bugreport in this area was ignored so I may be > wasting my time. I'll interpret no response as ``no interest, go away''.
Hi Jos, This patch is a long time comming, but I think it's ready. I'd had to add error return values to the pre_config hook and fix some other signal-related bugs before this patch could be applied, but I think it's ready. Test it and give it your blessing. It is almost identical to the original patch you submitted, only that I flipped the polarity and the name of the new apr_proc_detach parameter from "dont_fork" to "daemonize", and then made the values #defined. Basicly what we have now is the following flags: -DNO_DETACH - assume we are not the process group leader, just create a new session (or pgrp if setsid() is not supported). This detaches us from the controlling terminal. [We don't "daemonize" so that process watchers can keep track of us directly.] -DONE_PROCESS - enables NO_DETACH, only runs one process in a multiprocess MPM <neither param> - same as NO_DETACH, only we always fork() before creating a new session. In APR I've called this "to daemonize". -aaron Index: server/mpm/beos/beos.c =================================================================== RCS file: /home/cvs/httpd-2.0/server/mpm/beos/beos.c,v retrieving revision 1.83 diff -u -r1.83 beos.c --- server/mpm/beos/beos.c 1 Feb 2002 22:16:31 -0000 1.83 +++ server/mpm/beos/beos.c 14 Feb 2002 22:51:14 -0000 @@ -1012,8 +1012,9 @@ if (restart_num++ == 1) { is_graceful = 0; - if (!one_process && !no_detach) { - rv = apr_proc_detach(); + if (!one_process) { + rv = apr_proc_detach(no_detach ? APR_PROC_DETACH_FOREGROUND + : APR_PROC_DETACH_DAEMONIZE); if (rv != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, "apr_proc_detach failed"); Index: server/mpm/perchild/perchild.c =================================================================== RCS file: /home/cvs/httpd-2.0/server/mpm/perchild/perchild.c,v retrieving revision 1.108 diff -u -r1.108 perchild.c --- server/mpm/perchild/perchild.c 5 Feb 2002 22:18:49 -0000 1.108 +++ server/mpm/perchild/perchild.c 14 Feb 2002 22:51:17 -0000 @@ -1473,8 +1473,9 @@ if (restart_num++ == 1) { is_graceful = 0; - if (!one_process && !no_detach) { - rv = apr_proc_detach(); + if (!one_process) { + rv = apr_proc_detach(no_detach ? APR_PROC_DETACH_FOREGROUND + : APR_PROC_DETACH_DAEMONIZE); if (rv != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, "apr_proc_detach failed"); Index: server/mpm/prefork/prefork.c =================================================================== RCS file: /home/cvs/httpd-2.0/server/mpm/prefork/prefork.c,v retrieving revision 1.241 diff -u -r1.241 prefork.c --- server/mpm/prefork/prefork.c 11 Feb 2002 23:20:15 -0000 1.241 +++ server/mpm/prefork/prefork.c 14 Feb 2002 22:51:17 -0000 @@ -1235,8 +1235,9 @@ if (restart_num++ == 1) { is_graceful = 0; - if (!one_process && !no_detach) { - rv = apr_proc_detach(); + if (!one_process) { + rv = apr_proc_detach(no_detach ? APR_PROC_DETACH_FOREGROUND + : APR_PROC_DETACH_DAEMONIZE); if (rv != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, "apr_proc_detach failed"); Index: server/mpm/worker/worker.c =================================================================== RCS file: /home/cvs/httpd-2.0/server/mpm/worker/worker.c,v retrieving revision 1.76 diff -u -r1.76 worker.c --- server/mpm/worker/worker.c 14 Feb 2002 02:48:19 -0000 1.76 +++ server/mpm/worker/worker.c 14 Feb 2002 22:51:19 -0000 @@ -1544,17 +1544,17 @@ } } else if (!max_clients - && strncasecmp(pdir->directive, "MaxClients", 10) == 0) { + && strncasecmp(pdir->directive, "MaxClients", 10) == 0) { max_clients = pdir; } } debug = ap_exists_config_define("DEBUG"); - if (debug) + if (debug) { no_detach = one_process = 1; - else - { + } + else { one_process = ap_exists_config_define("ONE_PROCESS"); no_detach = ap_exists_config_define("NO_DETACH"); } @@ -1563,8 +1563,9 @@ if (restart_num++ == 1) { is_graceful = 0; - if (!one_process && !no_detach) { - rv = apr_proc_detach(); + if (!one_process) { + rv = apr_proc_detach(no_detach ? APR_PROC_DETACH_FOREGROUND + : APR_PROC_DETACH_DAEMONIZE); if (rv != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, "apr_proc_detach failed"); Index: srclib/apr/include/apr_thread_proc.h =================================================================== RCS file: /home/cvs/apr/include/apr_thread_proc.h,v retrieving revision 1.79 diff -u -r1.79 apr_thread_proc.h --- srclib/apr/include/apr_thread_proc.h 28 Jan 2002 21:58:15 -0000 1.79 +++ srclib/apr/include/apr_thread_proc.h 14 Feb 2002 22:51:20 -0000 @@ -566,10 +566,16 @@ apr_wait_how_e waithow, apr_pool_t *p); +#define APR_PROC_DETACH_FOREGROUND 0 +#define APR_PROC_DETACH_DAEMONIZE 1 + /** * Detach the process from the controlling terminal. + * @param daemonize set to non-zero if the process should daemonize + * and become a background process, else it will + * stay in the foreground. */ -APR_DECLARE(apr_status_t) apr_proc_detach(void); +APR_DECLARE(apr_status_t) apr_proc_detach(int daemonize); #if APR_HAS_OTHER_CHILD Index: srclib/apr/threadproc/netware/procsup.c =================================================================== RCS file: /home/cvs/apr/threadproc/netware/procsup.c,v retrieving revision 1.1 diff -u -r1.1 procsup.c --- srclib/apr/threadproc/netware/procsup.c 2 Aug 2001 20:29:14 -0000 1.1 +++ srclib/apr/threadproc/netware/procsup.c 14 Feb 2002 22:51:20 -0000 @@ -54,7 +54,7 @@ #include "threadproc.h" -apr_status_t apr_proc_detach(void) +apr_status_t apr_proc_detach(int daemonize) { #if 0 int x; Index: srclib/apr/threadproc/os2/proc.c =================================================================== RCS file: /home/cvs/apr/threadproc/os2/proc.c,v retrieving revision 1.48 diff -u -r1.48 proc.c --- srclib/apr/threadproc/os2/proc.c 28 Jan 2002 21:58:15 -0000 1.48 +++ srclib/apr/threadproc/os2/proc.c 14 Feb 2002 22:51:20 -0000 @@ -622,7 +622,7 @@ -APR_DECLARE(apr_status_t) apr_proc_detach() +APR_DECLARE(apr_status_t) apr_proc_detach(int daemonize) { return APR_ENOTIMPL; } Index: srclib/apr/threadproc/unix/proc.c =================================================================== RCS file: /home/cvs/apr/threadproc/unix/proc.c,v retrieving revision 1.55 diff -u -r1.55 proc.c --- srclib/apr/threadproc/unix/proc.c 28 Jan 2002 21:58:15 -0000 1.55 +++ srclib/apr/threadproc/unix/proc.c 14 Feb 2002 22:51:21 -0000 @@ -362,26 +362,26 @@ } newargs[i + 2] = NULL; if (attr->detached) { - apr_proc_detach(); + apr_proc_detach(APR_PROC_DETACH_DAEMONIZE); } execve(SHELL_PATH, (char * const *) newargs, (char * const *)env); } else if (attr->cmdtype == APR_PROGRAM) { if (attr->detached) { - apr_proc_detach(); + apr_proc_detach(APR_PROC_DETACH_DAEMONIZE); } execve(progname, (char * const *)args, (char * const *)env); } else if (attr->cmdtype == APR_PROGRAM_ENV) { if (attr->detached) { - apr_proc_detach(); + apr_proc_detach(APR_PROC_DETACH_DAEMONIZE); } execv(progname, (char * const *)args); } else { /* APR_PROGRAM_PATH */ if (attr->detached) { - apr_proc_detach(); + apr_proc_detach(APR_PROC_DETACH_DAEMONIZE); } execvp(progname, (char * const *)args); } Index: srclib/apr/threadproc/unix/procsup.c =================================================================== RCS file: /home/cvs/apr/threadproc/unix/procsup.c,v retrieving revision 1.33 diff -u -r1.33 procsup.c --- srclib/apr/threadproc/unix/procsup.c 28 Dec 2001 19:03:48 -0000 1.33 +++ srclib/apr/threadproc/unix/procsup.c 14 Feb 2002 22:51:21 -0000 @@ -54,24 +54,28 @@ #include "threadproc.h" -APR_DECLARE(apr_status_t) apr_proc_detach(void) +APR_DECLARE(apr_status_t) apr_proc_detach(int daemonize) { int x; pid_t pgrp; chdir("/"); #if !defined(MPE) && !defined(OS2) && !defined(TPF) && !defined(BEOS) -/* 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, "unable to fork new process\n"); - exit(1); /* we can't do anything here, so just exit. */ + /* Don't detach for MPE because child processes can't survive the death of + * the parent. */ + if (daemonize) { + if ((x = fork()) > 0) { + exit(0); + } + else if (x == -1) { + perror("fork"); + fprintf(stderr, "unable to fork new process\n"); + exit(1); /* we can't do anything here, so just exit. */ + } + /* RAISE_SIGSTOP(DETACH); */ } -/* RAISE_SIGSTOP(DETACH);*/ #endif + #ifdef HAVE_SETSID if ((pgrp = setsid()) == -1) { return errno;