You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by tr...@apache.org on 2009/10/06 01:32:16 UTC

svn commit: r822089 - in /httpd/mod_fcgid/trunk: ./ docs/manual/mod/ modules/fcgid/

Author: trawick
Date: Mon Oct  5 23:32:16 2009
New Revision: 822089

URL: http://svn.apache.org/viewvc?rev=822089&view=rev
Log:
Add a new directive FCGIDCmdOptions, allowing certain processing options to be
associated with a particular command instead of with any commands in a particular
context.

Modified:
    httpd/mod_fcgid/trunk/CHANGES-FCGID
    httpd/mod_fcgid/trunk/docs/manual/mod/mod_fcgid.xml
    httpd/mod_fcgid/trunk/modules/fcgid/fcgid_bridge.c
    httpd/mod_fcgid/trunk/modules/fcgid/fcgid_conf.c
    httpd/mod_fcgid/trunk/modules/fcgid/fcgid_conf.h
    httpd/mod_fcgid/trunk/modules/fcgid/fcgid_pm_unix.c
    httpd/mod_fcgid/trunk/modules/fcgid/fcgid_pm_win.c
    httpd/mod_fcgid/trunk/modules/fcgid/mod_fcgid.c

Modified: httpd/mod_fcgid/trunk/CHANGES-FCGID
URL: http://svn.apache.org/viewvc/httpd/mod_fcgid/trunk/CHANGES-FCGID?rev=822089&r1=822088&r2=822089&view=diff
==============================================================================
--- httpd/mod_fcgid/trunk/CHANGES-FCGID [utf8] (original)
+++ httpd/mod_fcgid/trunk/CHANGES-FCGID [utf8] Mon Oct  5 23:32:16 2009
@@ -1,6 +1,8 @@
                                                          -*- coding: utf-8 -*-
 Changes with mod_fcgid 2.3.3
 
+  *) Add FCGIDCmdOptions directive.  [Jeff Trawick]
+
   *) Allow/respect virtual host settings for the following directives:
      FCGIDBusyTimeout, FCGIDDefaultMaxClassProcessCount, 
      FCGIDDefaultMinClassProcessCount, FCGIDIdleTimeout, and 

Modified: httpd/mod_fcgid/trunk/docs/manual/mod/mod_fcgid.xml
URL: http://svn.apache.org/viewvc/httpd/mod_fcgid/trunk/docs/manual/mod/mod_fcgid.xml?rev=822089&r1=822088&r2=822089&view=diff
==============================================================================
--- httpd/mod_fcgid/trunk/docs/manual/mod/mod_fcgid.xml (original)
+++ httpd/mod_fcgid/trunk/docs/manual/mod/mod_fcgid.xml Mon Oct  5 23:32:16 2009
@@ -609,6 +609,85 @@
   </directivesynopsis>
 
   <directivesynopsis>
