static int fcgid_status_hook()

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>&nbsp;&nbsp;(%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;
}