From: Garrett Rooney Date: Tue, 7 Mar 2006 04:37:02 +0000 (+0000) Subject: Add support for starting multiple fastcgi processes listening on a X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9340c8c658546e1404f60a9a3bba759072261e5b;p=thirdparty%2Fapache%2Fhttpd.git Add support for starting multiple fastcgi processes listening on a given socket. This somewhat makes up for our lack of a good way to manage connections to a given proxy backend. * support/fcgistarter.c (main): Accept a new -N option that controls how many child procs we fork off. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/fcgi-proxy-dev@383774 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/support/fcgistarter.c b/support/fcgistarter.c index 8ee79a69acc..ad9b9e54906 100644 --- a/support/fcgistarter.c +++ b/support/fcgistarter.c @@ -29,12 +29,14 @@ #include /* For execl */ #endif +static const char *usage_message = + "usage: fcgistarter -c -p [-i -N ]\n" + "\n" + "If an interface is not specified, any available will be used.\n"; + static void usage() { - fprintf(stderr, - "usage: fcgistarter -c -p [-i ]\n" - "\n" - "If an interface is not specified, any available will be used.\n"); + fprintf(stderr, "%s", usage_message); exit(EXIT_FAILURE); } @@ -64,9 +66,9 @@ int main(int argc, const char *argv[]) /* Command line arguments */ + int num_to_start = 1, port = 0; const char *interface = NULL; const char *command = NULL; - int port = 0; apr_initialize(); @@ -83,7 +85,7 @@ int main(int argc, const char *argv[]) const char *arg; char opt; - rv = apr_getopt(gopt, "c:p:i:", &opt, &arg); + rv = apr_getopt(gopt, "c:p:i:N:", &opt, &arg); if (APR_STATUS_IS_EOF(rv)) { break; } else if (rv) { @@ -105,6 +107,13 @@ int main(int argc, const char *argv[]) interface = arg; break; + case 'N': + num_to_start = atoi(arg); + if (! num_to_start) { + usage(); + } + break; + default: break; } @@ -135,63 +144,68 @@ int main(int argc, const char *argv[]) exit_error(rv, "apr_socket_listen"); } - rv = apr_proc_fork(&proc, pool); - if (rv == APR_INCHILD) { - apr_os_file_t oft = 0; - apr_os_sock_t oskt; + while (--num_to_start >= 0) { + rv = apr_proc_fork(&proc, pool); + if (rv == APR_INCHILD) { + apr_os_file_t oft = 0; + apr_os_sock_t oskt; - rv = apr_proc_detach(APR_PROC_DETACH_DAEMONIZE); - if (rv) { - exit_error(rv, "apr_proc_detach"); - } + rv = apr_proc_detach(APR_PROC_DETACH_DAEMONIZE); + if (rv) { + exit_error(rv, "apr_proc_detach"); + } #if defined(WIN32) || defined(OS2) || defined(NETWARE) #error "Please implement me." #else - /* Ok, so we need a file that has file descriptor 0 (which - * FastCGI wants), but points to our socket. This isn't really - * possible in APR, so we cheat a bit. I have no idea how to - * do this on a non-unix platform, so for now this is platform - * specific. Ick. - * - * Note that this has to happen post-detach, otherwise fd 0 - * gets closed during apr_proc_detach and it's all for nothing. - * - * Unfortunately, doing this post detach means we have no way - * to let anyone know if there's a problem at this point :( */ - - rv = apr_os_file_put(&infd, &oft, APR_READ | APR_WRITE, pool); - if (rv) { - exit(EXIT_FAILURE); - } - rv = apr_os_sock_get(&oskt, skt); - if (rv) { - exit(EXIT_FAILURE); - } + /* Ok, so we need a file that has file descriptor 0 (which + * FastCGI wants), but points to our socket. This isn't really + * possible in APR, so we cheat a bit. I have no idea how to + * do this on a non-unix platform, so for now this is platform + * specific. Ick. + * + * Note that this has to happen post-detach, otherwise fd 0 + * gets closed during apr_proc_detach and it's all for nothing. + * + * Unfortunately, doing this post detach means we have no way + * to let anyone know if there's a problem at this point :( */ + + rv = apr_os_file_put(&infd, &oft, APR_READ | APR_WRITE, pool); + if (rv) { + exit(EXIT_FAILURE); + } - rv = apr_os_file_put(&skwrapper, &oskt, APR_READ | APR_WRITE, - pool); - if (rv) { - exit(EXIT_FAILURE); - } + rv = apr_os_sock_get(&oskt, skt); + if (rv) { + exit(EXIT_FAILURE); + } - rv = apr_file_dup2(infd, skwrapper, pool); - if (rv) { - exit(EXIT_FAILURE); - } + rv = apr_os_file_put(&skwrapper, &oskt, APR_READ | APR_WRITE, + pool); + if (rv) { + exit(EXIT_FAILURE); + } - /* XXX Can't use apr_proc_create because there's no way to get - * infd into the procattr without going through another dup2, - * which means by the time it gets to the fastcgi process it - * is no longer fd 0, so it doesn't work. Sigh. */ + rv = apr_file_dup2(infd, skwrapper, pool); + if (rv) { + exit(EXIT_FAILURE); + } + + /* XXX Can't use apr_proc_create because there's no way to get + * infd into the procattr without going through another dup2, + * which means by the time it gets to the fastcgi process it + * is no longer fd 0, so it doesn't work. Sigh. */ - execl(command, NULL); + execl(command, NULL); #endif - } else if (rv == APR_INPARENT) { - apr_socket_close(skt); - } else { - exit_error(rv, "apr_proc_fork"); + } else if (rv == APR_INPARENT) { + if (num_to_start == 0) { + apr_socket_close(skt); + } + } else { + exit_error(rv, "apr_proc_fork"); + } } return EXIT_SUCCESS;