+    <name>FCGIDCmdOptions</name>
+    <description>Set processing options for a FastCGI
+    command</description>
+    <syntax>FCGIDCmdOptions <em>command</em> <em>option</em>
+    [<em>option</em>] ...</syntax>
+    <contextlist><context>server config</context> <context>virtual host</context></contextlist>
+    <usage>
+      <p>This directive allows processing options to be specified for
+      a specific command spawned by mod_fcgid.  Each option for the
+      command corresponds to another directive that normally applies to
+      all commands started within a particular context.  If a
+      particular option is not specified on this directive, the
+      default will be used.</p>
+
+      <p>The following table provides a list of options and
+      corresponding directives:</p>
+
+      <table border="1" style="zebra">
+        <tr><th>Option name and syntax</th><th>Corresponding directive</th></tr>
+        <tr>
+          <td><code>ConnectTimeout <em>seconds</em></code></td>
+          <td><directive module="mod_fcgid">FCGIDIPCConnectTimeout</directive></td>
+        </tr>
+        <tr>
+          <td><code>IdleTimeout <em>seconds</em></code></td>
+          <td><directive module="mod_fcgid">FCGIDIdleTimeout</directive></td>
+        </tr>
+        <tr>
+          <td><code>InitialEnv <em>name[=value]</em></code></td>
+          <td><directive module="mod_fcgid">FCGIDDefaultInitEnv</directive></td>
+        </tr>
+        <tr>
+          <td><code>IOTimeout <em>seconds</em></code></td>
+          <td><directive module="mod_fcgid">FCGIDIPCCommTimeout</directive></td>
+        </tr>
+        <tr>
+          <td><code>MaxProcesses <em>value</em></code></td>
+          <td><directive module="mod_fcgid">FCGIDDefaultMaxClassProcessCount</directive></td>
+        </tr>
+        <tr>
+          <td><code>MaxProcessLifeTime <em>seconds</em></code></td>
+          <td><directive module="mod_fcgid">FCGIDProcessLifeTime</directive></td>
+        </tr>
+        <tr>
+          <td><code>MaxRequestsPerProcess <em>value</em></code></td>
+          <td><directive module="mod_fcgid">FCGIDMaxRequestsPerProcess</directive></td>
+        </tr>
+        <tr>
+          <td><code>MinProcesses <em>value</em></code></td>
+          <td><directive module="mod_fcgid">FCGIDDefaultMinClassProcessCount</directive></td>
+        </tr>
+      </table>
+
+      <p>Multiple environment variables are defined by repeating
+      the <code>InitialEnv</code> option.</p>
+
+      <example><title>Example</title>
+      FCGIDCmdOptions /usr/local/bin/wrapper \<br />
+      <indent>
+      InitialEnv MAX_REQUESTS=2000 \<br />
+      MaxRequestsPerProcess 2000 \<br />
+      IOTimeout 90<br />
+      </indent>
+      </example>
+
+      <p>When <code>/usr/local/bin/wrapper</code> is spawned, its initial
+      environment contains the <code>MAX_REQUESTS=2000</code>
+      environment variable setting; additionally, mod_fcgid will
+      terminate it after it has handled 2000 requests, and I/O
+      operations will time out after 90 seconds.  Directives
+      corresponding to other options, such as 
+      <directive module="mod_fcgid">FCGIDIdleTimeout</directive> or
+      <directive module="mod_fcgid">FCGIDProcessLifeTime</directive>,
+      will be ignored for this command; defaults will be used for options
+      not specified on <directive>FCGIDCmdOptions</directive>.</p>
+    </usage>
+  </directivesynopsis>
+
+  <directivesynopsis>
     <name>FCGIDDefaultInitEnv</name>
     <description>an environment variable name and optional value to pass to FastCGI.</description>
     <syntax>FCGIDDefaultInitEnv <em>name</em> [ <em>value</em> ]</syntax>

Modified: httpd/mod_fcgid/trunk/modules/fcgid/fcgid_bridge.c
URL: http://svn.apache.org/viewvc/httpd/mod_fcgid/trunk/modules/fcgid/fcgid_bridge.c?rev=822089&r1=822088&r2=822089&view=diff
==============================================================================
--- httpd/mod_fcgid/trunk/modules/fcgid/fcgid_bridge.c (original)
+++ httpd/mod_fcgid/trunk/modules/fcgid/fcgid_bridge.c Mon Oct  5 23:32:16 2009
@@ -195,9 +195,9 @@
             ctx->procnode->diewhy = FCGID_DIE_COMM_ERROR;
             return_procnode(s, ctx->procnode,
                             1 /* communication error */ );
