/* ====================================================================
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2000-2001 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Apache" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

#include "threadproc.h"
#include "fileio.h"
#include "apr_strings.h"
#include "apr_portable.h"

#include <nks/vm.h>

apr_status_t apr_netware_proc_cleanup(void *theproc)
{
    apr_proc_t *proc = theproc;

	NXVmDestroy(proc->pid);
    return APR_SUCCESS;
}

APR_DECLARE(apr_status_t) apr_procattr_create(apr_procattr_t **new,apr_pool_t *cont)
{
    (*new) = (apr_procattr_t *)apr_pcalloc(cont, sizeof(apr_procattr_t));

    if ((*new) == NULL) {
        return APR_ENOMEM;
    }
    (*new)->cntxt = cont;
    (*new)->cmdtype = APR_PROGRAM;
    return APR_SUCCESS;

}

APR_DECLARE(apr_status_t) apr_procattr_io_set(apr_procattr_t *attr, apr_int32_t in, 
                                 apr_int32_t out, apr_int32_t err)
{
    apr_status_t status;
    if (in != 0) {
        if ((status = apr_file_pipe_create(&attr->child_in, &attr->parent_in, 
                                   attr->cntxt)) != APR_SUCCESS) {
            return status;
        }
        switch (in) {
        case APR_FULL_BLOCK:
            break;
        case APR_PARENT_BLOCK:
            apr_file_pipe_timeout_set(attr->child_in, 0);
            break;
        case APR_CHILD_BLOCK:
            apr_file_pipe_timeout_set(attr->parent_in, 0);
            break;
        default:
            apr_file_pipe_timeout_set(attr->child_in, 0);
            apr_file_pipe_timeout_set(attr->parent_in, 0);
        }
    } 
    if (out) {
        if ((status = apr_file_pipe_create(&attr->parent_out, &attr->child_out, 
                                   attr->cntxt)) != APR_SUCCESS) {
            return status;
        }
        switch (out) {
        case APR_FULL_BLOCK:
            break;
        case APR_PARENT_BLOCK:
            apr_file_pipe_timeout_set(attr->child_out, 0);
            break;
        case APR_CHILD_BLOCK:
            apr_file_pipe_timeout_set(attr->parent_out, 0);
            break;
        default:
            apr_file_pipe_timeout_set(attr->child_out, 0);
            apr_file_pipe_timeout_set(attr->parent_out, 0);
        }
    } 
    if (err) {
        if ((status = apr_file_pipe_create(&attr->parent_err, &attr->child_err, 
                                   attr->cntxt)) != APR_SUCCESS) {
            return status;
        }
        switch (err) {
        case APR_FULL_BLOCK:
            break;
        case APR_PARENT_BLOCK:
            apr_file_pipe_timeout_set(attr->child_err, 0);
            break;
        case APR_CHILD_BLOCK:
            apr_file_pipe_timeout_set(attr->parent_err, 0);
            break;
        default:
            apr_file_pipe_timeout_set(attr->child_err, 0);
            apr_file_pipe_timeout_set(attr->parent_err, 0);
        }
    } 
    return APR_SUCCESS;
}


APR_DECLARE(apr_status_t) apr_procattr_child_in_set(apr_procattr_t *attr, apr_file_t *child_in,
                                   apr_file_t *parent_in)
{
    if (attr->child_in == NULL && attr->parent_in == NULL)
        apr_file_pipe_create(&attr->child_in, &attr->parent_in, attr->cntxt);

    if (child_in != NULL)
        apr_file_dup2(attr->child_in, child_in, attr->cntxt);

    if (parent_in != NULL)
        apr_file_dup2(attr->parent_in, parent_in, attr->cntxt);

    return APR_SUCCESS;
}


APR_DECLARE(apr_status_t) apr_procattr_child_out_set(apr_procattr_t *attr, apr_file_t *child_out,
                                    apr_file_t *parent_out)
{
    if (attr->child_out == NULL && attr->parent_out == NULL)
        apr_file_pipe_create(&attr->child_out, &attr->parent_out, attr->cntxt);

    if (child_out != NULL)
        apr_file_dup2(attr->child_out, child_out, attr->cntxt);

    if (parent_out != NULL)
        apr_file_dup2(attr->parent_out, parent_out, attr->cntxt);

    return APR_SUCCESS;
}


APR_DECLARE(apr_status_t) apr_procattr_child_err_set(apr_procattr_t *attr, apr_file_t *child_err,
                                   apr_file_t *parent_err)
{
    if (attr->child_err == NULL && attr->parent_err == NULL)
        apr_file_pipe_create(&attr->child_err, &attr->parent_err, attr->cntxt);

    if (child_err != NULL)
        apr_file_dup2(attr->child_err, child_err, attr->cntxt);

    if (parent_err != NULL)
        apr_file_dup2(attr->parent_err, parent_err, attr->cntxt);

    return APR_SUCCESS;
}


APR_DECLARE(apr_status_t) apr_procattr_dir_set(apr_procattr_t *attr, 
                               const char *dir) 
{
    attr->currdir = apr_pstrdup(attr->cntxt, dir);
    if (attr->currdir) {
        return APR_SUCCESS;
    }
    return APR_ENOMEM;
}

APR_DECLARE(apr_status_t) apr_procattr_cmdtype_set(apr_procattr_t *attr,
                                     apr_cmdtype_e cmd) 
{
    if (cmd != APR_PROGRAM)
        return APR_ENOTIMPL;
    attr->cmdtype = cmd;
    return APR_SUCCESS;
}

APR_DECLARE(apr_status_t) apr_procattr_detach_set(apr_procattr_t *attr, apr_int32_t detach) 
{
    attr->detached = detach;
    return APR_SUCCESS;
}

#if APR_HAS_FORK
APR_DECLARE(apr_status_t) apr_proc_fork(apr_proc_t *proc, apr_pool_t *cont)
{
    int pid;
    
    if ((pid = fork()) < 0) {
        return errno;
    }
    else if (pid == 0) {
        proc->pid = pid;
        proc->in = NULL; 
        proc->out = NULL; 
        proc->err = NULL; 
        return APR_INCHILD;
    }
    proc->pid = pid;
    proc->in = NULL; 
    proc->out = NULL; 
    proc->err = NULL; 
    return APR_INPARENT;
}
#endif

static apr_status_t limit_proc(apr_procattr_t *attr)
{
#if APR_HAVE_STRUCT_RLIMIT && APR_HAVE_SETRLIMIT
#ifdef RLIMIT_CPU
    if (attr->limit_cpu != NULL) {
        if ((setrlimit(RLIMIT_CPU, attr->limit_cpu)) != 0) {
            return errno;
        }
    }
#endif
#ifdef RLIMIT_NPROC
    if (attr->limit_nproc != NULL) {
        if ((setrlimit(RLIMIT_NPROC, attr->limit_nproc)) != 0) {
            return errno;
        }
    }
#endif
#if defined(RLIMIT_AS)
    if (attr->limit_mem != NULL) {
        if ((setrlimit(RLIMIT_AS, attr->limit_mem)) != 0) {
            return errno;
        }
    }
#elif defined(RLIMIT_DATA)
    if (attr->limit_mem != NULL) {
        if ((setrlimit(RLIMIT_DATA, attr->limit_mem)) != 0) {
            return errno;
        }
    }
#elif defined(RLIMIT_VMEM)
    if (attr->limit_mem != NULL) {
        if ((setrlimit(RLIMIT_VMEM, attr->limit_mem)) != 0) {
            return errno;
        }
    }
#endif
#else
    /*
     * Maybe make a note in error_log that setrlimit isn't supported??
     */

