in modules/fcgid/mod_fcgid.c [345:473]
static int fcgid_status_hook(request_rec *r, int flags)
{
fcgid_procnode **ar = NULL, *current_node;
int num_ent, index;
apr_ino_t last_inode = 0;
apr_dev_t last_deviceid = 0;
gid_t last_gid = 0;
uid_t last_uid = 0;
const char *last_cmdline = "";
apr_time_t now;
int last_vhost_id = -1;
const char *basename, *tmpbasename;
fcgid_procnode *proc_table = proctable_get_table_array();
fcgid_procnode *error_list_header = proctable_get_error_list();
fcgid_procnode *idle_list_header = proctable_get_idle_list();
fcgid_procnode *busy_list_header = proctable_get_busy_list();
if ((flags & AP_STATUS_SHORT) || (proc_table == NULL))
return OK;
proctable_lock(r);
/* Get element count */
num_ent = 0;
current_node = &proc_table[busy_list_header->next_index];
while (current_node != proc_table) {
num_ent++;
current_node = &proc_table[current_node->next_index];
}
current_node = &proc_table[idle_list_header->next_index];
while (current_node != proc_table) {
num_ent++;
current_node = &proc_table[current_node->next_index];
}
current_node = &proc_table[error_list_header->next_index];
while (current_node != proc_table) {
num_ent++;
current_node = &proc_table[current_node->next_index];
}
/* Create an array for qsort() */
if (num_ent != 0) {
ar = (fcgid_procnode **)apr_palloc(r->pool, num_ent * sizeof(fcgid_procnode*));
index = 0;
current_node = &proc_table[busy_list_header->next_index];
while (current_node != proc_table) {
ar[index] = apr_palloc(r->pool, sizeof(fcgid_procnode));
*ar[index] = *current_node;
ar[index++]->node_type = FCGID_PROCNODE_TYPE_BUSY;
current_node = &proc_table[current_node->next_index];
}
current_node = &proc_table[idle_list_header->next_index];
while (current_node != proc_table) {
ar[index] = apr_palloc(r->pool, sizeof(fcgid_procnode));
*ar[index] = *current_node;
ar[index++]->node_type = FCGID_PROCNODE_TYPE_IDLE;
current_node = &proc_table[current_node->next_index];
}
current_node = &proc_table[error_list_header->next_index];
while (current_node != proc_table) {
ar[index] = apr_palloc(r->pool, sizeof(fcgid_procnode));
*ar[index] = *current_node;
ar[index++]->node_type = FCGID_PROCNODE_TYPE_ERROR;
current_node = &proc_table[current_node->next_index];
}
}
proctable_unlock(r);
now = apr_time_now();
/* Sort the array */
if (num_ent != 0)
qsort((void *)ar, num_ent, sizeof(fcgid_procnode *),
(int (*)(const void *, const void *))fcgidsort);
/* Output */
ap_rputs("<hr />\n<h1>mod_fcgid status:</h1>\n", r);
ap_rprintf(r, "Total FastCGI processes: %d\n", num_ent);
for (index = 0; index < num_ent; index++) {
current_node = ar[index];
if (current_node->inode != last_inode || current_node->deviceid != last_deviceid
|| current_node->gid != last_gid || current_node->uid != last_uid
|| strcmp(current_node->cmdline, last_cmdline)
|| current_node->vhost_id != last_vhost_id) {
if (index != 0)
ap_rputs("</table>\n\n", r);
/* Print executable path basename */
tmpbasename = ap_strrchr_c(current_node->executable_path, '/');
if (tmpbasename != NULL)
tmpbasename++;
basename = ap_strrchr_c(tmpbasename, '\\');
if (basename != NULL)
basename++;
else
basename = tmpbasename;
ap_rprintf(r, "<hr />\n<b>Process: %s</b> (%s)<br />\n",
basename, current_node->cmdline);
/* Create a new table for this process info */
ap_rputs("\n\n<table border=\"0\"><tr>"
"<th>Pid</th><th>Active</th><th>Idle</th>"
"<th>Accesses</th><th>State</th>"
"</tr>\n", r);
last_inode = current_node->inode;
last_deviceid = current_node->deviceid;
last_gid = current_node->gid;
last_uid = current_node->uid;
last_cmdline = current_node->cmdline;
last_vhost_id = current_node->vhost_id;
}
ap_rprintf(r, "<tr><td>%" APR_PID_T_FMT "</td><td>%" APR_TIME_T_FMT "</td><td>%" APR_TIME_T_FMT "</td><td>%d</td><td>%s</td></tr>",
current_node->proc_id.pid,
apr_time_sec(now - current_node->start_time),
apr_time_sec(now - current_node->last_active_time),
current_node->requests_handled,
get_state_desc(current_node));
}
if (num_ent != 0) {
ap_rputs("</table>\n\n", r);
ap_rputs("<hr>\n"
"<b>Active</b> and <b>Idle</b> are time active and time since\n"
"last request, in seconds.\n", r);
}
return OK;
}