/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <unistd.h>
#include <sys/un.h>
#include <sys/types.h>
#include <netinet/tcp.h>        /* For TCP_NODELAY */
#include <sys/poll.h>
#include <sys/stat.h>
#define CORE_PRIVATE
#include "httpd.h"
#include "apr_version.h"
#include "apr_thread_proc.h"
#include "apr_strings.h"
#include "apr_portable.h"
#include "apr_pools.h"
#include "apr_network_io.h"
#include "ap_mpm.h"
#include "http_config.h"
#include "mpm_common.h"
#include "util_script.h"
#include "unixd.h"
#include "mod_core.h"
#include "mod_cgi.h"
#include "apr_tables.h"
#include "fcgid_proc.h"
#include "fcgid_proctbl.h"
#include "fcgid_protocol.h"
#include "fcgid_conf.h"
#include "fcgid_pm.h"
#include "fcgid_spawn_ctl.h"

#if MODULE_MAGIC_NUMBER_MAJOR < 20081201
#define ap_unixd_config unixd_config
#endif

#if APR_MAJOR_VERSION < 1
#define APR_FPROT_UWRITE        APR_UWRITE
#define APR_FPROT_UREAD         APR_UREAD
#define APR_FPROT_UEXECUTE      APR_UEXECUTE
#endif

#define DEFAULT_FCGID_LISTENBACKLOG 5

typedef struct {
    int handle_socket;
} fcgid_namedpipe_handle;

static int g_process_counter = 0;

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;
    const char *newprogname;
    const char *execuser, *execgroup;
    const char *argv0;

    if (!ap_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;
    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);
}

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 (!ap_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;

    unlink(procnode->socket_path);
    return APR_SUCCESS;
}

static void log_setid_failure(const char *proc_type,
                              const char *id_type,
                              uid_t user_id)
{
    char errno_desc[120];
    char errmsg[240];

    apr_strerror(errno, errno_desc, sizeof errno_desc);
    apr_snprintf(errmsg, sizeof errmsg,
                 "(%d)%s: %s unable to set %s to %ld\n",
                 errno, errno_desc, proc_type, id_type, (long)user_id);
    write(STDERR_FILENO, errmsg, strlen(errmsg));
}

/* When suexec is enabled, this runs in the forked child
 * process prior to exec().
 */
static apr_status_t exec_setuid_cleanup(void *dummy)
{
    if (seteuid(0) == -1) {
        log_setid_failure("mod_fcgid child", "effective uid", 0);
        _exit(1);
    }
    if (setuid(ap_unixd_config.user_id) == -1) {
        log_setid_failure("mod_fcgid child", "uid", ap_unixd_config.user_id);
        _exit(1);
    }
    return APR_SUCCESS;
}