#endif
    return APR_SUCCESS;
}

APR_DECLARE(apr_status_t) apr_proc_create(apr_proc_t *newproc,
									const char *progname, 
									const char * const *args, 
									const char * const *env,
                              		apr_procattr_t *attr, 
                              		apr_pool_t *cont)
{
    int i, envCount;
    const char **newargs;
    char **newenv;
    NXVmId_t newVM;
    unsigned long flags = 0;

    NXNameSpec_t nameSpec;
    NXExecEnvSpec_t envSpec;

    /* Set up the info for the NLM to be started */
    nameSpec.ssType = NX_OBJ_FILE;
    nameSpec.ssPathCtx = NULL;
    nameSpec.ssPath = (void*)progname;

    /* Count how many arguments there are and assign them 
        to the environent */
    for (i=0;args && args[i];i++);
    envSpec.esArgc = i;
    envSpec.esArgv = (void**)args;

    /* Count how many environment variables there are in the
        system, add any new environment variables and place
        them in the environment. */
    for (i=0;env && env[i];i++);
    envCount = NXGetEnvCount();
    if ((envCount + i) > 0) {
        newenv = (char **) NXMemAlloc(sizeof(char *) * (envCount+i+1), 0);
        if (!newenv)
            return APR_ENOMEM;
        NXCopyEnv(newenv, envCount);
        for (i=0;env && env[i];i++) {
            newenv[envCount+i-1] = (char*)env[i];
        }
        newenv[envCount+i] = NULL;

        envSpec.esEnv = (void**)newenv;
    }
    else
        envSpec.esEnv = NULL;

    if (attr->child_in) {
        envSpec.esStdin.ssType = NX_OBJ_FIFO;
        envSpec.esStdin.ssHandle = attr->child_in->filedes;
    }
    else {
        envSpec.esStdin.ssType = NX_OBJ_DEFAULT;
        envSpec.esStdin.ssHandle = -1;
    }
    envSpec.esStdin.ssPathCtx = NULL;
    envSpec.esStdin.ssPath = NULL;
    if (attr->child_out) {
        envSpec.esStdout.ssType = NX_OBJ_FIFO;
        envSpec.esStdout.ssHandle = attr->child_out->filedes;
    }
    else {
        envSpec.esStdout.ssType = NX_OBJ_DEFAULT;
        envSpec.esStdout.ssHandle = -1;
    }
    envSpec.esStdout.ssPathCtx = NULL;
    envSpec.esStdout.ssPath = NULL;
    if (attr->child_err) {
        envSpec.esStderr.ssType = NX_OBJ_FIFO;
        envSpec.esStderr.ssHandle = attr->child_err->filedes;
    }
    else {
        envSpec.esStderr.ssType = NX_OBJ_DEFAULT;
        envSpec.esStderr.ssHandle = -1;
    }
    envSpec.esStderr.ssPathCtx = NULL;
    envSpec.esStderr.ssPath = NULL;

    if (attr->detached) {
        flags = NX_VM_CREATE_DETACHED;
    }
    
    newproc->in = attr->parent_in;
    newproc->err = attr->parent_err;
    newproc->out = attr->parent_out;
    if (NXVmSpawn(&nameSpec, &envSpec, flags, &newVM) != 0) {
        return errno;
    }
    else { 
        newproc->pid = newVM;
        apr_pool_cleanup_register(cont, (void *)newproc, apr_netware_proc_cleanup,
                         apr_pool_cleanup_null);
    }
    return APR_SUCCESS;
}