-        } else if (sconf->max_requests_per_process
+        } else if (ctx->procnode->cmdopts.max_requests_per_process
                    && ++ctx->procnode->requests_handled >=
-                   sconf->max_requests_per_process) {
+                   ctx->procnode->cmdopts.max_requests_per_process) {
             ctx->procnode->diewhy = FCGID_DIE_LIFETIME_EXPIRED;
             return_procnode(s, ctx->procnode,
                             1 /* handled all requests */ );
@@ -292,9 +292,6 @@
                apr_bucket_brigade * output_brigade)
 {
     apr_pool_t *request_pool = r->main ? r->main->pool : r->pool;
-    server_rec *s = r->server;
-    fcgid_server_conf *sconf = ap_get_module_config(s->module_config,
-                                                    &fcgid_module);
     fcgid_command fcgi_request;
     fcgid_bucket_ctx *bucket_ctx;
     int i, j, cond_status;
@@ -304,8 +301,6 @@
     const char *location;
 
     bucket_ctx = apr_pcalloc(request_pool, sizeof(*bucket_ctx));
-    bucket_ctx->ipc.connect_timeout = sconf->ipc_connect_timeout;
-    bucket_ctx->ipc.communation_timeout = sconf->ipc_comm_timeout;
 
     bucket_ctx->ipc.request = r;
     apr_pool_cleanup_register(request_pool, bucket_ctx,
@@ -326,6 +321,11 @@
             procmgr_init_spawn_cmd(&fcgi_request, r, argv0, deviceid,
                                    inode, shareid);
 
+            bucket_ctx->ipc.connect_timeout =
+                fcgi_request.cmdopts.ipc_connect_timeout;
+            bucket_ctx->ipc.communation_timeout =
+                fcgi_request.cmdopts.ipc_comm_timeout;
+
             /* Apply a process slot */
             bucket_ctx->procnode =
                 apply_free_procnode(r->server, &fcgi_request);

Modified: httpd/mod_fcgid/trunk/modules/fcgid/fcgid_conf.c
URL: http://svn.apache.org/viewvc/httpd/mod_fcgid/trunk/modules/fcgid/fcgid_conf.c?rev=822089&r1=822088&r2=822089&view=diff
==============================================================================
--- httpd/mod_fcgid/trunk/modules/fcgid/fcgid_conf.c (original)
+++ httpd/mod_fcgid/trunk/modules/fcgid/fcgid_conf.c Mon Oct  5 23:32:16 2009
@@ -77,6 +77,7 @@
      * config->php_fix_pathinfo_enable = 0;
      * config->*_set = 0;
      */
+    config->cmdopts_hash = apr_hash_make(p);
     config->ipc_comm_timeout = DEFAULT_IPC_COMM_TIMEOUT;
     config->ipc_connect_timeout = DEFAULT_IPC_CONNECT_TIMEOUT;
     config->max_mem_request_len = DEFAULT_MAX_MEM_REQUEST_LEN;
@@ -104,6 +105,9 @@
     fcgid_server_conf *merged =
       (fcgid_server_conf *) apr_pmemdup(p, local, sizeof(fcgid_server_conf));
 
+    merged->cmdopts_hash = apr_hash_overlay(p, local->cmdopts_hash,
+                                            base->cmdopts_hash);
+
     /* Merge environment variables */
     if (base->default_init_env == NULL) {
         /* merged already set to local */
@@ -538,6 +542,19 @@
     return NULL;
 }
 
+static void add_envvar_to_table(apr_table_t *t, apr_pool_t *p,
+                                const char *name, const char *value)
+{
+#if defined(WIN32) || defined(OS2) || defined(NETWARE)
+    /* Case insensitive environment platforms */
+    char *pstr;
+    for (name = pstr = apr_pstrdup(p, name); *pstr; ++pstr) {
+        *pstr = apr_toupper(*pstr);
+    }
+#endif
+    apr_table_set(t, name, value ? value : "");
+}
+                                
 const char *add_default_env_vars(cmd_parms * cmd, void *dummy,
                                  const char *name, const char *value)
 {
@@ -545,15 +562,8 @@
         ap_get_module_config(cmd->server->module_config, &fcgid_module);
     if (config->default_init_env == NULL)
         config->default_init_env = apr_table_make(cmd->pool, 20);
-#if defined(WIN32) || defined(OS2) || defined(NETWARE)
-    /* Case insensitive environment platforms */
-    {
-        char *pstr;
-        for (name = pstr = apr_pstrdup(cmd->pool, name); *pstr; ++pstr)
-            *pstr = apr_toupper(*pstr);
-    }
-#endif
-    apr_table_set(config->default_init_env, name, value ? value : "");
+
+    add_envvar_to_table(config->default_init_env, cmd->pool, name, value);
     return NULL;
 }
 
@@ -855,41 +865,27 @@
     return NULL;
 }
 
-void get_cmd_options(request_rec *r, fcgid_cmd_options *cmdopts)
+static int set_cmd_envvars(fcgid_cmd_options *cmdopts, apr_table_t *envvars)
 {
-    fcgid_server_conf *sconf =
-        ap_get_module_config(r->server->module_config, &fcgid_module);
-    apr_table_t *initenv = sconf->default_init_env;
-    const apr_array_header_t *initenv_arr;
-    const apr_table_entry_t *initenv_entry;
+    const apr_array_header_t *envvars_arr;
+    const apr_table_entry_t *envvars_entry;
     int i;
-    
-    cmdopts->busy_timeout = sconf->busy_timeout;
-    cmdopts->idle_timeout = sconf->idle_timeout;
-    cmdopts->max_class_process_count = sconf->max_class_process_count;
-    cmdopts->min_class_process_count = sconf->min_class_process_count;
-    cmdopts->proc_lifetime = sconf->proc_lifetime;
+    int overflow = 0;
+
+    if (envvars) {
+        envvars_arr = apr_table_elts(envvars);
+        envvars_entry = (apr_table_entry_t *) envvars_arr->elts;
+        if (envvars_arr->nelts > INITENV_CNT) {
+            overflow = envvars_arr->nelts - INITENV_CNT;
+        }
 
-    /* Environment variables */
-    if (initenv) {
-        initenv_arr = apr_table_elts(initenv);
-        initenv_entry = (apr_table_entry_t *) initenv_arr->elts;
-        if (initenv_arr->nelts > INITENV_CNT) {
-            ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
-                          "mod_fcgid: %d environment variables dropped; increase "
-                          "INITENV_CNT in fcgid_pm.h from %d to at least %d",
-                          initenv_arr->nelts - INITENV_CNT,
-                          INITENV_CNT,
-                          initenv_arr->nelts);
-        }
-
-        for (i = 0; i < initenv_arr->nelts && i < INITENV_CNT; ++i) {
-            if (initenv_entry[i].key == NULL
-                || initenv_entry[i].key[0] == '\0')
+        for (i = 0; i < envvars_arr->nelts && i < INITENV_CNT; ++i) {
+            if (envvars_entry[i].key == NULL
+                || envvars_entry[i].key[0] == '\0')
                 break;
-            apr_cpystrn(cmdopts->initenv_key[i], initenv_entry[i].key,
+            apr_cpystrn(cmdopts->initenv_key[i], envvars_entry[i].key,
                         INITENV_KEY_LEN);
-            apr_cpystrn(cmdopts->initenv_val[i], initenv_entry[i].val,
+            apr_cpystrn(cmdopts->initenv_val[i], envvars_entry[i].val,
                         INITENV_VAL_LEN);
         }
         if (i < INITENV_CNT) {
@@ -899,4 +895,195 @@
     else {
         cmdopts->initenv_key[0][0] = '\0';
     }
+
+    return overflow;
+}
+
+const char *set_cmd_options(cmd_parms *cmd, void *dummy, const char *args)
+{
+    server_rec *s = cmd->server;
+    fcgid_server_conf *sconf =
+        ap_get_module_config(s->module_config, &fcgid_module);
+    const char *cmdname;
+    fcgid_cmd_options *cmdopts;
+    apr_table_t *envvars = NULL;
+    int overflow;
+    apr_finfo_t finfo;
+    apr_status_t rv;
+
+    cmdopts = apr_pcalloc(cmd->pool, sizeof *cmdopts);
+
+    cmdopts->busy_timeout = DEFAULT_BUSY_TIMEOUT;
+    cmdopts->idle_timeout = DEFAULT_IDLE_TIMEOUT;
+    cmdopts->ipc_comm_timeout = DEFAULT_IPC_COMM_TIMEOUT;
+    cmdopts->ipc_connect_timeout = DEFAULT_IPC_CONNECT_TIMEOUT;
+    cmdopts->max_class_process_count = DEFAULT_MAX_CLASS_PROCESS_COUNT;
+    cmdopts->max_requests_per_process = DEFAULT_MAX_REQUESTS_PER_PROCESS;
+    cmdopts->min_class_process_count = DEFAULT_MIN_CLASS_PROCESS_COUNT;
+    cmdopts->proc_lifetime = DEFAULT_PROC_LIFETIME;
+    /* via pcalloc: cmdopts->initenv_key[0][0] = '\0'; */
+    
+    cmdname = ap_getword_conf(cmd->pool, &args);
+    if (!strlen(cmdname)) {
+        return "A command must be specified for FCGIDCmdOptions";
+    }
+
+    rv = apr_stat(&finfo, cmdname, APR_FINFO_NORM, cmd->temp_pool);
+    if (rv != APR_SUCCESS) {
+        return apr_psprintf(cmd->pool,
+                            "File %s does not exist or cannot be accessed (error %d)",
+                            cmdname, rv);
+    }
+
+    if (!*args) {
+        return "At least one option must be specified for FCGIDCmdOptions";
+    }
+
+    while (*args) {
+        const char *option = ap_getword_white(cmd->pool, &args);
+        const char *val;
+
+        /* don't support BusyTimeout until BZ #47483 is fixed
+         * (The kludge in bucket_ctx_cleanup wouldn't have addressibility
+         * to the cmd-specific busy timeout setting.)
+         */
+
+        if (!strcasecmp(option, "ConnectTimeout")) {
+            val = ap_getword_white(cmd->pool, &args);
+            if (!strlen(val)) {
+                return "ConnectTimeout must have an argument";
+            }
+            cmdopts->ipc_connect_timeout = atoi(val);
+            continue;
+        }
+            
+        if (!strcasecmp(option, "IdleTimeout")) {
+            val = ap_getword_white(cmd->pool, &args);
+            if (!strlen(val)) {
+                return "IdleTimeout must have an argument";
+            }
+            cmdopts->idle_timeout = atoi(val);
+            continue;
+        }
+
+        if (!strcasecmp(option, "InitialEnv")) {
+            char *name;
+            char *eql;
+
+            name = ap_getword_white(cmd->pool, &args);
+            if (!strlen(name)) {
+                return "InitialEnv must have an argument";
+            }
+
+            eql = strchr(name, '=');
+            if (eql) {
+                *eql = '\0';
+                ++eql;
+            }
+
+            if (!envvars) {
+                envvars = apr_table_make(cmd->pool, 20);
+            }
+            add_envvar_to_table(envvars, cmd->pool, name, eql);
+            continue;
+        }
+
+        if (!strcasecmp(option, "IOTimeout")) {
+            val = ap_getword_white(cmd->pool, &args);
+            if (!strlen(val)) {
+                return "IOTimeout must have an argument";
+            }
+            cmdopts->ipc_comm_timeout = atoi(val);
+            continue;
+        }
+            
+        if (!strcasecmp(option, "MaxProcesses")) {
+            val = ap_getword_white(cmd->pool, &args);
+            if (!strlen(val)) {
+                return "MaxProcesses must have an argument";
+            }
+            cmdopts->max_class_process_count = atoi(val);
+            continue;
+        }
+
+        if (!strcasecmp(option, "MaxProcessLifetime")) {
+            val = ap_getword_white(cmd->pool, &args);
+            if (!strlen(val)) {
+                return "MaxProcessLifetime must have an argument";
+            }
+            cmdopts->proc_lifetime = atoi(val);
+            continue;
+        }
+
+        if (!strcasecmp(option, "MaxRequestsPerProcess")) {
+            val = ap_getword_white(cmd->pool, &args);
+            if (!strlen(val)) {
+                return "MaxRequestsPerProcess must have an argument";
+            }
+            cmdopts->max_requests_per_process = atoi(val);
+            continue;
+        }
+
+        if (!strcasecmp(option, "MinProcesses")) {
+            val = ap_getword_white(cmd->pool, &args);
+            if (!strlen(val)) {
+                return "MinProcesses must have an argument";
+            }
+            cmdopts->min_class_process_count = atoi(val);
+            continue;
+        }
+
+        return apr_psprintf(cmd->pool,
+                            "Invalid option for FCGIDCommandOptions: %s",
+                            option);
+    }
+
+    if ((overflow = set_cmd_envvars(cmdopts, envvars)) != 0) {
+        return apr_psprintf(cmd->pool, "mod_fcgid: environment variable table "
+                            "overflow; increase INITENV_CNT in fcgid_pm.h from"
+                            " %d to at least %d",
+                            INITENV_CNT, INITENV_CNT + overflow);
+    }
+
+    apr_hash_set(sconf->cmdopts_hash, cmdname, strlen(cmdname), cmdopts);
+
+    return NULL;
+}
+
+void get_cmd_options(request_rec *r, const char *cmdpath,
+                     fcgid_cmd_options *cmdopts)
+{
+    fcgid_server_conf *sconf =
+        ap_get_module_config(r->server->module_config, &fcgid_module);
+    fcgid_cmd_options *cmd_specific = apr_hash_get(sconf->cmdopts_hash,
+                                                   cmdpath,
+                                                   strlen(cmdpath));
+    int overflow;
+
+    if (cmd_specific) { /* ignore request context configuration */
+        *cmdopts = *cmd_specific;
+        /* pick up configuration for values that can't be configured
+         * on FCGIDCmdOptions
+         */
+        cmdopts->busy_timeout = sconf->busy_timeout;
+        return;
+    }
+
+    cmdopts->busy_timeout = sconf->busy_timeout;
+    cmdopts->idle_timeout = sconf->idle_timeout;
+    cmdopts->ipc_comm_timeout = sconf->ipc_comm_timeout;
+    cmdopts->ipc_connect_timeout = sconf->ipc_connect_timeout;
+    cmdopts->max_class_process_count = sconf->max_class_process_count;
+    cmdopts->max_requests_per_process = sconf->max_requests_per_process;
+    cmdopts->min_class_process_count = sconf->min_class_process_count;
+    cmdopts->proc_lifetime = sconf->proc_lifetime;
+
+    if ((overflow = set_cmd_envvars(cmdopts, sconf->default_init_env)) != 0) {
+        ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
+                      "mod_fcgid: %d environment variables dropped; increase "
+                      "INITENV_CNT in fcgid_pm.h from %d to at least %d",
+                      overflow,
+                      INITENV_CNT,
+                      INITENV_CNT + overflow);
+    }
 }

Modified: httpd/mod_fcgid/trunk/modules/fcgid/fcgid_conf.h
URL: http://svn.apache.org/viewvc/httpd/mod_fcgid/trunk/modules/fcgid/fcgid_conf.h?rev=822089&r1=822088&r2=822089&view=diff
==============================================================================
--- httpd/mod_fcgid/trunk/modules/fcgid/fcgid_conf.h (original)
+++ httpd/mod_fcgid/trunk/modules/fcgid/fcgid_conf.h Mon Oct  5 23:32:16 2009
@@ -63,6 +63,7 @@
 
 typedef struct {
     /* global only */
+    apr_hash_t *cmdopts_hash;
     int busy_scan_interval;
     int error_scan_interval;
     int idle_scan_interval;
@@ -126,14 +127,19 @@
     int access_authoritative_set;
 } fcgid_dir_conf;
 
-/* processing options which are sent to the PM with a spawn request */
+/* processing options which are sent to the PM with a spawn request
+ * and/or configurable via FCGIDCmdOptions
+ */
 #define INITENV_KEY_LEN 64
 #define INITENV_VAL_LEN 128
 #define INITENV_CNT 64
 typedef struct {
     int busy_timeout;
     int idle_timeout;
+    int ipc_comm_timeout;
+    int ipc_connect_timeout;
     int max_class_process_count;
+    int max_requests_per_process;
     int min_class_process_count;
     int proc_lifetime;
     char initenv_key[INITENV_CNT][INITENV_KEY_LEN];
@@ -242,7 +248,11 @@
 const char *set_max_requests_per_process(cmd_parms * cmd, void *dummy,
                                          const char *arg);
 
-void get_cmd_options(request_rec *r, fcgid_cmd_options *cmdopts);
+const char *set_cmd_options(cmd_parms *cmd, void *dummy,
+                            const char *arg);
+
+void get_cmd_options(request_rec *r, const char *cmdpath,
+                     fcgid_cmd_options *cmdopts);
 
 AP_MODULE_DECLARE_DATA extern module fcgid_module;
 

Modified: httpd/mod_fcgid/trunk/modules/fcgid/fcgid_pm_unix.c
URL: http://svn.apache.org/viewvc/httpd/mod_fcgid/trunk/modules/fcgid/fcgid_pm_unix.c?rev=822089&r1=822088&r2=822089&view=diff
==============================================================================
--- httpd/mod_fcgid/trunk/modules/fcgid/fcgid_pm_unix.c (original)
+++ httpd/mod_fcgid/trunk/modules/fcgid/fcgid_pm_unix.c Mon Oct  5 23:32:16 2009
@@ -389,6 +389,7 @@
 {
     ap_unix_identity_t *ugid;
     fcgid_wrapper_conf *wrapperconf;
+    const char *cmd_to_spawn;
 
     memset(command, 0, sizeof(*command));
 
@@ -416,9 +417,13 @@
         command->deviceid = wrapperconf->deviceid;
         command->inode = wrapperconf->inode;
         command->share_grp_id = wrapperconf->share_group_id;
+        cmd_to_spawn = command->wrapperpath;
+    }
+    else {
+        cmd_to_spawn = command->cgipath;
     }
 
-    get_cmd_options(r, &command->cmdopts);
+    get_cmd_options(r, cmd_to_spawn, &command->cmdopts);
 }
 
 apr_status_t procmgr_post_spawn_cmd(fcgid_command * command,

Modified: httpd/mod_fcgid/trunk/modules/fcgid/fcgid_pm_win.c
URL: http://svn.apache.org/viewvc/httpd/mod_fcgid/trunk/modules/fcgid/fcgid_pm_win.c?rev=822089&r1=822088&r2=822089&view=diff
==============================================================================
--- httpd/mod_fcgid/trunk/modules/fcgid/fcgid_pm_win.c (original)
+++ httpd/mod_fcgid/trunk/modules/fcgid/fcgid_pm_win.c Mon Oct  5 23:32:16 2009
@@ -126,6 +126,7 @@
                             apr_ino_t inode, apr_size_t share_grp_id)
 {
     fcgid_wrapper_conf *wrapperconf;
+    const char *cmd_to_spawn;
 
     memset(command, 0, sizeof(*command));
 
@@ -145,9 +146,13 @@
         command->deviceid = wrapperconf->deviceid;
         command->inode = wrapperconf->inode;
         command->share_grp_id = wrapperconf->share_group_id;
+        cmd_to_spawn = command->wrapperpath;
+    }
+    else {
+        cmd_to_spawn = command->cgipath;
     }
 
-    get_cmd_options(r, &command->cmdopts);
+    get_cmd_options(r, cmd_to_spawn, &command->cmdopts);
 }
 
 apr_status_t procmgr_post_spawn_cmd(fcgid_command * command,

Modified: httpd/mod_fcgid/trunk/modules/fcgid/mod_fcgid.c
URL: http://svn.apache.org/viewvc/httpd/mod_fcgid/trunk/modules/fcgid/mod_fcgid.c?rev=822089&r1=822088&r2=822089&view=diff
==============================================================================
--- httpd/mod_fcgid/trunk/modules/fcgid/mod_fcgid.c (original)
+++ httpd/mod_fcgid/trunk/modules/fcgid/mod_fcgid.c Mon Oct  5 23:32:16 2009
@@ -618,6 +618,8 @@
                   "scan interval for busy timeout process"),
     AP_INIT_TAKE1("FCGIDBusyTimeout", set_busy_timeout, NULL, RSRC_CONF,
                   "a fastcgi application will be killed after handling a request for BusyTimeout"),
+    AP_INIT_RAW_ARGS("FCGIDCmdOptions", set_cmd_options, NULL, RSRC_CONF,
+                     "set processing options for a FastCGI command"),
     AP_INIT_TAKE12("FCGIDDefaultInitEnv", add_default_env_vars, NULL, RSRC_CONF,
                    "an environment variable name and optional value to pass to FastCGI."),
     AP_INIT_TAKE1("FCGIDDefaultMaxClassProcessCount",