Came across something else in testing mod_fcgid. mod_fastcgi would consider every symbolic link to the same program as a unique program and would start it up based on the program name and not the inode/device node. Since mod_fcgid only was checking inode/device node, symbolic links were considered the same as the real program. Does anybody think that is a needed behaviour? Why would you rename the program name and still want to consider it the same program? Either way I made a patch that can retain the old behaviour via a directive. If it's decided that the old behaviour is unneeded I can take the directive out and make it respect program name by default. I included the patch for review and if every thing is cool I'll write the xml for the new directive.
Index: modules/fcgid/fcgid_pm_main.c =================================================================== --- modules/fcgid/fcgid_pm_main.c (revision 818854) +++ modules/fcgid/fcgid_pm_main.c (working copy) @@ -19,6 +19,7 @@ #define CORE_PRIVATE #include "httpd.h" #include "http_config.h" +#include "apr_strings.h" #include "fcgid_pm.h" #include "fcgid_pm_main.h" @@ -487,6 +488,10 @@ /* Prepare to spawn */ procnode->deviceid = command->deviceid; procnode->inode = command->inode; + apr_cpystrn(procnode->cgipath, command->cgipath, _POSIX_PATH_MAX); + if ((procnode->cgiNameOffset = (ap_strrchr_c(command->cgipath, '/') - command->cgipath)) < 0) { + procnode->cgiNameOffset = 0; + } procnode->share_grp_id = command->share_grp_id; procnode->virtualhost = command->virtualhost; procnode->uid = command->uid; @@ -561,8 +566,9 @@ /* Wait for command */ if (procmgr_peek_cmd(&command, main_server) == APR_SUCCESS) { - if (is_spawn_allowed(main_server, &command)) + if (is_spawn_allowed(main_server, &command)) { fastcgi_spawn(&command, main_server, configpool); + } procmgr_finish_notify(main_server); } Index: modules/fcgid/fcgid_conf.c =================================================================== --- modules/fcgid/fcgid_conf.c (revision 818854) +++ modules/fcgid/fcgid_conf.c (working copy) @@ -81,6 +81,7 @@ * config->default_init_env = NULL; * config->pass_headers = NULL; * config->php_fix_pathinfo_enable = 0; + * config->cgi_name_significant = 0; * config->*_set = 0; */ config->ipc_comm_timeout = DEFAULT_IPC_COMM_TIMEOUT; @@ -303,6 +304,23 @@ return NULL; } +const char *set_cgi_name_significant(cmd_parms * cmd, void *dummy, + const char *arg) +{ + server_rec *s = cmd->server; + fcgid_server_conf *config = + ap_get_module_config(s->module_config, &fcgid_module); + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + + if (err != NULL) { + return err; + } + + config->cgi_name_significant = atol(arg); + return NULL; + } + + const char *set_socketpath(cmd_parms * cmd, void *dummy, const char *arg) { server_rec *s = cmd->server; Index: modules/fcgid/fcgid_spawn_ctl.c =================================================================== --- modules/fcgid/fcgid_spawn_ctl.c (revision 818854) +++ modules/fcgid/fcgid_spawn_ctl.c (working copy) @@ -17,12 +17,15 @@ #include "fcgid_spawn_ctl.h" #include "fcgid_conf.h" +#include "apr_strings.h" #define REGISTER_LIFE 1 #define REGISTER_DEATH 2 struct fcgid_stat_node { apr_ino_t inode; dev_t deviceid; + char cgipath[_POSIX_PATH_MAX]; + int cgiNameOffset; uid_t uid; gid_t gid; apr_size_t share_grp_id; @@ -57,7 +60,8 @@ && current_node->share_grp_id == procnode->share_grp_id && current_node->virtualhost == procnode->virtualhost && current_node->uid == procnode->uid - && current_node->gid == procnode->gid) + && current_node->gid == procnode->gid + && !(sconf->cgi_name_significant && (apr_strnatcmp (current_node->cgipath+current_node->cgiNameOffset, procnode->cgipath+procnode->cgiNameOffset) != 0))) break; previous_node = current_node; } @@ -90,6 +94,8 @@ current_node = apr_pcalloc(g_stat_pool, sizeof(*current_node)); current_node->deviceid = procnode->deviceid; current_node->inode = procnode->inode; + apr_cpystrn(current_node->cgipath, procnode->cgipath, _POSIX_PATH_MAX); + current_node->cgiNameOffset = procnode->cgiNameOffset; current_node->share_grp_id = procnode->share_grp_id; current_node->virtualhost = procnode->virtualhost; current_node->uid = procnode->uid; @@ -146,7 +152,12 @@ struct fcgid_stat_node *current_node; fcgid_server_conf *sconf = ap_get_module_config(main_server->module_config, &fcgid_module); - + int cgiNameOffset; + if ((cgiNameOffset = (ap_strrchr_c(command->cgipath, '/') - command->cgipath)) < 0) { + cgiNameOffset = 0; + } + char *cgipath = command->cgipath+cgiNameOffset; + if (!command || !g_stat_pool) return 1; @@ -158,7 +169,8 @@ && current_node->share_grp_id == command->share_grp_id && current_node->virtualhost == command->virtualhost && current_node->uid == command->uid - && current_node->gid == command->gid) + && current_node->gid == command->gid + && !(sconf->cgi_name_significant && (apr_strnatcmp (current_node->cgipath+current_node->cgiNameOffset, cgipath) != 0))) break; } @@ -225,7 +237,8 @@ && current_node->share_grp_id == procnode->share_grp_id && current_node->virtualhost == procnode->virtualhost && current_node->uid == procnode->uid - && current_node->gid == procnode->gid) + && current_node->gid == procnode->gid + && !(sconf->cgi_name_significant && (apr_strnatcmp (current_node->cgipath+current_node->cgiNameOffset, procnode->cgipath+procnode->cgiNameOffset) != 0))) break; previous_node = current_node; } Index: modules/fcgid/fcgid_conf.h =================================================================== --- modules/fcgid/fcgid_conf.h (revision 818854) +++ modules/fcgid/fcgid_conf.h (working copy) @@ -80,6 +80,7 @@ int termination_score; int time_score; int zombie_scan_interval; + int cgi_name_significant; /* global or vhost * scalar values have corresponding _set field to aid merging */ @@ -159,6 +160,9 @@ const char *set_max_request_len(cmd_parms * cmd, void *dummy, const char *arg); +const char *set_cgi_name_significant(cmd_parms * cmd, void *dummy, + const char *arg); + const char *set_max_mem_request_len(cmd_parms * cmd, void *dummy, const char *arg); Index: modules/fcgid/fcgid_proctbl.h =================================================================== --- modules/fcgid/fcgid_proctbl.h (revision 818854) +++ modules/fcgid/fcgid_proctbl.h (working copy) @@ -42,6 +42,8 @@ char socket_path[_POSIX_PATH_MAX]; /* cgi application socket path */ apr_ino_t inode; /* cgi file inode */ apr_dev_t deviceid; /* cgi file device id */ + char cgipath[_POSIX_PATH_MAX]; /* cgi file path */ + int cgiNameOffset; /* program name in cgipath */ gid_t gid; /* for suEXEC */ uid_t uid; /* for suEXEC */ apr_size_t share_grp_id; /* cgi wrapper share group id */ Index: modules/fcgid/mod_fcgid.c =================================================================== --- modules/fcgid/mod_fcgid.c (revision 818854) +++ modules/fcgid/mod_fcgid.c (working copy) @@ -684,6 +684,11 @@ AP_INIT_TAKE1("FCGIDZombieScanInterval", set_zombie_scan_interval, NULL, RSRC_CONF, "scan interval for zombie process"), + AP_INIT_TAKE1("FCGIDCGINameSignificant", + set_cgi_name_significant, + NULL, RSRC_CONF, + "Set 1, if program/script name makes it unique"), + /* The following directives are all deprecated in favor * of a consistent use of the FCGID prefix. Index: modules/fcgid/fcgid_bridge.c =================================================================== --- modules/fcgid/fcgid_bridge.c (revision 818854) +++ modules/fcgid/fcgid_bridge.c (working copy) @@ -38,6 +38,9 @@ { /* Scan idle list, find a node match inode, deviceid and groupid If there is no one there, return NULL */ + + fcgid_server_conf *sconf = ap_get_module_config(s->module_config, + &fcgid_module); fcgid_procnode *previous_node, *current_node, *next_node; fcgid_procnode *busy_list_header, *proc_table; apr_ino_t inode = command->inode; @@ -46,7 +49,13 @@ gid_t gid = command->gid; apr_size_t share_grp_id = command->share_grp_id; const char *virtualhost = command->virtualhost; - + int cgi_name_significant = sconf->cgi_name_significant; + int cgiNameOffset; + if ((cgiNameOffset = (ap_strrchr_c(command->cgipath, '/') - command->cgipath)) < 0) { + cgiNameOffset = 0; + } + char *cgipath = command->cgipath+cgiNameOffset; + proc_table = proctable_get_table_array(); previous_node = proctable_get_idle_list(); busy_list_header = proctable_get_busy_list(); @@ -60,7 +69,8 @@ && current_node->deviceid == deviceid && current_node->share_grp_id == share_grp_id && current_node->virtualhost == virtualhost - && current_node->uid == uid && current_node->gid == gid) { + && current_node->uid == uid && current_node->gid == gid + && !(cgi_name_significant && (apr_strnatcmp (current_node->cgipath+current_node->cgiNameOffset, cgipath) != 0))) { /* Unlink from idle list */ previous_node->next_index = current_node->next_index;