You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ch...@apache.org on 2009/03/18 17:37:32 UTC
svn commit: r755634 [1/6] - in /httpd/mod_fcgid/trunk/mod_fcgid: ./
arch/unix/ arch/win32/
Author: chrisd
Date: Wed Mar 18 16:37:31 2009
New Revision: 755634
URL: http://svn.apache.org/viewvc?rev=755634&view=rev
Log:
convert tabs to spaces
Modified:
httpd/mod_fcgid/trunk/mod_fcgid/arch/unix/fcgid_pm_unix.c
httpd/mod_fcgid/trunk/mod_fcgid/arch/unix/fcgid_proc_unix.c
httpd/mod_fcgid/trunk/mod_fcgid/arch/unix/fcgid_proctbl_unix.c
httpd/mod_fcgid/trunk/mod_fcgid/arch/win32/fcgid_pm_win.c
httpd/mod_fcgid/trunk/mod_fcgid/arch/win32/fcgid_proc_win.c
httpd/mod_fcgid/trunk/mod_fcgid/arch/win32/fcgid_proctbl_win.c
httpd/mod_fcgid/trunk/mod_fcgid/fcgid_bridge.c
httpd/mod_fcgid/trunk/mod_fcgid/fcgid_bridge.h
httpd/mod_fcgid/trunk/mod_fcgid/fcgid_bucket.c
httpd/mod_fcgid/trunk/mod_fcgid/fcgid_bucket.h
httpd/mod_fcgid/trunk/mod_fcgid/fcgid_conf.c
httpd/mod_fcgid/trunk/mod_fcgid/fcgid_conf.h
httpd/mod_fcgid/trunk/mod_fcgid/fcgid_filter.c
httpd/mod_fcgid/trunk/mod_fcgid/fcgid_pm.h
httpd/mod_fcgid/trunk/mod_fcgid/fcgid_pm_main.c
httpd/mod_fcgid/trunk/mod_fcgid/fcgid_proc.h
httpd/mod_fcgid/trunk/mod_fcgid/fcgid_proctbl.h
httpd/mod_fcgid/trunk/mod_fcgid/fcgid_protocol.c
httpd/mod_fcgid/trunk/mod_fcgid/fcgid_protocol.h
httpd/mod_fcgid/trunk/mod_fcgid/fcgid_spawn_ctl.c
httpd/mod_fcgid/trunk/mod_fcgid/fcgid_spawn_ctl.h
httpd/mod_fcgid/trunk/mod_fcgid/mod_fcgid.c
Modified: httpd/mod_fcgid/trunk/mod_fcgid/arch/unix/fcgid_pm_unix.c
URL: http://svn.apache.org/viewvc/httpd/mod_fcgid/trunk/mod_fcgid/arch/unix/fcgid_pm_unix.c?rev=755634&r1=755633&r2=755634&view=diff
==============================================================================
--- httpd/mod_fcgid/trunk/mod_fcgid/arch/unix/fcgid_pm_unix.c (original)
+++ httpd/mod_fcgid/trunk/mod_fcgid/arch/unix/fcgid_pm_unix.c Wed Mar 18 16:37:31 2009
@@ -12,7 +12,7 @@
#include "fcgid_spawn_ctl.h"
#include <unistd.h>
static apr_status_t create_process_manager(server_rec * main_server,
- apr_pool_t * configpool);
+ apr_pool_t * configpool);
static int g_wakeup_timeout = 3;
static apr_proc_t *g_process_manager = NULL;
@@ -27,474 +27,474 @@
static pid_t g_pm_pid;
static void signal_handler(int signo)
{
- /* Sanity check, Make sure I am not the subprocess. A subprocess may
- get signale after fork() and before execve() */
- if (getpid() != g_pm_pid) {
- exit(0);
- return;
- }
-
- if ((signo == SIGTERM) || (signo == SIGUSR1) || (signo == SIGHUP)) {
- g_caughtSigTerm = 1;
- /* Tell the world it's time to die */
- proctable_get_globalshare()->must_exit = 1;
- }
+ /* Sanity check, Make sure I am not the subprocess. A subprocess may
+ get signale after fork() and before execve() */
+ if (getpid() != g_pm_pid) {
+ exit(0);
+ return;
+ }
+
+ if ((signo == SIGTERM) || (signo == SIGUSR1) || (signo == SIGHUP)) {
+ g_caughtSigTerm = 1;
+ /* Tell the world it's time to die */
+ proctable_get_globalshare()->must_exit = 1;
+ }
}
static apr_status_t init_signal(server_rec * main_server)
{
- struct sigaction sa;
+ struct sigaction sa;
- /* Setup handlers */
- sa.sa_handler = signal_handler;
- sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
-
- if (sigaction(SIGTERM, &sa, NULL) < 0) {
- ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server,
- "mod_fcgid: Can't install SIGTERM handler");
- return APR_EGENERAL;
- }
-
- /* Httpd restart */
- if (sigaction(SIGHUP, &sa, NULL) < 0) {
- ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server,
- "mod_fcgid: Can't install SIGHUP handler");
- return APR_EGENERAL;
- }
-
- /* Httpd graceful restart */
- if (sigaction(SIGUSR1, &sa, NULL) < 0) {
- ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server,
- "mod_fcgid: Can't install SIGUSR1 handler");
- return APR_EGENERAL;
- }
-
- /* Ignore SIGPIPE */
- sa.sa_handler = SIG_IGN;
- if (sigaction(SIGPIPE, &sa, NULL) < 0) {
- ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server,
- "mod_fcgid: Can't install SIGPIPE handler");
- return APR_EGENERAL;
- }
+ /* Setup handlers */
+ sa.sa_handler = signal_handler;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+
+ if (sigaction(SIGTERM, &sa, NULL) < 0) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server,
+ "mod_fcgid: Can't install SIGTERM handler");
+ return APR_EGENERAL;
+ }
+
+ /* Httpd restart */
+ if (sigaction(SIGHUP, &sa, NULL) < 0) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server,
+ "mod_fcgid: Can't install SIGHUP handler");
+ return APR_EGENERAL;
+ }
+
+ /* Httpd graceful restart */
+ if (sigaction(SIGUSR1, &sa, NULL) < 0) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server,
+ "mod_fcgid: Can't install SIGUSR1 handler");
+ return APR_EGENERAL;
+ }
+
+ /* Ignore SIGPIPE */
+ sa.sa_handler = SIG_IGN;
+ if (sigaction(SIGPIPE, &sa, NULL) < 0) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server,
+ "mod_fcgid: Can't install SIGPIPE handler");
+ return APR_EGENERAL;
+ }
- return APR_SUCCESS;
+ return APR_SUCCESS;
}
static void fcgid_maint(int reason, void *data, apr_wait_t status)
{
- apr_proc_t *proc = data;
- int mpm_state;
+ apr_proc_t *proc = data;
+ int mpm_state;
- switch (reason) {
- case APR_OC_REASON_DEATH:
- apr_proc_other_child_unregister(data);
- if (ap_mpm_query(AP_MPMQ_MPM_STATE, &mpm_state) == APR_SUCCESS
- && mpm_state != AP_MPMQ_STOPPING) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
- "mod_fcgid: fcgid process manager died, restarting the server");
-
- /* HACK: I can't just call create_process_manager() to
- restart a process manager, because it will use the dirty
- share memory, I have to kill myself a SIGHUP, to make
- a clean restart */
- if (kill(getpid(), SIGHUP) < 0) {
- ap_log_error(APLOG_MARK, APLOG_EMERG,
- apr_get_os_error(), NULL,
- "mod_fcgid: can' kill myself a signal SIGHUP");
- exit(0);
- }
- }
- break;
- case APR_OC_REASON_RESTART:
- apr_proc_other_child_unregister(data);
- break;
- case APR_OC_REASON_LOST:
- apr_proc_other_child_unregister(data);
- /* It hack here too, a note above */
- if (kill(getpid(), SIGHUP) < 0) {
- ap_log_error(APLOG_MARK, APLOG_EMERG,
- apr_get_os_error(), NULL,
- "mod_fcgid: can' kill myself a signal SIGHUP");
- exit(0);
- }
- break;
- case APR_OC_REASON_UNREGISTER:
- /* I don't think it's going to happen */
- kill(proc->pid, SIGHUP);
- break;
- }
+ switch (reason) {
+ case APR_OC_REASON_DEATH:
+ apr_proc_other_child_unregister(data);
+ if (ap_mpm_query(AP_MPMQ_MPM_STATE, &mpm_state) == APR_SUCCESS
+ && mpm_state != AP_MPMQ_STOPPING) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
+ "mod_fcgid: fcgid process manager died, restarting the server");
+
+ /* HACK: I can't just call create_process_manager() to
+ restart a process manager, because it will use the dirty
+ share memory, I have to kill myself a SIGHUP, to make
+ a clean restart */
+ if (kill(getpid(), SIGHUP) < 0) {
+ ap_log_error(APLOG_MARK, APLOG_EMERG,
+ apr_get_os_error(), NULL,
+ "mod_fcgid: can' kill myself a signal SIGHUP");
+ exit(0);
+ }
+ }
+ break;
+ case APR_OC_REASON_RESTART:
+ apr_proc_other_child_unregister(data);
+ break;
+ case APR_OC_REASON_LOST:
+ apr_proc_other_child_unregister(data);
+ /* It hack here too, a note above */
+ if (kill(getpid(), SIGHUP) < 0) {
+ ap_log_error(APLOG_MARK, APLOG_EMERG,
+ apr_get_os_error(), NULL,
+ "mod_fcgid: can' kill myself a signal SIGHUP");
+ exit(0);
+ }
+ break;
+ case APR_OC_REASON_UNREGISTER:
+ /* I don't think it's going to happen */
+ kill(proc->pid, SIGHUP);
+ break;
+ }
}
static int set_group_privs(void)
{
- if (!geteuid()) {
- const char *name;
+ if (!geteuid()) {
+ const char *name;
- /* Get username if passed as a uid */
- if (unixd_config.user_name[0] == '#') {
- struct passwd *ent;
-
- uid_t uid = atoi(&unixd_config.user_name[1]);
-
- if ((ent = getpwuid(uid)) == NULL) {
- ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL,
- "getpwuid: couldn't determine user name from uid %u, "
- "you probably need to modify the User directive",
- (unsigned) uid);
- return -1;
- }
- name = ent->pw_name;
- }
+ /* Get username if passed as a uid */
+ if (unixd_config.user_name[0] == '#') {
+ struct passwd *ent;
+
+ uid_t uid = atoi(&unixd_config.user_name[1]);
+
+ if ((ent = getpwuid(uid)) == NULL) {
+ ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL,
+ "getpwuid: couldn't determine user name from uid %u, "
+ "you probably need to modify the User directive",
+ (unsigned) uid);
+ return -1;
+ }
+ name = ent->pw_name;
+ }
- else
- name = unixd_config.user_name;
+ else
+ name = unixd_config.user_name;
#if !defined(OS2) && !defined(TPF)
- /* OS/2 and TPF don't support groups. */
+ /* OS/2 and TPF don't support groups. */
- /*
- * Set the GID before initgroups(), since on some platforms
- * setgid() is known to zap the group list.
- */
- if (setgid(unixd_config.group_id) == -1) {
- ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL,
- "setgid: unable to set group id to Group %u",
- (unsigned) unixd_config.group_id);
- return -1;
- }
-
- /* Reset `groups' attributes. */
- if (initgroups(name, unixd_config.group_id) == -1) {
- ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL,
- "initgroups: unable to set groups for User %s "
- "and Group %u", name,
- (unsigned) unixd_config.group_id);
- return -1;
- }
-#endif /* !defined(OS2) && !defined(TPF) */
- }
- return 0;
+ /*
+ * Set the GID before initgroups(), since on some platforms
+ * setgid() is known to zap the group list.
+ */
+ if (setgid(unixd_config.group_id) == -1) {
+ ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL,
+ "setgid: unable to set group id to Group %u",
+ (unsigned) unixd_config.group_id);
+ return -1;
+ }
+
+ /* Reset `groups' attributes. */
+ if (initgroups(name, unixd_config.group_id) == -1) {
+ ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL,
+ "initgroups: unable to set groups for User %s "
+ "and Group %u", name,
+ (unsigned) unixd_config.group_id);
+ return -1;
+ }
+#endif /* !defined(OS2) && !defined(TPF) */
+ }
+ return 0;
}
/* Base on unixd_setup_child() */
static int suexec_setup_child(void)
{
- if (set_group_privs()) {
- exit(-1);
- }
-
- /* Only try to switch if we're running as root */
- if (!geteuid() && (seteuid(unixd_config.user_id) == -1)) {
- ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL,
- "setuid: unable to change to uid: %ld",
- (long) unixd_config.user_id);
- exit(-1);
- }
- return 0;
+ if (set_group_privs()) {
+ exit(-1);
+ }
+
+ /* Only try to switch if we're running as root */
+ if (!geteuid() && (seteuid(unixd_config.user_id) == -1)) {
+ ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL,
+ "setuid: unable to change to uid: %ld",
+ (long) unixd_config.user_id);
+ exit(-1);
+ }
+ return 0;
}
static apr_status_t
create_process_manager(server_rec * main_server, apr_pool_t * configpool)
{
- apr_status_t rv;
+ apr_status_t rv;
- g_process_manager =
- (apr_proc_t *) apr_pcalloc(configpool, sizeof(*g_process_manager));
- rv = apr_proc_fork(g_process_manager, configpool);
- if (rv == APR_INCHILD) {
- /* I am the child */
- g_pm_pid = getpid();
- ap_log_error(APLOG_MARK, APLOG_INFO, 0, main_server,
- "mod_fcgid: Process manager %d started", getpid());
-
- if ((rv = init_signal(main_server)) != APR_SUCCESS) {
- ap_log_error(APLOG_MARK, LOG_EMERG, rv, main_server,
- "mod_fcgid: can't intall signal handler, exit now");
- exit(1);
- }
-
- /* if running as root, switch to configured user */
- if (unixd_config.suexec_enabled) {
- if (getuid() != 0) {
- ap_log_error(APLOG_MARK, LOG_EMERG, rv, main_server,
- "mod_fcgid: current user is not root while suexec is enabled, exit now");
- exit(1);
- }
- suexec_setup_child();
- } else
- unixd_setup_child();
- apr_file_pipe_timeout_set(g_pm_read_pipe,
- apr_time_from_sec(g_wakeup_timeout));
- apr_file_close(g_ap_write_pipe);
- apr_file_close(g_ap_read_pipe);
-
- /* Initialize spawn controler */
- spawn_control_init(main_server, configpool);
-
- pm_main(main_server, configpool);
-
- ap_log_error(APLOG_MARK, APLOG_INFO, 0, main_server,
- "mod_fcgid: Process manager %d stopped", getpid());
- exit(0);
- } else if (rv != APR_INPARENT) {
- ap_log_error(APLOG_MARK, APLOG_EMERG, errno, main_server,
- "mod_fcgid: Create process manager error");
- exit(1);
- }
-
- /* I am the parent
- I will send the stop signal in procmgr_stop_procmgr() */
- apr_pool_note_subprocess(configpool, g_process_manager,
- APR_KILL_ONLY_ONCE);
- apr_proc_other_child_register(g_process_manager, fcgid_maint,
- g_process_manager, NULL, configpool);
+ g_process_manager =
+ (apr_proc_t *) apr_pcalloc(configpool, sizeof(*g_process_manager));
+ rv = apr_proc_fork(g_process_manager, configpool);
+ if (rv == APR_INCHILD) {
+ /* I am the child */
+ g_pm_pid = getpid();
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, main_server,
+ "mod_fcgid: Process manager %d started", getpid());
+
+ if ((rv = init_signal(main_server)) != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, LOG_EMERG, rv, main_server,
+ "mod_fcgid: can't intall signal handler, exit now");
+ exit(1);
+ }
+
+ /* if running as root, switch to configured user */
+ if (unixd_config.suexec_enabled) {
+ if (getuid() != 0) {
+ ap_log_error(APLOG_MARK, LOG_EMERG, rv, main_server,
+ "mod_fcgid: current user is not root while suexec is enabled, exit now");
+ exit(1);
+ }
+ suexec_setup_child();
+ } else
+ unixd_setup_child();
+ apr_file_pipe_timeout_set(g_pm_read_pipe,
+ apr_time_from_sec(g_wakeup_timeout));
+ apr_file_close(g_ap_write_pipe);
+ apr_file_close(g_ap_read_pipe);
+
+ /* Initialize spawn controler */
+ spawn_control_init(main_server, configpool);
+
+ pm_main(main_server, configpool);
+
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, main_server,
+ "mod_fcgid: Process manager %d stopped", getpid());
+ exit(0);
+ } else if (rv != APR_INPARENT) {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, errno, main_server,
+ "mod_fcgid: Create process manager error");
+ exit(1);
+ }
+
+ /* I am the parent
+ I will send the stop signal in procmgr_stop_procmgr() */
+ apr_pool_note_subprocess(configpool, g_process_manager,
+ APR_KILL_ONLY_ONCE);
+ apr_proc_other_child_register(g_process_manager, fcgid_maint,
+ g_process_manager, NULL, configpool);
- return APR_SUCCESS;
+ return APR_SUCCESS;
}
apr_status_t
procmgr_child_init(server_rec * main_server, apr_pool_t * configpool)
{
- apr_status_t rv;
+ apr_status_t rv;
- if ((rv = apr_global_mutex_child_init(&g_pipelock,
- g_pipelock_name,
- main_server->process->pconf)) !=
- APR_SUCCESS) {
- ap_log_error(APLOG_MARK, APLOG_EMERG, rv, main_server,
- "mod_fcgid: apr_global_mutex_child_init error for pipe mutex");
- exit(1);
- }
+ if ((rv = apr_global_mutex_child_init(&g_pipelock,
+ g_pipelock_name,
+ main_server->process->pconf)) !=
+ APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, rv, main_server,
+ "mod_fcgid: apr_global_mutex_child_init error for pipe mutex");
+ exit(1);
+ }
- return APR_SUCCESS;
+ return APR_SUCCESS;
}
apr_status_t
procmgr_post_config(server_rec * main_server, apr_pool_t * configpool)
{
- apr_status_t rv;
- apr_finfo_t finfo;
- int error_scan_interval, busy_scan_interval, idle_scan_interval;
-
- /* Calculate procmgr_peek_cmd wake up interval */
- error_scan_interval = get_error_scan_interval(main_server);
- busy_scan_interval = get_busy_scan_interval(main_server);
- idle_scan_interval = get_idle_scan_interval(main_server);
- g_wakeup_timeout = fcgid_min(error_scan_interval, busy_scan_interval);
- g_wakeup_timeout = fcgid_min(idle_scan_interval, g_wakeup_timeout);
- if (g_wakeup_timeout == 0)
- g_wakeup_timeout = 1; /* Make it reasonable */
-
- rv = apr_stat(&finfo, get_socketpath(main_server), APR_FINFO_USER,
- configpool);
- if (rv != APR_SUCCESS || !(finfo.valid & APR_FINFO_USER)
- || finfo.user != unixd_config.user_id) {
- /* Make dir for unix domain socket */
- if ((rv = apr_dir_make_recursive(get_socketpath(main_server),
- APR_UREAD | APR_UWRITE |
- APR_UEXECUTE,
- configpool)) != APR_SUCCESS
- || chown(get_socketpath(main_server), unixd_config.user_id,
- -1) < 0) {
- ap_log_error(APLOG_MARK, APLOG_ERR, rv, main_server,
- "mod_fcgid: Can't create unix socket dir");
- exit(1);
- }
- }
-
- /* Create pipes to communicate between process manager and apache */
- if ((rv = apr_file_pipe_create(&g_pm_read_pipe, &g_ap_write_pipe,
- configpool)) != APR_SUCCESS
- || (rv = apr_file_pipe_create(&g_ap_read_pipe, &g_pm_write_pipe,
- configpool))) {
- ap_log_error(APLOG_MARK, APLOG_ERR, rv, main_server,
- "mod_fcgid: Can't create pipe between PM and stub");
- return rv;
- }
-
- /* Create mutex for pipe reading and writing */
- if ((rv =
- apr_global_mutex_create(&g_pipelock, tmpnam(g_pipelock_name),
- APR_LOCK_DEFAULT,
- main_server->process->pconf)) !=
- APR_SUCCESS) {
- ap_log_error(APLOG_MARK, APLOG_EMERG, rv, main_server,
- "mod_fcgid: Can't create global pipe mutex");
- exit(1);
- }
- if ((rv = unixd_set_global_mutex_perms(g_pipelock)) != APR_SUCCESS) {
- ap_log_error(APLOG_MARK, APLOG_EMERG, rv, main_server,
- "mod_fcgid: Can't set global pipe mutex perms");
- exit(1);
- }
+ apr_status_t rv;
+ apr_finfo_t finfo;
+ int error_scan_interval, busy_scan_interval, idle_scan_interval;
+
+ /* Calculate procmgr_peek_cmd wake up interval */
+ error_scan_interval = get_error_scan_interval(main_server);
+ busy_scan_interval = get_busy_scan_interval(main_server);
+ idle_scan_interval = get_idle_scan_interval(main_server);
+ g_wakeup_timeout = fcgid_min(error_scan_interval, busy_scan_interval);
+ g_wakeup_timeout = fcgid_min(idle_scan_interval, g_wakeup_timeout);
+ if (g_wakeup_timeout == 0)
+ g_wakeup_timeout = 1; /* Make it reasonable */
+
+ rv = apr_stat(&finfo, get_socketpath(main_server), APR_FINFO_USER,
+ configpool);
+ if (rv != APR_SUCCESS || !(finfo.valid & APR_FINFO_USER)
+ || finfo.user != unixd_config.user_id) {
+ /* Make dir for unix domain socket */
+ if ((rv = apr_dir_make_recursive(get_socketpath(main_server),
+ APR_UREAD | APR_UWRITE |
+ APR_UEXECUTE,
+ configpool)) != APR_SUCCESS
+ || chown(get_socketpath(main_server), unixd_config.user_id,
+ -1) < 0) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, rv, main_server,
+ "mod_fcgid: Can't create unix socket dir");
+ exit(1);
+ }
+ }
+
+ /* Create pipes to communicate between process manager and apache */
+ if ((rv = apr_file_pipe_create(&g_pm_read_pipe, &g_ap_write_pipe,
+ configpool)) != APR_SUCCESS
+ || (rv = apr_file_pipe_create(&g_ap_read_pipe, &g_pm_write_pipe,
+ configpool))) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, rv, main_server,
+ "mod_fcgid: Can't create pipe between PM and stub");
+ return rv;
+ }
+
+ /* Create mutex for pipe reading and writing */
+ if ((rv =
+ apr_global_mutex_create(&g_pipelock, tmpnam(g_pipelock_name),
+ APR_LOCK_DEFAULT,
+ main_server->process->pconf)) !=
+ APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, rv, main_server,
+ "mod_fcgid: Can't create global pipe mutex");
+ exit(1);
+ }
+ if ((rv = unixd_set_global_mutex_perms(g_pipelock)) != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, rv, main_server,
+ "mod_fcgid: Can't set global pipe mutex perms");
+ exit(1);
+ }
- /* Create process manager process */
- return create_process_manager(main_server, configpool);
+ /* Create process manager process */
+ return create_process_manager(main_server, configpool);
}
void procmgr_init_spawn_cmd(fcgid_command * command, request_rec * r,
- const char *argv0, dev_t deviceid,
- apr_ino_t inode, apr_size_t share_grp_id)
+ const char *argv0, dev_t deviceid,
+ apr_ino_t inode, apr_size_t share_grp_id)
{
- server_rec *main_server = r->server;
- ap_unix_identity_t *ugid;
- apr_table_t *initenv;
- const apr_array_header_t *initenv_arr;
- const apr_table_entry_t *initenv_entry;
- fcgid_wrapper_conf *wrapperconf;
- int i;
-
- memset(command, 0, sizeof(*command));
-
- /* suEXEC check */
- if ((ugid = ap_run_get_suexec_identity(r))) {
- command->uid = ugid->uid;
- command->gid = ugid->gid;
- command->userdir = ugid->userdir;
- } else {
- command->uid = (uid_t) - 1;
- command->gid = (gid_t) - 1;
- command->userdir = 0;
- }
-
- /* Environment variables */
- initenv = get_default_env_vars(r);
- 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_error(APLOG_MARK, LOG_WARNING, 0, main_server,
- "mod_fcgid: too much environment variables, Please increase INITENV_CNT in fcgid_pm.h and recompile module mod_fcgid");
-
- for (i = 0; i < initenv_arr->nelts && i < INITENV_CNT; ++i) {
- if (initenv_entry[i].key == NULL
- || initenv_entry[i].key[0] == '\0')
- break;
- strncpy(command->initenv_key[i], initenv_entry[i].key,
- INITENV_KEY_LEN);
- command->initenv_key[i][INITENV_KEY_LEN - 1] = '\0';
- strncpy(command->initenv_val[i], initenv_entry[i].val,
- INITENV_VAL_LEN);
- command->initenv_val[i][INITENV_VAL_LEN - 1] = '\0';
- }
- }
-
- strncpy(command->cgipath, argv0, _POSIX_PATH_MAX);
- command->cgipath[_POSIX_PATH_MAX - 1] = '\0';
- command->deviceid = deviceid;
- command->inode = inode;
- command->share_grp_id = share_grp_id;
- command->virtualhost = r->server->server_hostname;
-
- /* Update fcgid_command with wrapper info */
- command->wrapperpath[0] = '\0';
- if ((wrapperconf = get_wrapper_info(argv0, r))) {
- strncpy(command->wrapperpath, wrapperconf->args, _POSIX_PATH_MAX);
- command->wrapperpath[_POSIX_PATH_MAX - 1] = '\0';
- command->deviceid = wrapperconf->deviceid;
- command->inode = wrapperconf->inode;
- command->share_grp_id = wrapperconf->share_group_id;
- }
+ server_rec *main_server = r->server;
+ ap_unix_identity_t *ugid;
+ apr_table_t *initenv;
+ const apr_array_header_t *initenv_arr;
+ const apr_table_entry_t *initenv_entry;
+ fcgid_wrapper_conf *wrapperconf;
+ int i;
+
+ memset(command, 0, sizeof(*command));
+
+ /* suEXEC check */
+ if ((ugid = ap_run_get_suexec_identity(r))) {
+ command->uid = ugid->uid;
+ command->gid = ugid->gid;
+ command->userdir = ugid->userdir;
+ } else {
+ command->uid = (uid_t) - 1;
+ command->gid = (gid_t) - 1;
+ command->userdir = 0;
+ }
+
+ /* Environment variables */
+ initenv = get_default_env_vars(r);
+ 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_error(APLOG_MARK, LOG_WARNING, 0, main_server,
+ "mod_fcgid: too much environment variables, Please increase INITENV_CNT in fcgid_pm.h and recompile module mod_fcgid");
+
+ for (i = 0; i < initenv_arr->nelts && i < INITENV_CNT; ++i) {
+ if (initenv_entry[i].key == NULL
+ || initenv_entry[i].key[0] == '\0')
+ break;
+ strncpy(command->initenv_key[i], initenv_entry[i].key,
+ INITENV_KEY_LEN);
+ command->initenv_key[i][INITENV_KEY_LEN - 1] = '\0';
+ strncpy(command->initenv_val[i], initenv_entry[i].val,
+ INITENV_VAL_LEN);
+ command->initenv_val[i][INITENV_VAL_LEN - 1] = '\0';
+ }
+ }
+
+ strncpy(command->cgipath, argv0, _POSIX_PATH_MAX);
+ command->cgipath[_POSIX_PATH_MAX - 1] = '\0';
+ command->deviceid = deviceid;
+ command->inode = inode;
+ command->share_grp_id = share_grp_id;
+ command->virtualhost = r->server->server_hostname;
+
+ /* Update fcgid_command with wrapper info */
+ command->wrapperpath[0] = '\0';
+ if ((wrapperconf = get_wrapper_info(argv0, r))) {
+ strncpy(command->wrapperpath, wrapperconf->args, _POSIX_PATH_MAX);
+ command->wrapperpath[_POSIX_PATH_MAX - 1] = '\0';
+ command->deviceid = wrapperconf->deviceid;
+ command->inode = wrapperconf->inode;
+ command->share_grp_id = wrapperconf->share_group_id;
+ }
}
apr_status_t procmgr_post_spawn_cmd(fcgid_command * command,
- request_rec * r)
+ request_rec * r)
{
- apr_status_t rv;
- char notifybyte;
- apr_size_t nbytes = sizeof(*command);
- server_rec *main_server = r->server;
-
- /* Sanity check first */
- if (g_caughtSigTerm || !g_ap_write_pipe)
- return APR_SUCCESS;
-
- /* Get the global mutex before posting the request */
- if ((rv = apr_global_mutex_lock(g_pipelock)) != APR_SUCCESS) {
- ap_log_error(APLOG_MARK, LOG_WARNING, rv, main_server,
- "mod_fcgid: can't get pipe mutex");
- exit(0);
- }
-
- if ((rv =
- apr_file_write_full(g_ap_write_pipe, command, nbytes,
- NULL)) != APR_SUCCESS) {
- /* Just print some error log and fall through */
- ap_log_error(APLOG_MARK, LOG_WARNING, rv, main_server,
- "mod_fcgid: can't write spawn command");
- } else {
- /* Wait the finish notify while send the request successfully */
- nbytes = sizeof(notifybyte);
- if ((rv =
- apr_file_read(g_ap_read_pipe, ¬ifybyte,
- &nbytes)) != APR_SUCCESS) {
- ap_log_error(APLOG_MARK, LOG_WARNING, rv, main_server,
- "mod_fcgid: can't get notify from process manager");
- }
- }
-
- /* Release the lock */
- if ((rv = apr_global_mutex_unlock(g_pipelock)) != APR_SUCCESS) {
- ap_log_error(APLOG_MARK, LOG_WARNING, rv, main_server,
- "mod_fcgid: can't release pipe mutex");
- exit(0);
- }
+ apr_status_t rv;
+ char notifybyte;
+ apr_size_t nbytes = sizeof(*command);
+ server_rec *main_server = r->server;
+
+ /* Sanity check first */
+ if (g_caughtSigTerm || !g_ap_write_pipe)
+ return APR_SUCCESS;
+
+ /* Get the global mutex before posting the request */
+ if ((rv = apr_global_mutex_lock(g_pipelock)) != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, LOG_WARNING, rv, main_server,
+ "mod_fcgid: can't get pipe mutex");
+ exit(0);
+ }
+
+ if ((rv =
+ apr_file_write_full(g_ap_write_pipe, command, nbytes,
+ NULL)) != APR_SUCCESS) {
+ /* Just print some error log and fall through */
+ ap_log_error(APLOG_MARK, LOG_WARNING, rv, main_server,
+ "mod_fcgid: can't write spawn command");
+ } else {
+ /* Wait the finish notify while send the request successfully */
+ nbytes = sizeof(notifybyte);
+ if ((rv =
+ apr_file_read(g_ap_read_pipe, ¬ifybyte,
+ &nbytes)) != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, LOG_WARNING, rv, main_server,
+ "mod_fcgid: can't get notify from process manager");
+ }
+ }
+
+ /* Release the lock */
+ if ((rv = apr_global_mutex_unlock(g_pipelock)) != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, LOG_WARNING, rv, main_server,
+ "mod_fcgid: can't release pipe mutex");
+ exit(0);
+ }
- return APR_SUCCESS;
+ return APR_SUCCESS;
}
apr_status_t procmgr_finish_notify(server_rec * main_server)
{
- apr_status_t rv;
- char notifybyte = 'p';
- apr_size_t nbytes = sizeof(notifybyte);
-
- if ((rv =
- apr_file_write(g_pm_write_pipe, ¬ifybyte,
- &nbytes)) != APR_SUCCESS) {
- ap_log_error(APLOG_MARK, LOG_WARNING, rv, main_server,
- "mod_fcgid: can't send notify from process manager");
- }
+ apr_status_t rv;
+ char notifybyte = 'p';
+ apr_size_t nbytes = sizeof(notifybyte);
+
+ if ((rv =
+ apr_file_write(g_pm_write_pipe, ¬ifybyte,
+ &nbytes)) != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, LOG_WARNING, rv, main_server,
+ "mod_fcgid: can't send notify from process manager");
+ }
- return rv;
+ return rv;
}
#define FOR_READ 1
apr_status_t procmgr_peek_cmd(fcgid_command * command,
- server_rec * main_server)
+ server_rec * main_server)
{
- apr_status_t rv;
+ apr_status_t rv;
- /* Sanity check */
- if (!g_pm_read_pipe)
- return APR_EPIPE;
-
- /* Wait for next command */
- rv = apr_wait_for_io_or_timeout(g_pm_read_pipe, NULL, FOR_READ);
-
- /* Log any unexpect result */
- if (rv != APR_SUCCESS && !APR_STATUS_IS_TIMEUP(rv)) {
- ap_log_error(APLOG_MARK, LOG_WARNING, rv, main_server,
- "mod_fcgid: wait io error while getting message from pipe");
- return rv;
- }
-
- /* Timeout */
- if (rv != APR_SUCCESS)
- return rv;
+ /* Sanity check */
+ if (!g_pm_read_pipe)
+ return APR_EPIPE;
+
+ /* Wait for next command */
+ rv = apr_wait_for_io_or_timeout(g_pm_read_pipe, NULL, FOR_READ);
+
+ /* Log any unexpect result */
+ if (rv != APR_SUCCESS && !APR_STATUS_IS_TIMEUP(rv)) {
+ ap_log_error(APLOG_MARK, LOG_WARNING, rv, main_server,
+ "mod_fcgid: wait io error while getting message from pipe");
+ return rv;
+ }
+
+ /* Timeout */
+ if (rv != APR_SUCCESS)
+ return rv;
- return apr_file_read_full(g_pm_read_pipe, command, sizeof(*command),
- NULL);
+ return apr_file_read_full(g_pm_read_pipe, command, sizeof(*command),
+ NULL);
}
int procmgr_must_exit()
{
- return g_caughtSigTerm;
+ return g_caughtSigTerm;
}
apr_status_t procmgr_stop_procmgr(void *server)
{
- return APR_SUCCESS;
+ return APR_SUCCESS;
}
Modified: httpd/mod_fcgid/trunk/mod_fcgid/arch/unix/fcgid_proc_unix.c
URL: http://svn.apache.org/viewvc/httpd/mod_fcgid/trunk/mod_fcgid/arch/unix/fcgid_proc_unix.c?rev=755634&r1=755633&r2=755634&view=diff
==============================================================================
--- httpd/mod_fcgid/trunk/mod_fcgid/arch/unix/fcgid_proc_unix.c (original)
+++ httpd/mod_fcgid/trunk/mod_fcgid/arch/unix/fcgid_proc_unix.c Wed Mar 18 16:37:31 2009
@@ -1,7 +1,7 @@
#include <unistd.h>
#include <sys/un.h>
#include <sys/types.h>
-#include <netinet/tcp.h> /* For TCP_NODELAY */
+#include <netinet/tcp.h> /* For TCP_NODELAY */
#include <sys/poll.h>
#define CORE_PRIVATE
#include "httpd.h"
@@ -24,7 +24,7 @@
#include "fcgid_spawn_ctl.h"
#define DEFAULT_FCGID_LISTENBACKLOG 5
typedef struct {
- int handle_socket;
+ int handle_socket;
} fcgid_namedpipe_handle;
static int g_process_counter = 0;
@@ -32,804 +32,804 @@
static const char *g_socket_dir = NULL;
static apr_status_t ap_unix_create_privileged_process(apr_proc_t * newproc,
- const char *progname,
- const char *const
- *args, const char *const
- *env,
- apr_procattr_t *
- attr,
- ap_unix_identity_t *
- ugid, apr_pool_t * p)
-{
- int i = 0;
- const char **newargs;
- char *newprogname;
- char *execuser, *execgroup;
- const char *argv0;
-
- if (!unixd_config.suexec_enabled) {
- return apr_proc_create(newproc, progname, args, env, attr, p);
- }
-
- argv0 = ap_strrchr_c(progname, '/');
- /* Allow suexec's "/" check to succeed */
- if (argv0 != NULL) {
- argv0++;
- } else {
- argv0 = progname;
- }
-
-
- if (ugid->userdir) {
- execuser = apr_psprintf(p, "~%ld", (long) ugid->uid);
- } else {
- execuser = apr_psprintf(p, "%ld", (long) ugid->uid);
- }
- execgroup = apr_psprintf(p, "%ld", (long) ugid->gid);
-
- if (!execuser || !execgroup) {
- return APR_ENOMEM;
- }
-
- i = 0;
- if (args) {
- while (args[i]) {
- i++;
- }
- }
- /* allocate space for 4 new args, the input args, and a null terminator */
- newargs = apr_palloc(p, sizeof(char *) * (i + 4));
- newprogname = SUEXEC_BIN;
- newargs[0] = SUEXEC_BIN;
- newargs[1] = execuser;
- newargs[2] = execgroup;
- newargs[3] = apr_pstrdup(p, argv0);
-
- /*
- ** using a shell to execute suexec makes no sense thus
- ** we force everything to be APR_PROGRAM, and never
- ** APR_SHELLCMD
- */
- if (apr_procattr_cmdtype_set(attr, APR_PROGRAM) != APR_SUCCESS) {
- return APR_EGENERAL;
- }
-
- i = 1;
- do {
- newargs[i + 3] = args[i];
- } while (args[i++]);
+ const char *progname,
+ const char *const
+ *args, const char *const
+ *env,
+ apr_procattr_t *
+ attr,
+ ap_unix_identity_t *
+ ugid, apr_pool_t * p)
+{
+ int i = 0;
+ const char **newargs;
+ char *newprogname;
+ char *execuser, *execgroup;
+ const char *argv0;
+
+ if (!unixd_config.suexec_enabled) {
+ return apr_proc_create(newproc, progname, args, env, attr, p);
+ }
+
+ argv0 = ap_strrchr_c(progname, '/');
+ /* Allow suexec's "/" check to succeed */
+ if (argv0 != NULL) {
+ argv0++;
+ } else {
+ argv0 = progname;
+ }
+
+
+ if (ugid->userdir) {
+ execuser = apr_psprintf(p, "~%ld", (long) ugid->uid);
+ } else {
+ execuser = apr_psprintf(p, "%ld", (long) ugid->uid);
+ }
+ execgroup = apr_psprintf(p, "%ld", (long) ugid->gid);
+
+ if (!execuser || !execgroup) {
+ return APR_ENOMEM;
+ }
+
+ i = 0;
+ if (args) {
+ while (args[i]) {
+ i++;
+ }
+ }
+ /* allocate space for 4 new args, the input args, and a null terminator */
+ newargs = apr_palloc(p, sizeof(char *) * (i + 4));
+ newprogname = SUEXEC_BIN;
+ newargs[0] = SUEXEC_BIN;
+ newargs[1] = execuser;
+ newargs[2] = execgroup;
+ newargs[3] = apr_pstrdup(p, argv0);
+
+ /*
+ ** using a shell to execute suexec makes no sense thus
+ ** we force everything to be APR_PROGRAM, and never
+ ** APR_SHELLCMD
+ */
+ if (apr_procattr_cmdtype_set(attr, APR_PROGRAM) != APR_SUCCESS) {
+ return APR_EGENERAL;
+ }
+
+ i = 1;
+ do {
+ newargs[i + 3] = args[i];
+ } while (args[i++]);
- return apr_proc_create(newproc, newprogname, newargs, env, attr, p);
+ return apr_proc_create(newproc, newprogname, newargs, env, attr, p);
}
static apr_status_t fcgid_create_privileged_process(apr_proc_t * newproc,
- const char *progname,
- const char *const
- *args,
- const char *const *env,
- apr_procattr_t * attr,
- fcgid_proc_info *
- procinfo,
- apr_pool_t * p)
-{
- ap_unix_identity_t ugid;
-
- if (!unixd_config.suexec_enabled
- || (procinfo->uid == (uid_t) - 1
- && procinfo->gid == (gid_t) - 1)) {
- return apr_proc_create(newproc, progname, args, env, attr, p);
- }
-
- ugid.gid = procinfo->gid;
- ugid.uid = procinfo->uid;
- ugid.userdir = procinfo->userdir;
- return ap_unix_create_privileged_process(newproc, progname, args, env,
- attr, &ugid, p);
+ const char *progname,
+ const char *const
+ *args,
+ const char *const *env,
+ apr_procattr_t * attr,
+ fcgid_proc_info *
+ procinfo,
+ apr_pool_t * p)
+{
+ ap_unix_identity_t ugid;
+
+ if (!unixd_config.suexec_enabled
+ || (procinfo->uid == (uid_t) - 1
+ && procinfo->gid == (gid_t) - 1)) {
+ return apr_proc_create(newproc, progname, args, env, attr, p);
+ }
+
+ ugid.gid = procinfo->gid;
+ ugid.uid = procinfo->uid;
+ ugid.userdir = procinfo->userdir;
+ return ap_unix_create_privileged_process(newproc, progname, args, env,
+ attr, &ugid, p);
}
static apr_status_t socket_file_cleanup(void *theprocnode)
{
- fcgid_procnode *procnode = (fcgid_procnode *) theprocnode;
+ fcgid_procnode *procnode = (fcgid_procnode *) theprocnode;
- unlink(procnode->socket_path);
- return APR_SUCCESS;
+ unlink(procnode->socket_path);
+ return APR_SUCCESS;
}
static apr_status_t exec_setuid_cleanup(void *dummy)
{
- seteuid(0);
- setuid(unixd_config.user_id);
- return APR_SUCCESS;
+ seteuid(0);
+ setuid(unixd_config.user_id);
+ return APR_SUCCESS;
}
apr_status_t
proc_spawn_process(char *lpszwapper, fcgid_proc_info * procinfo,
- fcgid_procnode * procnode)
+ fcgid_procnode * procnode)
{
- server_rec *main_server = procinfo->main_server;
- apr_status_t rv = APR_SUCCESS;
- apr_file_t *file;
- int omask, retcode, unix_socket;
- char **proc_environ;
- struct sockaddr_un unix_addr;
- apr_procattr_t *procattr = NULL;
- char key_name[_POSIX_PATH_MAX];
- void *dummy;
- int argc;
- char *wargv[APACHE_ARG_MAX], *word; /* For wrapper */
- const char *tmp;
- char *argv[2];
-
- /* Build wrapper args */
- argc = 0;
- tmp = lpszwapper;
- while (1) {
- word = ap_getword_white(procnode->proc_pool, &tmp);
- if (word == NULL || *word == '\0')
- break;
- if (argc >= APACHE_ARG_MAX)
- break;
- wargv[argc++] = word;
- }
- wargv[argc] = NULL;
-
- /* Initialize the variables */
- if (!g_inode_cginame_map) {
- apr_pool_create(&g_inode_cginame_map,
- procinfo->main_server->process->pconf);
- }
-
- if (!g_socket_dir)
- g_socket_dir = get_socketpath(procinfo->main_server);
- if (!g_inode_cginame_map || !g_socket_dir) {
- ap_log_error(APLOG_MARK, APLOG_WARNING, apr_get_os_error(),
- procinfo->main_server,
- "mod_fcgid: can't cgi name map table");
- return APR_ENOMEM;
- }
-
- /*
- Create UNIX domain socket before spawn
- */
-
- /* Generate a UNIX domain socket file path */
- /* XXX It's nothing I can do if strlen(g_socket_dir) too long... */
- memset(&unix_addr, 0, sizeof(unix_addr));
- unix_addr.sun_family = AF_UNIX;
- apr_snprintf(unix_addr.sun_path, sizeof(unix_addr.sun_path) - 1,
- "%s/%d.%d", g_socket_dir, getpid(), g_process_counter++);
- strncpy(procnode->socket_path, unix_addr.sun_path,
- sizeof(procnode->socket_path) - 1);
-
- /* Unlink the file just in case */
- unlink(unix_addr.sun_path);
-
- /* Create the socket */
- if ((unix_socket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
- ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server,
- "mod_fcgid: couldn't create unix domain socket");
- return errno;
- }
-
- /* Unlink it when process exit */
- if (unixd_config.suexec_enabled) {
- apr_pool_cleanup_register(procnode->proc_pool,
- procnode, socket_file_cleanup,
- exec_setuid_cleanup);
- } else {
- apr_pool_cleanup_register(procnode->proc_pool,
- procnode, socket_file_cleanup,
- apr_pool_cleanup_null);
- }
-
- /* Bind the socket */
- omask = umask(0077);
- retcode = bind(unix_socket, (struct sockaddr *) &unix_addr,
- sizeof(unix_addr));
- umask(omask);
- if (retcode < 0) {
- ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server,
- "mod_fcgid: couldn't bind unix domain socket %s",
- unix_addr.sun_path);
- close(unix_socket);
- return errno;
- }
-
- /* Listen the socket */
- if (listen(unix_socket, DEFAULT_FCGID_LISTENBACKLOG) < 0) {
- ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server,
- "mod_fcgid: couldn't listen on unix domain socket");
- close(unix_socket);
- return errno;
- }
-
- /* Correct the file owner */
- if (!geteuid()) {
- if (chown(unix_addr.sun_path, unixd_config.user_id, -1) < 0) {
- ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server,
- "mod_fcgid: couldn't change owner of unix domain socket %s",
- unix_addr.sun_path);
- close(unix_socket);
- return errno;
- }
- }
-
- {
- int oldflags = fcntl(unix_socket, F_GETFD, 0);
-
- if (oldflags < 0) {
- ap_log_error(APLOG_MARK, APLOG_WARNING, apr_get_os_error(),
- procinfo->main_server,
- "mod_fcgid: fcntl F_GETFD failed");
- close(unix_socket);
- return errno;
- }
-
- oldflags |= FD_CLOEXEC;
- if (fcntl(unix_socket, F_SETFD, oldflags) < 0) {
- ap_log_error(APLOG_MARK, APLOG_WARNING, apr_get_os_error(),
- procinfo->main_server,
- "mod_fcgid: fcntl F_SETFD failed");
- close(unix_socket);
- return errno;
- }
- }
-
- /* Build environment variables */
- proc_environ = ap_create_environment(procnode->proc_pool,
- procinfo->proc_environ);
- if (!proc_environ) {
- ap_log_error(APLOG_MARK, APLOG_WARNING, apr_get_os_error(),
- procinfo->main_server,
- "mod_fcgid: can't build environment variables");
- close(unix_socket);
- return APR_ENOMEM;
- }
-
- /* Prepare the fork */
- if (!
- (procnode->proc_id =
- apr_pcalloc(procnode->proc_pool, sizeof(apr_proc_t)))
+ server_rec *main_server = procinfo->main_server;
+ apr_status_t rv = APR_SUCCESS;
+ apr_file_t *file;
+ int omask, retcode, unix_socket;
+ char **proc_environ;
+ struct sockaddr_un unix_addr;
+ apr_procattr_t *procattr = NULL;
+ char key_name[_POSIX_PATH_MAX];
+ void *dummy;
+ int argc;
+ char *wargv[APACHE_ARG_MAX], *word; /* For wrapper */
+ const char *tmp;
+ char *argv[2];
+
+ /* Build wrapper args */
+ argc = 0;
+ tmp = lpszwapper;
+ while (1) {
+ word = ap_getword_white(procnode->proc_pool, &tmp);
+ if (word == NULL || *word == '\0')
+ break;
+ if (argc >= APACHE_ARG_MAX)
+ break;
+ wargv[argc++] = word;
+ }
+ wargv[argc] = NULL;
+
+ /* Initialize the variables */
+ if (!g_inode_cginame_map) {
+ apr_pool_create(&g_inode_cginame_map,
+ procinfo->main_server->process->pconf);
+ }
+
+ if (!g_socket_dir)
+ g_socket_dir = get_socketpath(procinfo->main_server);
+ if (!g_inode_cginame_map || !g_socket_dir) {
+ ap_log_error(APLOG_MARK, APLOG_WARNING, apr_get_os_error(),
+ procinfo->main_server,
+ "mod_fcgid: can't cgi name map table");
+ return APR_ENOMEM;
+ }
+
+ /*
+ Create UNIX domain socket before spawn
+ */
+
+ /* Generate a UNIX domain socket file path */
+ /* XXX It's nothing I can do if strlen(g_socket_dir) too long... */
+ memset(&unix_addr, 0, sizeof(unix_addr));
+ unix_addr.sun_family = AF_UNIX;
+ apr_snprintf(unix_addr.sun_path, sizeof(unix_addr.sun_path) - 1,
+ "%s/%d.%d", g_socket_dir, getpid(), g_process_counter++);
+ strncpy(procnode->socket_path, unix_addr.sun_path,
+ sizeof(procnode->socket_path) - 1);
+
+ /* Unlink the file just in case */
+ unlink(unix_addr.sun_path);
+
+ /* Create the socket */
+ if ((unix_socket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server,
+ "mod_fcgid: couldn't create unix domain socket");
+ return errno;
+ }
+
+ /* Unlink it when process exit */
+ if (unixd_config.suexec_enabled) {
+ apr_pool_cleanup_register(procnode->proc_pool,
+ procnode, socket_file_cleanup,
+ exec_setuid_cleanup);
+ } else {
+ apr_pool_cleanup_register(procnode->proc_pool,
+ procnode, socket_file_cleanup,
+ apr_pool_cleanup_null);
+ }
+
+ /* Bind the socket */
+ omask = umask(0077);
+ retcode = bind(unix_socket, (struct sockaddr *) &unix_addr,
+ sizeof(unix_addr));
+ umask(omask);
+ if (retcode < 0) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server,
+ "mod_fcgid: couldn't bind unix domain socket %s",
+ unix_addr.sun_path);
+ close(unix_socket);
+ return errno;
+ }
+
+ /* Listen the socket */
+ if (listen(unix_socket, DEFAULT_FCGID_LISTENBACKLOG) < 0) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server,
+ "mod_fcgid: couldn't listen on unix domain socket");
+ close(unix_socket);
+ return errno;
+ }
+
+ /* Correct the file owner */
+ if (!geteuid()) {
+ if (chown(unix_addr.sun_path, unixd_config.user_id, -1) < 0) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server,
+ "mod_fcgid: couldn't change owner of unix domain socket %s",
+ unix_addr.sun_path);
+ close(unix_socket);
+ return errno;
+ }
+ }
+
+ {
+ int oldflags = fcntl(unix_socket, F_GETFD, 0);
+
+ if (oldflags < 0) {
+ ap_log_error(APLOG_MARK, APLOG_WARNING, apr_get_os_error(),
+ procinfo->main_server,
+ "mod_fcgid: fcntl F_GETFD failed");
+ close(unix_socket);
+ return errno;
+ }
+
+ oldflags |= FD_CLOEXEC;
+ if (fcntl(unix_socket, F_SETFD, oldflags) < 0) {
+ ap_log_error(APLOG_MARK, APLOG_WARNING, apr_get_os_error(),
+ procinfo->main_server,
+ "mod_fcgid: fcntl F_SETFD failed");
+ close(unix_socket);
+ return errno;
+ }
+ }
+
+ /* Build environment variables */
+ proc_environ = ap_create_environment(procnode->proc_pool,
+ procinfo->proc_environ);
+ if (!proc_environ) {
+ ap_log_error(APLOG_MARK, APLOG_WARNING, apr_get_os_error(),
+ procinfo->main_server,
+ "mod_fcgid: can't build environment variables");
+ close(unix_socket);
+ return APR_ENOMEM;
+ }
+
+ /* Prepare the fork */
+ if (!
+ (procnode->proc_id =
+ apr_pcalloc(procnode->proc_pool, sizeof(apr_proc_t)))
|| (rv =
- apr_procattr_create(&procattr, procnode->proc_pool)) != APR_SUCCESS
+ apr_procattr_create(&procattr, procnode->proc_pool)) != APR_SUCCESS
|| (rv =
- apr_procattr_child_err_set(procattr,
- procinfo->main_server->error_log,
- NULL)) != APR_SUCCESS
+ apr_procattr_child_err_set(procattr,
+ procinfo->main_server->error_log,
+ NULL)) != APR_SUCCESS
|| (rv =
- apr_procattr_child_out_set(procattr,
- procinfo->main_server->error_log,
- NULL)) != APR_SUCCESS
+ apr_procattr_child_out_set(procattr,
+ procinfo->main_server->error_log,
+ NULL)) != APR_SUCCESS
|| (rv =
- apr_procattr_dir_set(procattr,
- ap_make_dirstr_parent(procnode->proc_pool,
- (lpszwapper != NULL
- && lpszwapper[0] !=
- '\0') ? wargv[0] :
- procinfo->cgipath))) !=
+ apr_procattr_dir_set(procattr,
+ ap_make_dirstr_parent(procnode->proc_pool,
+ (lpszwapper != NULL
+ && lpszwapper[0] !=
+ '\0') ? wargv[0] :
+ procinfo->cgipath))) !=
APR_SUCCESS
|| (rv = apr_procattr_cmdtype_set(procattr, APR_PROGRAM)) != APR_SUCCESS
|| (rv =
- apr_os_file_put(&file, &unix_socket, 0,
- procnode->proc_pool)) != APR_SUCCESS
+ apr_os_file_put(&file, &unix_socket, 0,
+ procnode->proc_pool)) != APR_SUCCESS
|| (rv = apr_procattr_child_in_set(procattr, file, NULL)) != APR_SUCCESS) {
- ap_log_error(APLOG_MARK, APLOG_ERR, rv, procinfo->main_server,
- "mod_fcgid: couldn't set child process attributes: %s",
- unix_addr.sun_path);
- close(unix_socket);
- return rv;
- }
-
- /* fork and exec now */
- if (lpszwapper != NULL && lpszwapper[0] != '\0') {
- ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, procinfo->main_server,
- "mod_fcgid: call %s with wrapper %s",
- procinfo->cgipath, lpszwapper);
- if ((rv =
- fcgid_create_privileged_process(procnode->proc_id,
- wargv[0],
- (const char *const *) wargv,
- (const char *const *)
- proc_environ, procattr,
- procinfo,
- procnode->proc_pool)) !=
- APR_SUCCESS) {
- ap_log_error(APLOG_MARK, APLOG_ERR, rv, procinfo->main_server,
- "mod_fcgid: can't create wrapper process for %s",
- procinfo->cgipath);
- close(unix_socket);
- return rv;
- }
- } else {
- argv[0] = procinfo->cgipath;
- argv[1] = NULL;
- if ((rv =
- fcgid_create_privileged_process(procnode->proc_id,
- procinfo->cgipath,
- (const char *const *) argv,
- (const char *const *)
- proc_environ, procattr,
- procinfo,
- procnode->proc_pool)) !=
- APR_SUCCESS) {
- ap_log_error(APLOG_MARK, APLOG_ERR, rv, procinfo->main_server,
- "mod_fcgid: can't create process");
- close(unix_socket);
- return rv;
- }
- }
-
- /* Set the (deviceid, inode) -> fastcgi path map for log */
- apr_snprintf(key_name, _POSIX_PATH_MAX, "%lX%lX",
- procnode->inode, (unsigned long) procnode->deviceid);
- dummy = NULL;
- apr_pool_userdata_get((void **) &dummy, key_name, g_inode_cginame_map);
- if (!dummy) {
- /* Insert a new item if key not found */
- char *put_key = apr_psprintf(g_inode_cginame_map, "%lX%lX",
- procnode->inode,
- (unsigned long) procnode->deviceid);
- char *fcgipath = apr_psprintf(g_inode_cginame_map, "%s",
- procinfo->cgipath);
-
- if (put_key && fcgipath)
- apr_pool_userdata_set(fcgipath, put_key, NULL,
- g_inode_cginame_map);
- }
+ ap_log_error(APLOG_MARK, APLOG_ERR, rv, procinfo->main_server,
+ "mod_fcgid: couldn't set child process attributes: %s",
+ unix_addr.sun_path);
+ close(unix_socket);
+ return rv;
+ }
+
+ /* fork and exec now */
+ if (lpszwapper != NULL && lpszwapper[0] != '\0') {
+ ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, procinfo->main_server,
+ "mod_fcgid: call %s with wrapper %s",
+ procinfo->cgipath, lpszwapper);
+ if ((rv =
+ fcgid_create_privileged_process(procnode->proc_id,
+ wargv[0],
+ (const char *const *) wargv,
+ (const char *const *)
+ proc_environ, procattr,
+ procinfo,
+ procnode->proc_pool)) !=
+ APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, rv, procinfo->main_server,
+ "mod_fcgid: can't create wrapper process for %s",
+ procinfo->cgipath);
+ close(unix_socket);
+ return rv;
+ }
+ } else {
+ argv[0] = procinfo->cgipath;
+ argv[1] = NULL;
+ if ((rv =
+ fcgid_create_privileged_process(procnode->proc_id,
+ procinfo->cgipath,
+ (const char *const *) argv,
+ (const char *const *)
+ proc_environ, procattr,
+ procinfo,
+ procnode->proc_pool)) !=
+ APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, rv, procinfo->main_server,
+ "mod_fcgid: can't create process");
+ close(unix_socket);
+ return rv;
+ }
+ }
+
+ /* Set the (deviceid, inode) -> fastcgi path map for log */
+ apr_snprintf(key_name, _POSIX_PATH_MAX, "%lX%lX",
+ procnode->inode, (unsigned long) procnode->deviceid);
+ dummy = NULL;
+ apr_pool_userdata_get((void **) &dummy, key_name, g_inode_cginame_map);
+ if (!dummy) {
+ /* Insert a new item if key not found */
+ char *put_key = apr_psprintf(g_inode_cginame_map, "%lX%lX",
+ procnode->inode,
+ (unsigned long) procnode->deviceid);
+ char *fcgipath = apr_psprintf(g_inode_cginame_map, "%s",
+ procinfo->cgipath);
+
+ if (put_key && fcgipath)
+ apr_pool_userdata_set(fcgipath, put_key, NULL,
+ g_inode_cginame_map);
+ }
- /* Close socket before try to connect to it */
- close(unix_socket);
+ /* Close socket before try to connect to it */
+ close(unix_socket);
- return APR_SUCCESS;
+ return APR_SUCCESS;
}
apr_status_t
proc_kill_gracefully(fcgid_procnode * procnode, server_rec * main_server)
{
- /* su as root before sending kill signal, for suEXEC */
- apr_status_t rv;
+ /* su as root before sending kill signal, for suEXEC */
+ apr_status_t rv;
- if (unixd_config.suexec_enabled && seteuid(0) != 0) {
+ if (unixd_config.suexec_enabled && seteuid(0) != 0) {
- /* It's fatal error */
- kill(getpid(), SIGTERM);
- return APR_EACCES;
- }
- rv = apr_proc_kill(procnode->proc_id, SIGTERM);
- if (unixd_config.suexec_enabled && seteuid(unixd_config.user_id) != 0) {
- kill(getpid(), SIGTERM);
- return APR_EACCES;
- }
- return rv;
+ /* It's fatal error */
+ kill(getpid(), SIGTERM);
+ return APR_EACCES;
+ }
+ rv = apr_proc_kill(procnode->proc_id, SIGTERM);
+ if (unixd_config.suexec_enabled && seteuid(unixd_config.user_id) != 0) {
+ kill(getpid(), SIGTERM);
+ return APR_EACCES;
+ }
+ return rv;
}
apr_status_t proc_kill_force(fcgid_procnode * procnode,
- server_rec * main_server)
+ server_rec * main_server)
{
- apr_status_t rv;
+ apr_status_t rv;
- if (unixd_config.suexec_enabled && seteuid(0) != 0) {
+ if (unixd_config.suexec_enabled && seteuid(0) != 0) {
- /* It's fatal error */
- kill(getpid(), SIGTERM);
- return APR_EACCES;
- }
- rv = apr_proc_kill(procnode->proc_id, SIGKILL);
- if (unixd_config.suexec_enabled && seteuid(unixd_config.user_id) != 0) {
- kill(getpid(), SIGTERM);
- return APR_EACCES;
- }
- return rv;
+ /* It's fatal error */
+ kill(getpid(), SIGTERM);
+ return APR_EACCES;
+ }
+ rv = apr_proc_kill(procnode->proc_id, SIGKILL);
+ if (unixd_config.suexec_enabled && seteuid(unixd_config.user_id) != 0) {
+ kill(getpid(), SIGTERM);
+ return APR_EACCES;
+ }
+ return rv;
}
apr_status_t
proc_wait_process(server_rec * main_server, fcgid_procnode * procnode)
{
- apr_status_t rv;
- int exitcode;
- apr_exit_why_e exitwhy;
-
- rv = apr_proc_wait(procnode->proc_id, &exitcode, &exitwhy, APR_NOWAIT);
- if (rv == APR_CHILD_DONE || rv == APR_EGENERAL) {
- /* Log why and how it die */
- proc_print_exit_info(procnode, exitcode, exitwhy, main_server);
-
- /* Register the death */
- register_termination(main_server, procnode);
-
- /* Destroy pool */
- apr_pool_destroy(procnode->proc_pool);
- procnode->proc_pool = NULL;
+ apr_status_t rv;
+ int exitcode;
+ apr_exit_why_e exitwhy;
+
+ rv = apr_proc_wait(procnode->proc_id, &exitcode, &exitwhy, APR_NOWAIT);
+ if (rv == APR_CHILD_DONE || rv == APR_EGENERAL) {
+ /* Log why and how it die */
+ proc_print_exit_info(procnode, exitcode, exitwhy, main_server);
+
+ /* Register the death */
+ register_termination(main_server, procnode);
+
+ /* Destroy pool */
+ apr_pool_destroy(procnode->proc_pool);
+ procnode->proc_pool = NULL;
- return APR_CHILD_DONE;
- }
+ return APR_CHILD_DONE;
+ }
- return rv;
+ return rv;
}
static apr_status_t ipc_handle_cleanup(void *thesocket)
{
- fcgid_namedpipe_handle *handle_info =
- (fcgid_namedpipe_handle *) thesocket;
+ fcgid_namedpipe_handle *handle_info =
+ (fcgid_namedpipe_handle *) thesocket;
- if (handle_info) {
- if (handle_info->handle_socket != -1) {
- close(handle_info->handle_socket);
- handle_info->handle_socket = -1;
- }
- }
+ if (handle_info) {
+ if (handle_info->handle_socket != -1) {
+ close(handle_info->handle_socket);
+ handle_info->handle_socket = -1;
+ }
+ }
- return APR_SUCCESS;
+ return APR_SUCCESS;
}
static apr_status_t set_socket_nonblock(int sd)
{
#ifndef BEOS
- int fd_flags;
+ int fd_flags;
- fd_flags = fcntl(sd, F_GETFL, 0);
+ fd_flags = fcntl(sd, F_GETFL, 0);
#if defined(O_NONBLOCK)
- fd_flags |= O_NONBLOCK;
+ fd_flags |= O_NONBLOCK;
#elif defined(O_NDELAY)
- fd_flags |= O_NDELAY;
+ fd_flags |= O_NDELAY;
#elif defined(FNDELAY)
- fd_flags |= FNDELAY;
+ fd_flags |= FNDELAY;
#else
#error Please teach APR how to make sockets non-blocking on your platform.
#endif
- if (fcntl(sd, F_SETFL, fd_flags) == -1) {
- return errno;
- }
+ if (fcntl(sd, F_SETFL, fd_flags) == -1) {
+ return errno;
+ }
#else
- int on = 1;
- if (setsockopt(sd, SOL_SOCKET, SO_NONBLOCK, &on, sizeof(int)) < 0)
- return errno;
-#endif /* BEOS */
- return APR_SUCCESS;
+ int on = 1;
+ if (setsockopt(sd, SOL_SOCKET, SO_NONBLOCK, &on, sizeof(int)) < 0)
+ return errno;
+#endif /* BEOS */
+ return APR_SUCCESS;
}
apr_status_t
proc_connect_ipc(server_rec * main_server,
- fcgid_procnode * procnode, fcgid_ipc * ipc_handle)
+ fcgid_procnode * procnode, fcgid_ipc * ipc_handle)
{
- fcgid_namedpipe_handle *handle_info;
- struct sockaddr_un unix_addr;
- apr_status_t rv;
- apr_int32_t on = 1;
-
- /* Alloc memory for unix domain socket */
- ipc_handle->ipc_handle_info
- = (fcgid_namedpipe_handle *) apr_pcalloc(ipc_handle->request->pool,
- sizeof
- (fcgid_namedpipe_handle));
- if (!ipc_handle->ipc_handle_info)
- return APR_ENOMEM;
- handle_info = (fcgid_namedpipe_handle *) ipc_handle->ipc_handle_info;
- handle_info->handle_socket = socket(AF_UNIX, SOCK_STREAM, 0);
- apr_pool_cleanup_register(ipc_handle->request->pool,
- handle_info, ipc_handle_cleanup,
- apr_pool_cleanup_null);
-
- /* Connect to fastcgi server */
- memset(&unix_addr, 0, sizeof(unix_addr));
- unix_addr.sun_family = AF_UNIX;
- strncpy(unix_addr.sun_path, procnode->socket_path,
- sizeof(unix_addr.sun_path) - 1);
-
- /* I am the only one who connecting the server
- So I don't have to worry about ECONNREFUSED(listen queue overflow) problem,
- and I will never retry on error */
- if (connect(handle_info->handle_socket, (struct sockaddr *) &unix_addr,
- sizeof(unix_addr)) < 0) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, apr_get_os_error(),
- main_server,
- "mod_fcgid: can't connect unix domain socket: %s",
- procnode->socket_path);
- return APR_ECONNREFUSED;
- }
-
- /* Set no delay option */
- setsockopt(handle_info->handle_socket, IPPROTO_TCP, TCP_NODELAY,
- (char *) &on, sizeof(on));
-
- /* Set nonblock option */
- if ((rv =
- set_socket_nonblock(handle_info->handle_socket)) != APR_SUCCESS) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, main_server,
- "mod_fcgid: can't set nonblock unix domain socket");
- return rv;
- }
+ fcgid_namedpipe_handle *handle_info;
+ struct sockaddr_un unix_addr;
+ apr_status_t rv;
+ apr_int32_t on = 1;
+
+ /* Alloc memory for unix domain socket */
+ ipc_handle->ipc_handle_info
+ = (fcgid_namedpipe_handle *) apr_pcalloc(ipc_handle->request->pool,
+ sizeof
+ (fcgid_namedpipe_handle));
+ if (!ipc_handle->ipc_handle_info)
+ return APR_ENOMEM;
+ handle_info = (fcgid_namedpipe_handle *) ipc_handle->ipc_handle_info;
+ handle_info->handle_socket = socket(AF_UNIX, SOCK_STREAM, 0);
+ apr_pool_cleanup_register(ipc_handle->request->pool,
+ handle_info, ipc_handle_cleanup,
+ apr_pool_cleanup_null);
+
+ /* Connect to fastcgi server */
+ memset(&unix_addr, 0, sizeof(unix_addr));
+ unix_addr.sun_family = AF_UNIX;
+ strncpy(unix_addr.sun_path, procnode->socket_path,
+ sizeof(unix_addr.sun_path) - 1);
+
+ /* I am the only one who connecting the server
+ So I don't have to worry about ECONNREFUSED(listen queue overflow) problem,
+ and I will never retry on error */
+ if (connect(handle_info->handle_socket, (struct sockaddr *) &unix_addr,
+ sizeof(unix_addr)) < 0) {
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, apr_get_os_error(),
+ main_server,
+ "mod_fcgid: can't connect unix domain socket: %s",
+ procnode->socket_path);
+ return APR_ECONNREFUSED;
+ }
+
+ /* Set no delay option */
+ setsockopt(handle_info->handle_socket, IPPROTO_TCP, TCP_NODELAY,
+ (char *) &on, sizeof(on));
+
+ /* Set nonblock option */
+ if ((rv =
+ set_socket_nonblock(handle_info->handle_socket)) != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, main_server,
+ "mod_fcgid: can't set nonblock unix domain socket");
+ return rv;
+ }
- return APR_SUCCESS;
+ return APR_SUCCESS;
}
apr_status_t proc_close_ipc(server_rec * main_server,
- fcgid_ipc * ipc_handle)
+ fcgid_ipc * ipc_handle)
{
- apr_status_t rv;
+ apr_status_t rv;
- rv = apr_pool_cleanup_run(ipc_handle->request->pool,
- ipc_handle->ipc_handle_info,
- ipc_handle_cleanup);
- ipc_handle->ipc_handle_info = NULL;
- return rv;
+ rv = apr_pool_cleanup_run(ipc_handle->request->pool,
+ ipc_handle->ipc_handle_info,
+ ipc_handle_cleanup);
+ ipc_handle->ipc_handle_info = NULL;
+ return rv;
}
apr_status_t proc_read_ipc(server_rec * main_server,
- fcgid_ipc * ipc_handle, const char *buffer,
- apr_size_t * size)
+ fcgid_ipc * ipc_handle, const char *buffer,
+ apr_size_t * size)
{
- int retcode, unix_socket;
- fcgid_namedpipe_handle *handle_info;
- struct pollfd pollfds[1];
-
- handle_info = (fcgid_namedpipe_handle *) ipc_handle->ipc_handle_info;
- unix_socket = handle_info->handle_socket;
-
- do {
- if ((retcode = read(unix_socket, (void *) buffer, *size)) > 0) {
- *size = retcode;
- return APR_SUCCESS;
- }
- } while (retcode == -1 && APR_STATUS_IS_EINTR(errno));
- if (retcode == -1 && !APR_STATUS_IS_EAGAIN(errno)) {
- ap_log_error(APLOG_MARK, APLOG_WARNING, errno,
- main_server,
- "mod_fcgid: read data from fastcgi server error");
- return errno;
- }
-
- /* I have to wait a while */
-
- pollfds[0].fd = unix_socket;
- pollfds[0].events = POLLIN;
- do {
- retcode = poll(pollfds, 1, ipc_handle->communation_timeout * 1000);
- } while (retcode <= 0 && APR_STATUS_IS_EINTR(errno));
- if (retcode == -1) {
- ap_log_error(APLOG_MARK, APLOG_WARNING, errno,
- main_server,
- "mod_fcgid: poll unix domain socket error");
- return errno;
- } else if (retcode == 0) {
- ap_log_error(APLOG_MARK, APLOG_WARNING, 0,
- main_server,
- "mod_fcgid: read data timeout in %d seconds",
- ipc_handle->communation_timeout);
- return APR_ETIMEDOUT;
- }
-
- do {
- if ((retcode = read(unix_socket, (void *) buffer, *size)) > 0) {
- *size = retcode;
- return APR_SUCCESS;
- }
- } while (retcode == -1 && APR_STATUS_IS_EINTR(errno));
-
- if (retcode == 0) {
- ap_log_error(APLOG_MARK, APLOG_WARNING, 0,
- main_server,
- "mod_fcgid: Read data error, fastcgi server has close connection");
- return APR_EPIPE;
- }
-
- ap_log_error(APLOG_MARK, APLOG_WARNING, errno,
- main_server,
- "mod_fcgid: read data from fastcgi server error.");
- return errno;
+ int retcode, unix_socket;
+ fcgid_namedpipe_handle *handle_info;
+ struct pollfd pollfds[1];
+
+ handle_info = (fcgid_namedpipe_handle *) ipc_handle->ipc_handle_info;
+ unix_socket = handle_info->handle_socket;
+
+ do {
+ if ((retcode = read(unix_socket, (void *) buffer, *size)) > 0) {
+ *size = retcode;
+ return APR_SUCCESS;
+ }
+ } while (retcode == -1 && APR_STATUS_IS_EINTR(errno));
+ if (retcode == -1 && !APR_STATUS_IS_EAGAIN(errno)) {
+ ap_log_error(APLOG_MARK, APLOG_WARNING, errno,
+ main_server,
+ "mod_fcgid: read data from fastcgi server error");
+ return errno;
+ }
+
+ /* I have to wait a while */
+
+ pollfds[0].fd = unix_socket;
+ pollfds[0].events = POLLIN;
+ do {
+ retcode = poll(pollfds, 1, ipc_handle->communation_timeout * 1000);
+ } while (retcode <= 0 && APR_STATUS_IS_EINTR(errno));
+ if (retcode == -1) {
+ ap_log_error(APLOG_MARK, APLOG_WARNING, errno,
+ main_server,
+ "mod_fcgid: poll unix domain socket error");
+ return errno;
+ } else if (retcode == 0) {
+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0,
+ main_server,
+ "mod_fcgid: read data timeout in %d seconds",
+ ipc_handle->communation_timeout);
+ return APR_ETIMEDOUT;
+ }
+
+ do {
+ if ((retcode = read(unix_socket, (void *) buffer, *size)) > 0) {
+ *size = retcode;
+ return APR_SUCCESS;
+ }
+ } while (retcode == -1 && APR_STATUS_IS_EINTR(errno));
+
+ if (retcode == 0) {
+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0,
+ main_server,
+ "mod_fcgid: Read data error, fastcgi server has close connection");
+ return APR_EPIPE;
+ }
+
+ ap_log_error(APLOG_MARK, APLOG_WARNING, errno,
+ main_server,
+ "mod_fcgid: read data from fastcgi server error.");
+ return errno;
}
static apr_status_t socket_writev(fcgid_ipc * ipc_handle,
- struct iovec *vec, int nvec,
- int *writecnt)
+ struct iovec *vec, int nvec,
+ int *writecnt)
{
- int retcode, unix_socket;
- fcgid_namedpipe_handle *handle_info;
- struct pollfd pollfds[1];
-
- handle_info = (fcgid_namedpipe_handle *) ipc_handle->ipc_handle_info;
- unix_socket = handle_info->handle_socket;
-
- /* Try nonblock write */
- do {
- if ((retcode = writev(unix_socket, vec, nvec)) > 0) {
- *writecnt = retcode;
- return APR_SUCCESS;
- }
- } while (retcode == -1 && APR_STATUS_IS_EINTR(errno));
- if (!APR_STATUS_IS_EAGAIN(errno))
- return errno;
-
- /* poll() */
- pollfds[0].fd = unix_socket;
- pollfds[0].events = POLLOUT;
- do {
- retcode = poll(pollfds, 1, ipc_handle->communation_timeout * 1000);
- } while (retcode <= 0 && APR_STATUS_IS_EINTR(errno));
- if (retcode == -1)
- return errno;
-
- /* Write again */
- do {
- if ((retcode = writev(unix_socket, vec, nvec)) > 0) {
- *writecnt = retcode;
- return APR_SUCCESS;
- }
- } while (retcode == -1 && APR_STATUS_IS_EINTR(errno));
-
- if (retcode == 0) {
- ap_log_error(APLOG_MARK, APLOG_INFO, 0,
- ipc_handle->request->server,
- "mod_fcgid: Write data error, fastcgi server has close connection");
- return APR_EPIPE;
- }
+ int retcode, unix_socket;
+ fcgid_namedpipe_handle *handle_info;
+ struct pollfd pollfds[1];
+
+ handle_info = (fcgid_namedpipe_handle *) ipc_handle->ipc_handle_info;
+ unix_socket = handle_info->handle_socket;
+
+ /* Try nonblock write */
+ do {
+ if ((retcode = writev(unix_socket, vec, nvec)) > 0) {
+ *writecnt = retcode;
+ return APR_SUCCESS;
+ }
+ } while (retcode == -1 && APR_STATUS_IS_EINTR(errno));
+ if (!APR_STATUS_IS_EAGAIN(errno))
+ return errno;
+
+ /* poll() */
+ pollfds[0].fd = unix_socket;
+ pollfds[0].events = POLLOUT;
+ do {
+ retcode = poll(pollfds, 1, ipc_handle->communation_timeout * 1000);
+ } while (retcode <= 0 && APR_STATUS_IS_EINTR(errno));
+ if (retcode == -1)
+ return errno;
+
+ /* Write again */
+ do {
+ if ((retcode = writev(unix_socket, vec, nvec)) > 0) {
+ *writecnt = retcode;
+ return APR_SUCCESS;
+ }
+ } while (retcode == -1 && APR_STATUS_IS_EINTR(errno));
+
+ if (retcode == 0) {
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0,
+ ipc_handle->request->server,
+ "mod_fcgid: Write data error, fastcgi server has close connection");
+ return APR_EPIPE;
+ }
- return errno;
+ return errno;
}
static apr_status_t writev_it_all(fcgid_ipc * ipc_handle,
- struct iovec *vec, int nvec)
+ struct iovec *vec, int nvec)
{
- apr_size_t bytes_written = 0;
- apr_status_t rv;
- apr_size_t len = 0;
- int i = 0;
- int writecnt = 0;
-
- /* Calculate the total size */
- for (i = 0; i < nvec; i++) {
- len += vec[i].iov_len;
- }
-
- i = 0;
- while (bytes_written != len) {
- rv = socket_writev(ipc_handle, vec + i, nvec - i, &writecnt);
- if (rv != APR_SUCCESS)
- return rv;
- bytes_written += writecnt;
-
- if (bytes_written < len) {
- /* Skip over the vectors that have already been written */
- apr_size_t cnt = vec[i].iov_len;
-
- while (writecnt >= cnt && i + 1 < nvec) {
- i++;
- cnt += vec[i].iov_len;
- }
-
- if (writecnt < cnt) {
- /* Handle partial write of vec i */
- vec[i].iov_base = (char *) vec[i].iov_base +
- (vec[i].iov_len - (cnt - writecnt));
- vec[i].iov_len = cnt - writecnt;
- }
- }
- }
+ apr_size_t bytes_written = 0;
+ apr_status_t rv;
+ apr_size_t len = 0;
+ int i = 0;
+ int writecnt = 0;
+
+ /* Calculate the total size */
+ for (i = 0; i < nvec; i++) {
+ len += vec[i].iov_len;
+ }
+
+ i = 0;
+ while (bytes_written != len) {
+ rv = socket_writev(ipc_handle, vec + i, nvec - i, &writecnt);
+ if (rv != APR_SUCCESS)
+ return rv;
+ bytes_written += writecnt;
+
+ if (bytes_written < len) {
+ /* Skip over the vectors that have already been written */
+ apr_size_t cnt = vec[i].iov_len;
+
+ while (writecnt >= cnt && i + 1 < nvec) {
+ i++;
+ cnt += vec[i].iov_len;
+ }
+
+ if (writecnt < cnt) {
+ /* Handle partial write of vec i */
+ vec[i].iov_base = (char *) vec[i].iov_base +
+ (vec[i].iov_len - (cnt - writecnt));
+ vec[i].iov_len = cnt - writecnt;
+ }
+ }
+ }
- return APR_SUCCESS;
+ return APR_SUCCESS;
}
#define FCGID_VEC_COUNT 8
apr_status_t proc_write_ipc(server_rec * main_server,
- fcgid_ipc * ipc_handle,
- apr_bucket_brigade * output_brigade)
+ fcgid_ipc * ipc_handle,
+ apr_bucket_brigade * output_brigade)
{
- apr_status_t rv;
- struct iovec vec[FCGID_VEC_COUNT];
- int nvec = 0;
- apr_bucket *e;
-
- for (e = APR_BRIGADE_FIRST(output_brigade);
- e != APR_BRIGADE_SENTINEL(output_brigade);
- e = APR_BUCKET_NEXT(e)) {
- /* Read bucket */
- if ((rv = apr_bucket_read(e, (const char **) &vec[nvec].iov_base,
- &vec[nvec].iov_len,
- APR_BLOCK_READ)) != APR_SUCCESS)
- return rv;
-
- if (nvec == (FCGID_VEC_COUNT - 1)) {
- /* It's time to write now */
- if ((rv =
- writev_it_all(ipc_handle, vec,
- FCGID_VEC_COUNT)) != APR_SUCCESS)
- return rv;
- nvec = 0;
- } else
- nvec++;
- }
-
- /* There are something left */
- if (nvec != 0) {
- if ((rv = writev_it_all(ipc_handle, vec, nvec)) != APR_SUCCESS)
- return rv;
- }
+ apr_status_t rv;
+ struct iovec vec[FCGID_VEC_COUNT];
+ int nvec = 0;
+ apr_bucket *e;
+
+ for (e = APR_BRIGADE_FIRST(output_brigade);
+ e != APR_BRIGADE_SENTINEL(output_brigade);
+ e = APR_BUCKET_NEXT(e)) {
+ /* Read bucket */
+ if ((rv = apr_bucket_read(e, (const char **) &vec[nvec].iov_base,
+ &vec[nvec].iov_len,
+ APR_BLOCK_READ)) != APR_SUCCESS)
+ return rv;
+
+ if (nvec == (FCGID_VEC_COUNT - 1)) {
+ /* It's time to write now */
+ if ((rv =
+ writev_it_all(ipc_handle, vec,
+ FCGID_VEC_COUNT)) != APR_SUCCESS)
+ return rv;
+ nvec = 0;
+ } else
+ nvec++;
+ }
+
+ /* There are something left */
+ if (nvec != 0) {
+ if ((rv = writev_it_all(ipc_handle, vec, nvec)) != APR_SUCCESS)
+ return rv;
+ }
- return APR_SUCCESS;
+ return APR_SUCCESS;
}
void
proc_print_exit_info(fcgid_procnode * procnode, int exitcode,
- apr_exit_why_e exitwhy, server_rec * main_server)
+ apr_exit_why_e exitwhy, server_rec * main_server)
{
- char *cgipath = NULL;
- char *diewhy = NULL;
- char signal_info[HUGE_STRING_LEN];
- char key_name[_POSIX_PATH_MAX];
- int signum = exitcode;
-
- memset(signal_info, 0, HUGE_STRING_LEN);
-
- /* Get the file name infomation base on inode and deviceid */
- apr_snprintf(key_name, _POSIX_PATH_MAX, "%lX%lX",
- procnode->inode, (unsigned long) procnode->deviceid);
- apr_pool_userdata_get((void **) &cgipath, key_name,
- g_inode_cginame_map);
-
- /* Reasons to exit */
- switch (procnode->diewhy) {
- case FCGID_DIE_KILLSELF:
- diewhy = "normal exit";
- break;
- case FCGID_DIE_IDLE_TIMEOUT:
- diewhy = "idle timeout";
- break;
- case FCGID_DIE_LIFETIME_EXPIRED:
- diewhy = "lifetime expired";
- break;
- case FCGID_DIE_BUSY_TIMEOUT:
- diewhy = "busy timeout";
- break;
- case FCGID_DIE_CONNECT_ERROR:
- diewhy = "connect error";
- break;
- case FCGID_DIE_COMM_ERROR:
- diewhy = "communication error";
- break;
- case FCGID_DIE_SHUTDOWN:
- diewhy = "shutting down";
- break;
- default:
- diewhy = "unknow";
- }
-
- /* Get signal info */
- if (APR_PROC_CHECK_SIGNALED(exitwhy)) {
- switch (signum) {
- case SIGTERM:
- case SIGHUP:
- case AP_SIG_GRACEFUL:
- case SIGKILL:
- apr_snprintf(signal_info, HUGE_STRING_LEN - 1,
- "get stop signal %d", signum);
- break;
-
- default:
- if (APR_PROC_CHECK_CORE_DUMP(exitwhy)) {
- apr_snprintf(signal_info, HUGE_STRING_LEN - 1,
- "get signal %d, possible coredump generated",
- signum);
- } else {
- apr_snprintf(signal_info, HUGE_STRING_LEN - 1,
- "get unexpected signal %d", signum);
- }
- }
- } else if (APR_PROC_CHECK_EXIT(exitwhy)) {
- apr_snprintf(signal_info, HUGE_STRING_LEN - 1,
- "terminated by calling exit(), return code: %d",
- exitcode);
- if (procnode->diewhy == FCGID_DIE_CONNECT_ERROR)
- diewhy = "server exited";
- }
-
- /* Print log now */
- if (cgipath)
- ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, main_server,
- "mod_fcgid: process %s(%d) exit(%s), %s",
- cgipath, procnode->proc_id->pid, diewhy, signal_info);
- else
- ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, main_server,
- "mod_fcgid: can't get cgi name while exiting, exitcode: %d",
- exitcode);
+ char *cgipath = NULL;
+ char *diewhy = NULL;
+ char signal_info[HUGE_STRING_LEN];
+ char key_name[_POSIX_PATH_MAX];
+ int signum = exitcode;
+
+ memset(signal_info, 0, HUGE_STRING_LEN);
+
+ /* Get the file name infomation base on inode and deviceid */
+ apr_snprintf(key_name, _POSIX_PATH_MAX, "%lX%lX",
+ procnode->inode, (unsigned long) procnode->deviceid);
+ apr_pool_userdata_get((void **) &cgipath, key_name,
+ g_inode_cginame_map);
+
+ /* Reasons to exit */
+ switch (procnode->diewhy) {
+ case FCGID_DIE_KILLSELF:
+ diewhy = "normal exit";
+ break;
+ case FCGID_DIE_IDLE_TIMEOUT:
+ diewhy = "idle timeout";
+ break;
+ case FCGID_DIE_LIFETIME_EXPIRED:
+ diewhy = "lifetime expired";
+ break;
+ case FCGID_DIE_BUSY_TIMEOUT:
+ diewhy = "busy timeout";
+ break;
+ case FCGID_DIE_CONNECT_ERROR:
+ diewhy = "connect error";
+ break;
+ case FCGID_DIE_COMM_ERROR:
+ diewhy = "communication error";
+ break;
+ case FCGID_DIE_SHUTDOWN:
+ diewhy = "shutting down";
+ break;
+ default:
+ diewhy = "unknow";
+ }
+
+ /* Get signal info */
+ if (APR_PROC_CHECK_SIGNALED(exitwhy)) {
+ switch (signum) {
+ case SIGTERM:
+ case SIGHUP:
+ case AP_SIG_GRACEFUL:
+ case SIGKILL:
+ apr_snprintf(signal_info, HUGE_STRING_LEN - 1,
+ "get stop signal %d", signum);
+ break;
+
+ default:
+ if (APR_PROC_CHECK_CORE_DUMP(exitwhy)) {
+ apr_snprintf(signal_info, HUGE_STRING_LEN - 1,
+ "get signal %d, possible coredump generated",
+ signum);
+ } else {
+ apr_snprintf(signal_info, HUGE_STRING_LEN - 1,
+ "get unexpected signal %d", signum);
+ }
+ }
+ } else if (APR_PROC_CHECK_EXIT(exitwhy)) {
+ apr_snprintf(signal_info, HUGE_STRING_LEN - 1,
+ "terminated by calling exit(), return code: %d",
+ exitcode);
+ if (procnode->diewhy == FCGID_DIE_CONNECT_ERROR)
+ diewhy = "server exited";
+ }
+
+ /* Print log now */
+ if (cgipath)
+ ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, main_server,
+ "mod_fcgid: process %s(%d) exit(%s), %s",
+ cgipath, procnode->proc_id->pid, diewhy, signal_info);
+ else
+ ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, main_server,
+ "mod_fcgid: can't get cgi name while exiting, exitcode: %d",
+ exitcode);
}