apr_status_t proc_spawn_process(const char *cmdline, fcgid_proc_info *procinfo,
                                fcgid_procnode *procnode)
{
    server_rec *main_server = procinfo->main_server;
    fcgid_server_conf *sconf = ap_get_module_config(main_server->module_config,
                                                    &fcgid_module);
    apr_status_t rv = APR_SUCCESS;
    apr_file_t *file;
    apr_proc_t tmpproc;
    int omask, retcode, unix_socket;
    char **proc_environ;
    struct sockaddr_un unix_addr;
    apr_procattr_t *procattr = NULL;
    int argc, len;
    const char *wargv[APACHE_ARG_MAX + 1];
    const char *word; /* For wrapper */
    const char *tmp;

    /* Build wrapper args */
    argc = 0;
    tmp = cmdline;
    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;

    /* 
       Create UNIX domain socket before spawn 
     */

    /* Generate a UNIX domain socket file path */
    memset(&unix_addr, 0, sizeof(unix_addr));
    unix_addr.sun_family = AF_UNIX;
    len = apr_snprintf(unix_addr.sun_path, sizeof(unix_addr.sun_path),
                       "%s/%" APR_PID_T_FMT ".%d", sconf->sockname_prefix,
                       getpid(), g_process_counter++);

    /* check for truncation of the socket path
     *
     * cheap but overly zealous check for sun_path overflow: if length of
     * prepared string is at the limit, assume truncation
     */
    if (len + 1 == sizeof(unix_addr.sun_path)
        || len >= sizeof procnode->socket_path) {
        ap_log_error(APLOG_MARK, APLOG_ERR, 0, main_server,
                     "mod_fcgid: socket path length exceeds compiled-in limits");
        return APR_EGENERAL;
    }

    apr_cpystrn(procnode->socket_path, unix_addr.sun_path,
                sizeof(procnode->socket_path));

    /* truncation already checked for in handler or FcgidWrapper parser */
    AP_DEBUG_ASSERT(strlen(wargv[0]) < sizeof(procnode->executable_path));
    apr_cpystrn(procnode->executable_path, wargv[0],
                sizeof(procnode->executable_path));

    /* 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;
    }

    /* Register cleanups to
     * 1. Unlink the socket when the process exits
     * 2. (suexec mode only, in the child cleanup) Switch to the configured uid
     */
    if (ap_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;
    }

    /* IPC directory permissions are safe, but avoid confusion */
    /* Not all flavors of unix use the current umask for AF_UNIX perms */

    rv = apr_file_perms_set(unix_addr.sun_path,
                            APR_FPROT_UREAD|APR_FPROT_UWRITE|APR_FPROT_UEXECUTE);
    if (rv != APR_SUCCESS) {
        ap_log_error(APLOG_MARK, APLOG_CRIT, rv, main_server,
                     "mod_fcgid: Couldn't set permissions on unix domain socket %s",
                     unix_addr.sun_path);
        return rv;
    }

    /* 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, ap_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 ((rv = apr_procattr_create(&procattr, procnode->proc_pool)) != APR_SUCCESS
        || (rv = 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
        || (rv = apr_procattr_dir_set(procattr,
                                      ap_make_dirstr_parent(procnode->proc_pool,
                                                            wargv[0]))) != 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
        || (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 */
    /* Note, don't pass &(procnode->proc_id) to fcgid_create_privileged_process(),
     * for it's a share memory address, both parent and child process may modify 
     * procnode->proc_id->pid, so sometimes it's 0 and sometimes it's >0
     */
    rv = fcgid_create_privileged_process(&tmpproc, wargv[0], wargv,
                                         (const char *const *)proc_environ,
                                         procattr, procinfo,
                                         procnode->proc_pool);

    if (ap_unixd_config.suexec_enabled) {
        /* Prior to creating the child process, a child cleanup was registered
         * to switch the uid in the child.  No-op the child cleanup for this
         * pool so that it won't run again as other child processes are created.
         * (The cleanup will be registered for the pool associated with those
         * processes too.)
         */
        apr_pool_child_cleanup_set(procnode->proc_pool, procnode,
                                   socket_file_cleanup, apr_pool_cleanup_null);
    }

    /* Close socket before try to connect to it */
    close(unix_socket);
    procnode->proc_id = tmpproc;

    if (rv != APR_SUCCESS) {
        ap_log_error(APLOG_MARK, APLOG_ERR, rv, procinfo->main_server,
                     "mod_fcgid: can't run %s", wargv[0]);
    }

    return rv;
}

static apr_status_t proc_kill_internal(fcgid_procnode *procnode, int sig)
{
    /* su as root before sending signal, for suEXEC */
    apr_status_t rv;

    if (ap_unixd_config.suexec_enabled && seteuid(0) != 0) {

        /* can't gain privileges to send signal (should not occur); do NOT
         * proceed, as something is broken with current identity
         */
        log_setid_failure("mod_fcgid PM", "effective uid", 0);
        _exit(1);
    }
    rv = apr_proc_kill(&(procnode->proc_id), sig);
    if (ap_unixd_config.suexec_enabled && seteuid(ap_unixd_config.user_id) != 0) {
        /* can't drop privileges after signalling (should not occur); do NOT
         * proceed any further as euid(0)!
         */
        log_setid_failure("mod_fcgid PM", "effective uid", ap_unixd_config.user_id);
        _exit(1);
    }
    return rv;
}

apr_status_t proc_kill_gracefully(fcgid_procnode *procnode, server_rec *main_server)
{
    return proc_kill_internal(procnode, SIGTERM);
}

apr_status_t proc_kill_force(fcgid_procnode * procnode,
                             server_rec * main_server)
{
    return proc_kill_internal(procnode, SIGKILL);
}

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;

        return APR_CHILD_DONE;
    }

    return rv;
}

static apr_status_t ipc_handle_cleanup(void *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;
        }
    }

    return APR_SUCCESS;
}

static apr_status_t set_socket_nonblock(int sd)
{
#ifndef BEOS
    int fd_flags;

    fd_flags = fcntl(sd, F_GETFL, 0);
#if defined(O_NONBLOCK)
    fd_flags |= O_NONBLOCK;
#elif defined(O_NDELAY)
    fd_flags |= O_NDELAY;
#elif defined(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;
    }
