
#include <ngx_config.h>
#include <ngx_core.h>


static void ngx_exec_proc(ngx_cycle_t *cycle, void *data);

ngx_uint_t     ngx_last_process;
ngx_process_t  ngx_processes[NGX_MAX_PROCESSES];


ngx_pid_t ngx_spawn_process(ngx_cycle_t *cycle,
                            ngx_spawn_proc_pt proc, void *data,
                            char *name, ngx_int_t respawn)
{
    sigset_t   set, oset;
    ngx_pid_t  pid;

    if (respawn < 0) {
        sigemptyset(&set);
        sigaddset(&set, SIGCHLD);
        if (sigprocmask(SIG_BLOCK, &set, &oset) == -1) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                          "sigprocmask() failed while spawning %s", name);
            return NGX_ERROR;
        }
    }

    pid = fork();

    if (pid == -1) {
        ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                      "fork() failed while spawning \"%s\"", name);
    }

    if (pid == -1 || pid == 0) {
        if (sigprocmask(SIG_SETMASK, &oset, &set) == -1) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                          "sigprocmask() failed while spawning %s", name);
            return NGX_ERROR;
        }
    }

    switch (pid) {
    case -1:
        return NGX_ERROR;

    case 0:
        proc(cycle, data);
        break;

    default:
        break;
    }

    ngx_log_debug2(NGX_LOG_DEBUG_CORE, cycle->log, 0,
                   "spawn %s: " PID_T_FMT, name, pid);

    if (respawn >= 0) {
        ngx_processes[respawn].pid = pid;
        ngx_processes[respawn].exited = 0;
        return pid;
    }

    ngx_processes[ngx_last_process].pid = pid;
    ngx_processes[ngx_last_process].proc = proc;
    ngx_processes[ngx_last_process].data = data;
    ngx_processes[ngx_last_process].name = name;
    ngx_processes[ngx_last_process].respawn =
                                      (respawn == NGX_PROCESS_RESPAWN) ? 1 : 0;
    ngx_processes[ngx_last_process].detached =
                                     (respawn == NGX_PROCESS_DETACHED) ? 1 : 0;
    ngx_processes[ngx_last_process].signal = 0;
    ngx_processes[ngx_last_process].exited = 0;
    ngx_processes[ngx_last_process].exiting = 0;
    ngx_last_process++;

    if (sigprocmask(SIG_SETMASK, &oset, &set) == -1) {
        ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                      "sigprocmask() failed while spawning %s", name);
        return NGX_ERROR;
    }

    return pid;
}


ngx_pid_t ngx_exec(ngx_cycle_t *cycle, ngx_exec_ctx_t *ctx)
{
    return ngx_spawn_process(cycle, ngx_exec_proc, ctx, ctx->name,
                             NGX_PROCESS_DETACHED);
}


static void ngx_exec_proc(ngx_cycle_t *cycle, void *data)
{
    ngx_exec_ctx_t  *ctx = data;

    if (execve(ctx->path, ctx->argv, ctx->envp) == -1) {
        ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                      "execve() failed while executing %s \"%s\"",
                      ctx->name, ctx->path);
    }

    exit(1);
}


#if 0

void ngx_signal_processes(ngx_cycle_t *cycle)
{
    ngx_uint_t  i;

    for (i = 0; i < ngx_last_process; i++) {

        if (ngx_processes[i].signal0 == 0) {
            continue;
        }

#if 0
        if (ngx_processes[i].exited) {
            if (i != --ngx_last_process) {
                ngx_processes[i--] = ngx_processes[ngx_last_process];
            }
            continue;
        }
#endif

        ngx_log_debug2(NGX_LOG_DEBUG_CORE, cycle->log, 0,
                       "kill (" PID_T_FMT ", %d)" ,
                       ngx_processes[i].pid, ngx_processes[i].signal0);

        if (kill(ngx_processes[i].pid, ngx_processes[i].signal0) == -1) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                          "kill(%d, %d) failed",
                          ngx_processes[i].pid, ngx_processes[i].signal0);
            continue;
        }

        if (ngx_processes[i].signal0 != ngx_signal_value(NGX_REOPEN_SIGNAL)) {
            ngx_processes[i].exiting = 1;
        }
    }
}

#endif


void ngx_respawn_processes(ngx_cycle_t *cycle)
{
    ngx_uint_t  i;

    for (i = 0; i < ngx_last_process; i++) {

        if (ngx_processes[i].exiting || !ngx_processes[i].exited) {
            continue;
        }

        if (!ngx_processes[i].respawn) {
            if (i != --ngx_last_process) {
                ngx_processes[i--] = ngx_processes[ngx_last_process];
            }
            continue;
        }

        if (ngx_spawn_process(cycle,
                              ngx_processes[i].proc, ngx_processes[i].data,
                              ngx_processes[i].name, i) == NGX_ERROR)
        {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
                          "can not respawn %s", ngx_processes[i].name);
        }
    }
}


void ngx_process_get_status()
{
    int              status;
    char            *process;
    ngx_pid_t        pid;
    ngx_err_t        err;
    ngx_uint_t       i, one;
    struct timeval   tv;
    one = 0;

    for ( ;; ) {
        pid = waitpid(-1, &status, WNOHANG);

        if (pid == 0) {
            return;
        }

        if (pid == -1) {
            err = ngx_errno;

            if (err == NGX_EINTR) {
                continue;
            }

            if (err == NGX_ECHILD && one) {
                return;
            }

            ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, errno,
                          "waitpid() failed");
            return;
        }

        one = 1;
        process = "";

        for (i = 0; i < ngx_last_process; i++) {
            if (ngx_processes[i].pid == pid) {
                ngx_processes[i].status = status;
                ngx_processes[i].exited = 1;
                process = ngx_processes[i].name;
                break;
            }
        }

        if (i == ngx_last_process) {
            process = "unknown process";
        }

        if (WTERMSIG(status)) {
            ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
                          "%s " PID_T_FMT " exited on signal %d%s",
                          process, pid, WTERMSIG(status),
                          WCOREDUMP(status) ? " (core dumped)" : "");

        } else {
            ngx_log_error(NGX_LOG_INFO, ngx_cycle->log, 0,
                          "%s " PID_T_FMT " exited with code %d",
                          process, pid, WEXITSTATUS(status));
        }

        if (WEXITSTATUS(status) == 2 && ngx_processes[i].respawn) {
            ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
                          "%s " PID_T_FMT
                          " exited with fatal code %d and could not respawn",
                          process, pid, WEXITSTATUS(status));
            ngx_processes[i].respawn = 0;
        }
    }
}