APR_DECLARE(apr_status_t) apr_proc_wait_all_procs(apr_proc_t *proc,
                                                  int *exitcode,
                                                  apr_exit_why_e *exitwhy,
                                                  apr_wait_how_e waithow,
                                                  apr_pool_t *p)
{
#if 0
    int waitpid_options = WUNTRACED;

    if (waithow != APR_WAIT) {
        waitpid_options |= WNOHANG;
    }

    if ((proc->pid = waitpid(-1, status, waitpid_options)) > 0) {
        return APR_CHILD_DONE;
    }
    else if (proc->pid == 0) {
        return APR_CHILD_NOTDONE;
    }
    return errno;
#else
    return APR_ENOTIMPL;
#endif
} 

APR_DECLARE(apr_status_t) apr_proc_wait(apr_proc_t *proc,
                                        int *exitcode, apr_exit_why_e *exitwhy,
                                        apr_wait_how_e waithow)
{
#if 0
    pid_t status;

    if (waithow == APR_WAIT) {
        if ((status = waitpid(proc->pid, NULL, WUNTRACED)) > 0) {
            return APR_CHILD_DONE;
        }
        else if (status == 0) {
            return APR_CHILD_NOTDONE;
        }
        return errno;
    }
    if ((status = waitpid(proc->pid, NULL, WUNTRACED | WNOHANG)) > 0) {
        return APR_CHILD_DONE;
    }
    else if (status == 0) {
        return APR_CHILD_NOTDONE;
    }
    return errno;
#else
    return APR_ENOTIMPL;
#endif
} 

APR_DECLARE(apr_status_t) apr_procattr_limit_set(apr_procattr_t *attr, apr_int32_t what, 
                          struct rlimit *limit)
{
    switch(what) {
        case APR_LIMIT_CPU:
#ifdef RLIMIT_CPU
            attr->limit_cpu = limit;
            break;
#else
            return APR_ENOTIMPL;
#endif
        case APR_LIMIT_MEM:
#if defined (RLIMIT_DATA) || defined (RLIMIT_VMEM) || defined(RLIMIT_AS)
            attr->limit_mem = limit;
            break;
#else
            return APR_ENOTIMPL;
#endif
        case APR_LIMIT_NPROC:
#ifdef RLIMIT_NPROC
            attr->limit_nproc = limit;
            break;
#else
            return APR_ENOTIMPL;
#endif
    }
    return APR_SUCCESS;
}  