#else
    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(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));
    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;

    /* PM already made this check for truncation */
    AP_DEBUG_ASSERT(sizeof unix_addr.sun_path > strlen(procnode->socket_path));
    apr_cpystrn(unix_addr.sun_path, procnode->socket_path,
                sizeof(unix_addr.sun_path));

    /* 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_rerror(APLOG_MARK, APLOG_DEBUG, apr_get_os_error(),
                      ipc_handle->request,
                      "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_rerror(APLOG_MARK, APLOG_DEBUG, rv, ipc_handle->request,
                      "mod_fcgid: can't make unix domain socket nonblocking");
        return rv;
    }

    return APR_SUCCESS;
}

apr_status_t proc_close_ipc(fcgid_ipc * ipc_handle)
{
    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;
}

apr_status_t proc_read_ipc(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_rerror(APLOG_MARK, APLOG_WARNING, errno,
                      ipc_handle->request,
                      "mod_fcgid: error reading data from FastCGI server");
        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_rerror(APLOG_MARK, APLOG_WARNING, errno,
                      ipc_handle->request,
                      "mod_fcgid: error polling unix domain socket");
        return errno;
    }
    else if (retcode == 0) {
        ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0,
                      ipc_handle->request,
                      "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_rerror(APLOG_MARK, APLOG_WARNING, 0,
                      ipc_handle->request,
                      "mod_fcgid: error reading data, FastCGI server closed connection");
        return APR_EPIPE;
    }

    ap_log_rerror(APLOG_MARK, APLOG_WARNING, errno,
                  ipc_handle->request,
                  "mod_fcgid: error reading data from FastCGI server");
    return errno;
}

static apr_status_t socket_writev(fcgid_ipc *ipc_handle,
                                  struct iovec *vec, int nvec,
                                  int *writecnt)
{
    apr_status_t rv;
    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));
    rv = errno;

    if (APR_STATUS_IS_EAGAIN(rv)) {
        /* 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 < 0) {
            rv = errno;
        }
        else if (retcode == 0) {
            rv = APR_TIMEUP;
        }
        else {
            /* Write again */
            do {
                if ((retcode = writev(unix_socket, vec, nvec)) > 0) {
                    *writecnt = retcode;
                    return APR_SUCCESS;
                }
            } while (retcode == -1 && APR_STATUS_IS_EINTR(errno));
            rv = errno;
        }
    }

    if (APR_STATUS_IS_EAGAIN(rv)) {
        /* socket is writable, but we can't write the entire buffer; try to write a
         * smaller amount, and if even that fails then sleep
         */
        size_t to_write = vec[0].iov_len;
        int slept = 0;
        const apr_interval_time_t sleep_time = APR_USEC_PER_SEC / 4;
        const int max_sleeps = 8;

        do {
            if ((retcode = write(unix_socket, vec[0].iov_base, to_write)) > 0) {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, ipc_handle->request,
                              "wrote %d byte(s) and slept %d time(s) after EAGAIN",
                              retcode, slept);
                *writecnt = retcode;
                return APR_SUCCESS;
            }
            if (APR_STATUS_IS_EAGAIN(errno)) {
                if (to_write == 1) {
                    apr_sleep(sleep_time);
                    ++slept;
                }
                else {
                    to_write /= 2;
                }
            }
        } while ((APR_STATUS_IS_EINTR(errno) || APR_STATUS_IS_EAGAIN(errno))
                 && slept < max_sleeps);
        rv = errno;
    }

    ap_log_rerror(APLOG_MARK, APLOG_INFO, rv,
                  ipc_handle->request,
                  "mod_fcgid: error writing data to FastCGI server");
    return rv;
}

static apr_status_t writev_it_all(fcgid_ipc *ipc_handle,
                                  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;
            }
        }
    }

    return APR_SUCCESS;
}

#define FCGID_VEC_COUNT 8
apr_status_t proc_write_ipc(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 */
        apr_size_t len;
        const char* base;
        if ((rv = apr_bucket_read(e, &base, &len,
                                  APR_BLOCK_READ)) != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_WARNING, rv, ipc_handle->request,
                          "mod_fcgid: can't read request from bucket");
            return rv;
        }

        vec[nvec].iov_len = len;
        vec[nvec].iov_base = (char*) base;
        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;
}

void proc_print_exit_info(fcgid_procnode *procnode, int exitcode,
                          apr_exit_why_e exitwhy, server_rec *main_server)
{
    const char *diewhy = NULL;
    char signal_info[HUGE_STRING_LEN];
    int signum = exitcode;
    int loglevel = APLOG_INFO;

    memset(signal_info, 0, HUGE_STRING_LEN);

    /* 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:
        loglevel = APLOG_ERR;
        diewhy = "unknown";
    }

    /* 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:
            loglevel = APLOG_ERR;
            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 */
    ap_log_error(APLOG_MARK, loglevel, 0, main_server,
                 "mod_fcgid: process %s(%" APR_PID_T_FMT ") exit(%s), %s",
                 procnode->executable_path, procnode->proc_id.pid, diewhy, signal_info);
}
