/* Process handling for Windows.
Copyright (C) 1996-2014 Free Software Foundation, Inc.
This file is part of GNU Make.

GNU Make is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3 of the License, or (at your option) any later
version.

GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.  See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with
this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include <config.h>
#include <stdlib.h>
#include <stdio.h>
#include <io.h>         /* for _get_osfhandle */
#ifdef _MSC_VER
# include <stddef.h>    /* for intptr_t */
#else
# include <stdint.h>
#endif
#include <string.h>
#include <process.h>  /* for msvc _beginthreadex, _endthreadex */
#include <signal.h>
#include <windows.h>

#include "makeint.h"
#include "filedef.h"
#include "variable.h"
#include "sub_proc.h"
#include "proc.h"
#include "w32err.h"
#include "debug.h"

static char *make_command_line(char *shell_name, char *exec_path, char **argv);

typedef struct sub_process_t {
        intptr_t sv_stdin[2];
        intptr_t sv_stdout[2];
        intptr_t sv_stderr[2];
        int using_pipes;
        char *inp;
        DWORD incnt;
        char * volatile outp;
        volatile DWORD outcnt;
        char * volatile errp;
        volatile DWORD errcnt;
        pid_t pid;
        int exit_code;
        int signal;
        long last_err;
        long lerrno;
} sub_process;

/* keep track of children so we can implement a waitpid-like routine */
static sub_process *proc_array[MAXIMUM_WAIT_OBJECTS];
static int proc_index = 0;
static int fake_exits_pending = 0;

/* Windows jobserver implementation variables */
static char jobserver_semaphore_name[MAX_PATH + 1];
static HANDLE jobserver_semaphore = NULL;

/* Open existing jobserver semaphore */
int open_jobserver_semaphore(const char* name)
{
    jobserver_semaphore = OpenSemaphore(
        SEMAPHORE_ALL_ACCESS,   // Semaphore access setting
        FALSE,                  // Child processes DON'T inherit
        name);                  // Semaphore name

    if (jobserver_semaphore == NULL)
        return 0;

    return 1;
}

/* Create new jobserver semaphore */
int create_jobserver_semaphore(int tokens)
{
    sprintf(jobserver_semaphore_name, "gmake_semaphore_%d", _getpid());

    jobserver_semaphore = CreateSemaphore(
        NULL,                           // Use default security descriptor
        tokens,                         // Initial count
        tokens,                         // Maximum count
        jobserver_semaphore_name);      // Semaphore name

    if (jobserver_semaphore == NULL)
        return 0;

    return 1;
}

/* Close jobserver semaphore */
void free_jobserver_semaphore()
{
    if (jobserver_semaphore != NULL)
    {
        CloseHandle(jobserver_semaphore);
        jobserver_semaphore = NULL;
    }
}

/* Decrement semaphore count */
int acquire_jobserver_semaphore()
{
    DWORD dwEvent = WaitForSingleObject(
        jobserver_semaphore,    // Handle to semaphore
        0);                     // DON'T wait on semaphore

    return (dwEvent == WAIT_OBJECT_0);
}

/* Increment semaphore count */
int release_jobserver_semaphore()
{
    BOOL bResult = ReleaseSemaphore(
        jobserver_semaphore,    // handle to semaphore
        1,                      // increase count by one
        NULL);                  // not interested in previous count

    return (bResult);
}

int has_jobserver_semaphore()
{
    return (jobserver_semaphore != NULL);
}

char* get_jobserver_semaphore_name()
{
    return (jobserver_semaphore_name);
}

/* Wait for either the jobserver semaphore to become signalled or one of our
 * child processes to terminate.
 */
int wait_for_semaphore_or_child_process()
{
    HANDLE handles[MAXIMUM_WAIT_OBJECTS];
    DWORD dwHandleCount = 1;
    DWORD dwEvent;
    int i;

    /* Add jobserver semaphore to first slot. */
    handles[0] = jobserver_semaphore;

    /* Build array of handles to wait for */
    for (i = 0; i < proc_index; i++)
    {
        /* Don't wait on child processes that have already finished */
        if (fake_exits_pending && proc_array[i]->exit_code)
            continue;

        handles[dwHandleCount++] = (HANDLE) proc_array[i]->pid;
    }

    dwEvent = WaitForMultipleObjects(
        dwHandleCount,  // number of objects in array
        handles,        // array of objects
        FALSE,          // wait for any object
        INFINITE);      // wait until object is signalled

    switch(dwEvent)
    {
      case WAIT_FAILED:
        return -1;

      case WAIT_OBJECT_0:
        /* Indicate that the semaphore was signalled */
        return 1;

      default:
        /* Assume that one or more of the child processes terminated. */
        return 0;
    }
}

/*
 * When a process has been waited for, adjust the wait state
 * array so that we don't wait for it again
 */
static void
process_adjust_wait_state(sub_process* pproc)
{
        int i;

        if (!proc_index)
                return;

        for (i = 0; i < proc_index; i++)
                if (proc_array[i]->pid == pproc->pid)
                        break;

        if (i < proc_index) {
                proc_index--;
                if (i != proc_index)
                        memmove(&proc_array[i], &proc_array[i+1],
                                (proc_index-i) * sizeof(sub_process*));
                proc_array[proc_index] = NULL;
        }
}

/*
 * Waits for any of the registered child processes to finish.
 */
static sub_process *
process_wait_for_any_private(int block, DWORD* pdwWaitStatus)
{
        HANDLE handles[MAXIMUM_WAIT_OBJECTS];
        DWORD retval, which;
        int i;

        if (!proc_index)
                return NULL;

        /* build array of handles to wait for */
        for (i = 0; i < proc_index; i++) {
                handles[i] = (HANDLE) proc_array[i]->pid;

                if (fake_exits_pending && proc_array[i]->exit_code)
                        break;
        }

        /* wait for someone to exit */
        if (!fake_exits_pending) {
                retval = WaitForMultipleObjects(proc_index, handles, FALSE, (block ? INFINITE : 0));
                which = retval - WAIT_OBJECT_0;
        } else {
                fake_exits_pending--;
                retval = !WAIT_FAILED;
                which = i;
        }

        /* If the pointer is not NULL, set the wait status result variable. */
        if (pdwWaitStatus)
            *pdwWaitStatus = retval;

        /* return pointer to process */
        if ((retval == WAIT_TIMEOUT) || (retval == WAIT_FAILED)) {
                return NULL;
        }
        else {
                sub_process* pproc = proc_array[which];
                process_adjust_wait_state(pproc);
                return pproc;
        }
}

/*
 * Terminate a process.
 */
BOOL
process_kill(HANDLE proc, int signal)
{
        sub_process* pproc = (sub_process*) proc;
        pproc->signal = signal;
        return (TerminateProcess((HANDLE) pproc->pid, signal));
}

/*
 * Use this function to register processes you wish to wait for by
 * calling process_file_io(NULL) or process_wait_any(). This must be done
 * because it is possible for callers of this library to reuse the same
 * handle for multiple processes launches :-(
 */
void
process_register(HANDLE proc)
{
        if (proc_index < MAXIMUM_WAIT_OBJECTS)
                proc_array[proc_index++] = (sub_process *) proc;
}

/*
 * Return the number of processes that we are still waiting for.
 */
int
process_used_slots(void)
{
        return proc_index;
}

/*
 * Public function which works kind of like waitpid(). Wait for any
 * of the children to die and return results. To call this function,
 * you must do 1 of things:
 *
 *      x = process_easy(...);
 *
 * or
 *
 *      x = process_init_fd();
 *      process_register(x);
 *
 * or
 *
 *      x = process_init();
 *      process_register(x);
 *
 * You must NOT then call process_pipe_io() because this function is
 * not capable of handling automatic notification of any child
 * death.
 */

HANDLE
process_wait_for_any(int block, DWORD* pdwWaitStatus)
{
        sub_process* pproc = process_wait_for_any_private(block, pdwWaitStatus);

        if (!pproc)
                return NULL;
        else {
                /*
                 * Ouch! can't tell caller if this fails directly. Caller
                 * will have to use process_last_err()
                 */
                (void) process_file_io(pproc);
                return ((HANDLE) pproc);
        }
}

long
process_signal(HANDLE proc)
{
        if (proc == INVALID_HANDLE_VALUE) return 0;
        return (((sub_process *)proc)->signal);
}

long
process_last_err(HANDLE proc)
{
        if (proc == INVALID_HANDLE_VALUE) return ERROR_INVALID_HANDLE;
        return (((sub_process *)proc)->last_err);
}

long
process_exit_code(HANDLE proc)
{
        if (proc == INVALID_HANDLE_VALUE) return EXIT_FAILURE;
        return (((sub_process *)proc)->exit_code);
}

void
process_noinherit(int fd)
{
  HANDLE fh = (HANDLE)_get_osfhandle(fd);

  if (fh && fh != INVALID_HANDLE_VALUE)
        SetHandleInformation(fh, HANDLE_FLAG_INHERIT, 0);
}

/*
2006-02:
All the following functions are currently unused.
All of them would crash gmake if called with argument INVALID_HANDLE_VALUE.
Hence whoever wants to use one of this functions must invent and implement
a reasonable error handling for this function.

char *
process_outbuf(HANDLE proc)
{
        return (((sub_process *)proc)->outp);
}

char *
process_errbuf(HANDLE proc)
{
        return (((sub_process *)proc)->errp);
}

int
process_outcnt(HANDLE proc)
{
        return (((sub_process *)proc)->outcnt);
}

int
process_errcnt(HANDLE proc)
{
        return (((sub_process *)proc)->errcnt);
}

void
process_pipes(HANDLE proc, int pipes[3])
{
        pipes[0] = ((sub_process *)proc)->sv_stdin[0];
        pipes[1] = ((sub_process *)proc)->sv_stdout[0];
        pipes[2] = ((sub_process *)proc)->sv_stderr[0];
        return;
}
*/

        HANDLE
process_init()
{
        sub_process *pproc;
        /*
         * open file descriptors for attaching stdin/stdout/sterr
         */
        HANDLE stdin_pipes[2];
        HANDLE stdout_pipes[2];
        HANDLE stderr_pipes[2];
        SECURITY_ATTRIBUTES inherit;
        BYTE sd[SECURITY_DESCRIPTOR_MIN_LENGTH];

        pproc = malloc(sizeof(*pproc));
        memset(pproc, 0, sizeof(*pproc));

        /* We can't use NULL for lpSecurityDescriptor because that
           uses the default security descriptor of the calling process.
           Instead we use a security descriptor with no DACL.  This
           allows nonrestricted access to the associated objects. */

        if (!InitializeSecurityDescriptor((PSECURITY_DESCRIPTOR)(&sd),
                                          SECURITY_DESCRIPTOR_REVISION)) {
                pproc->last_err = GetLastError();
                pproc->lerrno = E_SCALL;
                return((HANDLE)pproc);
        }

        inherit.nLength = sizeof(inherit);
        inherit.lpSecurityDescriptor = (PSECURITY_DESCRIPTOR)(&sd);
        inherit.bInheritHandle = TRUE;

        // By convention, parent gets pipe[0], and child gets pipe[1]
        // This means the READ side of stdin pipe goes into pipe[1]
        // and the WRITE side of the stdout and stderr pipes go into pipe[1]
        if (CreatePipe( &stdin_pipes[1], &stdin_pipes[0], &inherit, 0) == FALSE ||
        CreatePipe( &stdout_pipes[0], &stdout_pipes[1], &inherit, 0) == FALSE ||
        CreatePipe( &stderr_pipes[0], &stderr_pipes[1], &inherit, 0) == FALSE) {

                pproc->last_err = GetLastError();
                pproc->lerrno = E_SCALL;
                return((HANDLE)pproc);
        }

        //
        // Mark the parent sides of the pipes as non-inheritable
        //
        if (SetHandleInformation(stdin_pipes[0],
                                HANDLE_FLAG_INHERIT, 0) == FALSE ||
                SetHandleInformation(stdout_pipes[0],
                                HANDLE_FLAG_INHERIT, 0) == FALSE ||
                SetHandleInformation(stderr_pipes[0],
                                HANDLE_FLAG_INHERIT, 0) == FALSE) {

                pproc->last_err = GetLastError();
                pproc->lerrno = E_SCALL;
                return((HANDLE)pproc);
        }
        pproc->sv_stdin[0]  = (intptr_t) stdin_pipes[0];
        pproc->sv_stdin[1]  = (intptr_t) stdin_pipes[1];
        pproc->sv_stdout[0] = (intptr_t) stdout_pipes[0];
        pproc->sv_stdout[1] = (intptr_t) stdout_pipes[1];
        pproc->sv_stderr[0] = (intptr_t) stderr_pipes[0];
        pproc->sv_stderr[1] = (intptr_t) stderr_pipes[1];

        pproc->using_pipes = 1;

        pproc->lerrno = 0;

        return((HANDLE)pproc);
}


        HANDLE
process_init_fd(HANDLE stdinh, HANDLE stdouth, HANDLE stderrh)
{
        sub_process *pproc;

        pproc = malloc(sizeof(*pproc));
        if (pproc) {
                memset(pproc, 0, sizeof(*pproc));

                /*
                 * Just pass the provided file handles to the 'child
                 * side' of the pipe, bypassing pipes altogether.
                 */
                pproc->sv_stdin[1]  = (intptr_t) stdinh;
                pproc->sv_stdout[1] = (intptr_t) stdouth;
                pproc->sv_stderr[1] = (intptr_t) stderrh;

                pproc->last_err = pproc->lerrno = 0;
        }

        return((HANDLE)pproc);
}


static HANDLE
find_file(const char *exec_path, const char *path_var,
          char *full_fname, DWORD full_len)
{
        HANDLE exec_handle;
        char *fname;
        char *ext;
        DWORD req_len;
        int i;
        static const char *extensions[] =
          /* Should .com come before no-extension case?  */
          { ".exe", ".cmd", ".bat", "", ".com", NULL };

        fname = xmalloc(strlen(exec_path) + 5);
        strcpy(fname, exec_path);
        ext = fname + strlen(fname);

        for (i = 0; extensions[i]; i++) {
                strcpy(ext, extensions[i]);
                if (((req_len = SearchPath (path_var, fname, NULL, full_len,
                                            full_fname, NULL)) > 0
                     /* For compatibility with previous code, which
                        used OpenFile, and with Windows operation in
                        general, also look in various default
                        locations, such as Windows directory and
                        Windows System directory.  Warning: this also
                        searches PATH in the Make's environment, which
                        might not be what the Makefile wants, but it
                        seems to be OK as a fallback, after the
                        previous SearchPath failed to find on child's
                        PATH.  */
                     || (req_len = SearchPath (NULL, fname, NULL, full_len,
                                               full_fname, NULL)) > 0)
                    && req_len <= full_len
                    && (exec_handle =
                                CreateFile(full_fname,
                                           GENERIC_READ,
                                           FILE_SHARE_READ | FILE_SHARE_WRITE,
                                           NULL,
                                           OPEN_EXISTING,
                                           FILE_ATTRIBUTE_NORMAL,
                                           NULL)) != INVALID_HANDLE_VALUE) {
                        free(fname);
                        return(exec_handle);
                }
        }

        free(fname);
        return INVALID_HANDLE_VALUE;
}

/*
 * Return non-zero of FNAME specifies a batch file and its name
 * includes embedded whitespace.
 */

static int
batch_file_with_spaces(const char *fname)
{
        size_t fnlen = strlen(fname);

        return (fnlen > 4
                && (_strnicmp(fname + fnlen - 4, ".bat", 4) == 0
                    || _strnicmp(fname + fnlen - 4, ".cmd", 4) == 0)
                /* The set of characters in the 2nd arg to strpbrk
                   should be the same one used by make_command_line
                   below to decide whether an argv[] element needs
                   quoting.  */
                && strpbrk(fname, " \t") != NULL);
}


/*
 * Description:   Create the child process to be helped
 *
 * Returns: success <=> 0
 *
 * Notes/Dependencies:
 */
long
process_begin(
        HANDLE proc,
        char **argv,
        char **envp,
        char *exec_path,
        char *as_user)
{
        sub_process *pproc = (sub_process *)proc;
        char *shell_name = 0;
        int file_not_found=0;
        HANDLE exec_handle;
        char exec_fname[MAX_PATH];
        const char *path_var = NULL;
        char **ep;
        char buf[MAX_PATH];
        DWORD bytes_returned;
        DWORD flags;
        char *command_line;
        STARTUPINFO startInfo;
        PROCESS_INFORMATION procInfo;
        char *envblk=NULL;
        int envsize_needed = 0;
        int pass_null_exec_path = 0;

        /*
         *  Shell script detection...  if the exec_path starts with #! then
         *  we want to exec shell-script-name exec-path, not just exec-path
         *  NT doesn't recognize #!/bin/sh or #!/etc/Tivoli/bin/perl.  We do not
         *  hard-code the path to the shell or perl or whatever:  Instead, we
         *  assume it's in the path somewhere (generally, the NT tools
         *  bin directory)
         */

        /* Use the Makefile's value of PATH to look for the program to
           execute, because it could be different from Make's PATH
           (e.g., if the target sets its own value.  */
        if (envp)
                for (ep = envp; *ep; ep++) {
                        if (strncmp (*ep, "PATH=", 5) == 0
                            || strncmp (*ep, "Path=", 5) == 0) {
                                path_var = *ep + 5;
                                break;
                        }
                }
        exec_handle = find_file(exec_path, path_var,
                                exec_fname, sizeof(exec_fname));

        /*
         * If we couldn't open the file, just assume that Windows will be
         * somehow able to find and execute it.  If the first character
         * of the command is '/', assume they set SHELL to a Unixy shell
         * that have some magic mounts known only to it, and run the whole
         * command via $SHELL -c "COMMAND" instead.
         */
        if (exec_handle == INVALID_HANDLE_VALUE) {
                if (exec_path[0] == '/') {
                        char *new_argv0;
                        char **argvi = argv;
                        int arglen = 0;

                        strcpy(buf, variable_expand ("$(SHELL)"));
                        shell_name = &buf[0];
                        strcpy(exec_fname, "-c");
                        /* Construct a single command string in argv[0].  */
                        while (*argvi) {
                                arglen += strlen(*argvi) + 1;
                                argvi++;
                        }
                        new_argv0 = xmalloc(arglen + 1);
                        new_argv0[0] = '\0';
                        for (argvi = argv; *argvi; argvi++) {
                                strcat(new_argv0, *argvi);
                                strcat(new_argv0, " ");
                        }
                        /* Remove the extra blank at the end.  */
                        new_argv0[arglen-1] = '\0';
                        free(argv[0]);
                        argv[0] = new_argv0;
                        argv[1] = NULL;
                }
                else
                        file_not_found++;
        }
        else {
                /* Attempt to read the first line of the file */
                if (ReadFile( exec_handle,
                                buf, sizeof(buf) - 1, /* leave room for trailing NULL */
                                &bytes_returned, 0) == FALSE || bytes_returned < 2) {

                        pproc->last_err = GetLastError();
                        pproc->lerrno = E_IO;
                        CloseHandle(exec_handle);
                        return(-1);
                }
                if (buf[0] == '#' && buf[1] == '!') {
                        /*
                         *  This is a shell script...  Change the command line from
                         *      exec_path args to shell_name exec_path args
                         */
                        char *p;

                        /*  Make sure buf is NULL terminated */
                        buf[bytes_returned] = 0;
                        /*
                         * Depending on the file system type, etc. the first line
                         * of the shell script may end with newline or newline-carriage-return
                         * Whatever it ends with, cut it off.
                         */
                        p= strchr(buf, '\n');
                        if (p)
                                *p = 0;
                        p = strchr(buf, '\r');
                        if (p)
                                *p = 0;

                        /*
                         *  Find base name of shell
                         */
                        shell_name = strrchr( buf, '/');
                        if (shell_name) {
                                shell_name++;
                        } else {
                                shell_name = &buf[2];/* skipping "#!" */
                        }

                }
                CloseHandle(exec_handle);
        }

        flags = 0;

        if (file_not_found)
                command_line = make_command_line( shell_name, exec_path, argv);
        else {
                /* If exec_fname includes whitespace, CreateProcess
                   behaves erratically and unreliably, and often fails
                   if argv[0] also includes whitespace (and thus will
                   be quoted by make_command_line below).  So in that
                   case, we don't pass exec_fname as the 1st arg to
                   CreateProcess, but instead replace argv[0] with
                   exec_fname (to keep its leading directories and
                   extension as found by find_file), and pass NULL to
                   CreateProcess as its 1st arg.  This works around
                   the bugs in CreateProcess, which are probably
                   caused by its passing the command to cmd.exe with
                   some incorrect quoting.  */
                if (!shell_name
                    && batch_file_with_spaces(exec_fname)
                    && _stricmp(exec_path, argv[0]) == 0) {
                        char *new_argv, *p;
                        char **argvi;
                        int arglen, i;
                        pass_null_exec_path = 1;
                        /* Rewrite argv[] replacing argv[0] with exec_fname.  */
                        for (argvi = argv + 1, arglen = strlen(exec_fname) + 1;
                             *argvi;
                             argvi++) {
                                arglen += strlen(*argvi) + 1;
                        }
                        new_argv = xmalloc(arglen);
                        p = strcpy(new_argv, exec_fname) + strlen(exec_fname) + 1;
                        for (argvi = argv + 1, i = 1; *argvi; argvi++, i++) {
                                strcpy(p, *argvi);
                                argv[i] = p;
                                p += strlen(*argvi) + 1;
                        }
                        argv[i] = NULL;
                        free (argv[0]);
                        argv[0] = new_argv;
                }
                command_line = make_command_line( shell_name, exec_fname, argv);
        }

        if ( command_line == NULL ) {
                pproc->last_err = 0;
                pproc->lerrno = E_NO_MEM;
                return(-1);
        }

        if (envp) {
                if (arr2envblk(envp, &envblk, &envsize_needed) == FALSE) {
                        pproc->lerrno = E_NO_MEM;
                        free( command_line );
                        if ((pproc->last_err == ERROR_INVALID_PARAMETER
			     || pproc->last_err == ERROR_MORE_DATA)
                            && envsize_needed > 32*1024) {
                                fprintf (stderr, "CreateProcess failed, probably because environment is too large (%d bytes).\n",
                                         envsize_needed);
                        }
                        pproc->last_err = 0;
                        return(-1);
                }
        }

        if (shell_name || file_not_found || pass_null_exec_path) {
                exec_path = 0;  /* Search for the program in %Path% */
        } else {
                exec_path = exec_fname;
        }

        /*
         *  Set up inherited stdin, stdout, stderr for child
         */
        GetStartupInfo(&startInfo);
        startInfo.dwFlags = STARTF_USESTDHANDLES;
        startInfo.lpReserved = 0;
        startInfo.cbReserved2 = 0;
        startInfo.lpReserved2 = 0;
        startInfo.hStdInput = (HANDLE)pproc->sv_stdin[1];
        startInfo.hStdOutput = (HANDLE)pproc->sv_stdout[1];
        startInfo.hStdError = (HANDLE)pproc->sv_stderr[1];

        if (as_user) {
                free(envblk);
                return -1;
        } else {
                DB (DB_JOBS, ("CreateProcess(%s,%s,...)\n",
                        exec_path ? exec_path : "NULL",
                        command_line ? command_line : "NULL"));
                if (CreateProcess(
                        exec_path,
                        command_line,
                        NULL,
                        0, /* default security attributes for thread */
                        TRUE, /* inherit handles (e.g. helper pipes, oserv socket) */
                        flags,
                        envblk,
                        0, /* default starting directory */
                        &startInfo,
                        &procInfo) == FALSE) {

                        pproc->last_err = GetLastError();
                        pproc->lerrno = E_FORK;
                        fprintf(stderr, "process_begin: CreateProcess(%s, %s, ...) failed.\n",
                                exec_path ? exec_path : "NULL", command_line);
                        free(envblk);
                        free( command_line );
                        return(-1);
                }
        }

        pproc->pid = (pid_t)procInfo.hProcess;
        /* Close the thread handle -- we'll just watch the process */
        CloseHandle(procInfo.hThread);

        /* Close the halves of the pipes we don't need */
        if ((HANDLE)pproc->sv_stdin[1] != INVALID_HANDLE_VALUE)
          CloseHandle((HANDLE)pproc->sv_stdin[1]);
        if ((HANDLE)pproc->sv_stdout[1] != INVALID_HANDLE_VALUE)
          CloseHandle((HANDLE)pproc->sv_stdout[1]);
        if ((HANDLE)pproc->sv_stderr[1] != INVALID_HANDLE_VALUE)
          CloseHandle((HANDLE)pproc->sv_stderr[1]);
        pproc->sv_stdin[1] = 0;
        pproc->sv_stdout[1] = 0;
        pproc->sv_stderr[1] = 0;

        free( command_line );
        free(envblk);
        pproc->lerrno=0;
        return 0;
}



#if 0   /* unused */
static DWORD
proc_stdin_thread(sub_process *pproc)
{
        DWORD in_done;
        for (;;) {
                if (WriteFile( (HANDLE) pproc->sv_stdin[0], pproc->inp, pproc->incnt,
                                         &in_done, NULL) == FALSE)
                        _endthreadex(0);
                // This if should never be true for anonymous pipes, but gives
                // us a chance to change I/O mechanisms later
                if (in_done < pproc->incnt) {
                        pproc->incnt -= in_done;
                        pproc->inp += in_done;
                } else {
                        _endthreadex(0);
                }
        }
        return 0; // for compiler warnings only.. not reached
}

static DWORD
proc_stdout_thread(sub_process *pproc)
{
        DWORD bufsize = 1024;
        char c;
        DWORD nread;
        pproc->outp = malloc(bufsize);
        if (pproc->outp == NULL)
                _endthreadex(0);
        pproc->outcnt = 0;

        for (;;) {
                if (ReadFile( (HANDLE)pproc->sv_stdout[0], &c, 1, &nread, NULL)
                                        == FALSE) {
/*                      map_windows32_error_to_string(GetLastError());*/
                        _endthreadex(0);
                }
                if (nread == 0)
                        _endthreadex(0);
                if (pproc->outcnt + nread > bufsize) {
                        bufsize += nread + 512;
                        pproc->outp = realloc(pproc->outp, bufsize);
                        if (pproc->outp == NULL) {
                                pproc->outcnt = 0;
                                _endthreadex(0);
                        }
                }
                pproc->outp[pproc->outcnt++] = c;
        }
        return 0;
}

static DWORD
proc_stderr_thread(sub_process *pproc)
{
        DWORD bufsize = 1024;
        char c;
        DWORD nread;
        pproc->errp = malloc(bufsize);
        if (pproc->errp == NULL)
                _endthreadex(0);
        pproc->errcnt = 0;

        for (;;) {
                if (ReadFile( (HANDLE)pproc->sv_stderr[0], &c, 1, &nread, NULL) == FALSE) {
                        map_windows32_error_to_string(GetLastError());
                        _endthreadex(0);
                }
                if (nread == 0)
                        _endthreadex(0);
                if (pproc->errcnt + nread > bufsize) {
                        bufsize += nread + 512;
                        pproc->errp = realloc(pproc->errp, bufsize);
                        if (pproc->errp == NULL) {
                                pproc->errcnt = 0;
                                _endthreadex(0);
                        }
                }
                pproc->errp[pproc->errcnt++] = c;
        }
        return 0;
}


/*
 * Purpose: collects output from child process and returns results
 *
 * Description:
 *
 * Returns:
 *
 * Notes/Dependencies:
 */
        long
process_pipe_io(
        HANDLE proc,
        char *stdin_data,
        int stdin_data_len)
{
        sub_process *pproc = (sub_process *)proc;
        bool_t stdin_eof = FALSE, stdout_eof = FALSE, stderr_eof = FALSE;
        HANDLE childhand = (HANDLE) pproc->pid;
        HANDLE tStdin = NULL, tStdout = NULL, tStderr = NULL;
        unsigned int dwStdin, dwStdout, dwStderr;
        HANDLE wait_list[4];
        DWORD wait_count;
        DWORD wait_return;
        HANDLE ready_hand;
        bool_t child_dead = FALSE;
        BOOL GetExitCodeResult;

        /*
         *  Create stdin thread, if needed
         */
        pproc->inp = stdin_data;
        pproc->incnt = stdin_data_len;
        if (!pproc->inp) {
                stdin_eof = TRUE;
                CloseHandle((HANDLE)pproc->sv_stdin[0]);
                pproc->sv_stdin[0] = 0;
        } else {
                tStdin = (HANDLE) _beginthreadex( 0, 1024,
                        (unsigned (__stdcall *) (void *))proc_stdin_thread,
                                                  pproc, 0, &dwStdin);
                if (tStdin == 0) {
                        pproc->last_err = GetLastError();
                        pproc->lerrno = E_SCALL;
                        goto done;
                }
        }

        /*
         *   Assume child will produce stdout and stderr
         */
        tStdout = (HANDLE) _beginthreadex( 0, 1024,
                (unsigned (__stdcall *) (void *))proc_stdout_thread, pproc, 0,
                &dwStdout);
        tStderr = (HANDLE) _beginthreadex( 0, 1024,
                (unsigned (__stdcall *) (void *))proc_stderr_thread, pproc, 0,
                &dwStderr);

        if (tStdout == 0 || tStderr == 0) {

                pproc->last_err = GetLastError();
                pproc->lerrno = E_SCALL;
                goto done;
        }


        /*
         *  Wait for all I/O to finish and for the child process to exit
         */

        while (!stdin_eof || !stdout_eof || !stderr_eof || !child_dead) {
                wait_count = 0;
                if (!stdin_eof) {
                        wait_list[wait_count++] = tStdin;
                }
                if (!stdout_eof) {
                        wait_list[wait_count++] = tStdout;
                }
                if (!stderr_eof) {
                        wait_list[wait_count++] = tStderr;
                }
                if (!child_dead) {
                        wait_list[wait_count++] = childhand;
                }

                wait_return = WaitForMultipleObjects(wait_count, wait_list,
                         FALSE, /* don't wait for all: one ready will do */
                         child_dead? 1000 :INFINITE); /* after the child dies, subthreads have
                                one second to collect all remaining output */

                if (wait_return == WAIT_FAILED) {
/*                      map_windows32_error_to_string(GetLastError());*/
                        pproc->last_err = GetLastError();
                        pproc->lerrno = E_SCALL;
                        goto done;
                }

                ready_hand = wait_list[wait_return - WAIT_OBJECT_0];

                if (ready_hand == tStdin) {
                        CloseHandle((HANDLE)pproc->sv_stdin[0]);
                        pproc->sv_stdin[0] = 0;
                        CloseHandle(tStdin);
                        tStdin = 0;
                        stdin_eof = TRUE;

                } else if (ready_hand == tStdout) {

                        CloseHandle((HANDLE)pproc->sv_stdout[0]);
                        pproc->sv_stdout[0] = 0;
                        CloseHandle(tStdout);
                        tStdout = 0;
                        stdout_eof = TRUE;

                } else if (ready_hand == tStderr) {

                        CloseHandle((HANDLE)pproc->sv_stderr[0]);
                        pproc->sv_stderr[0] = 0;
                        CloseHandle(tStderr);
                        tStderr = 0;
                        stderr_eof = TRUE;

                } else if (ready_hand == childhand) {

                        DWORD ierr;
                        GetExitCodeResult = GetExitCodeProcess(childhand, &ierr);
                        if (ierr == CONTROL_C_EXIT) {
                                pproc->signal = SIGINT;
                        } else {
                                pproc->exit_code = ierr;
                        }
                        if (GetExitCodeResult == FALSE) {
                                pproc->last_err = GetLastError();
                                pproc->lerrno = E_SCALL;
                                goto done;
                        }
                        child_dead = TRUE;

                } else {

                        /* ?? Got back a handle we didn't query ?? */
                        pproc->last_err = 0;
                        pproc->lerrno = E_FAIL;
                        goto done;
                }
        }

 done:
        if (tStdin != 0)
                CloseHandle(tStdin);
        if (tStdout != 0)
                CloseHandle(tStdout);
        if (tStderr != 0)
                CloseHandle(tStderr);

        if (pproc->lerrno)
                return(-1);
        else
                return(0);

}
#endif  /* unused */

/*
 * Purpose: collects output from child process and returns results
 *
 * Description:
 *
 * Returns:
 *
 * Notes/Dependencies:
 */
        long
process_file_io(
        HANDLE proc)
{
        sub_process *pproc;
        HANDLE childhand;
        DWORD wait_return;
        BOOL GetExitCodeResult;
        DWORD ierr;

        if (proc == NULL)
                pproc = process_wait_for_any_private(1, 0);
        else
                pproc = (sub_process *)proc;

        /* some sort of internal error */
        if (!pproc)
                return -1;

        childhand = (HANDLE) pproc->pid;

        /*
         * This function is poorly named, and could also be used just to wait
         * for child death if you're doing your own pipe I/O.  If that is
         * the case, close the pipe handles here.
         */
        if (pproc->sv_stdin[0]) {
                CloseHandle((HANDLE)pproc->sv_stdin[0]);
                pproc->sv_stdin[0] = 0;
        }
        if (pproc->sv_stdout[0]) {
                CloseHandle((HANDLE)pproc->sv_stdout[0]);
                pproc->sv_stdout[0] = 0;
        }
        if (pproc->sv_stderr[0]) {
                CloseHandle((HANDLE)pproc->sv_stderr[0]);
                pproc->sv_stderr[0] = 0;
        }

        /*
         *  Wait for the child process to exit
         */

        wait_return = WaitForSingleObject(childhand, INFINITE);

        if (wait_return != WAIT_OBJECT_0) {
/*              map_windows32_error_to_string(GetLastError());*/
                pproc->last_err = GetLastError();
                pproc->lerrno = E_SCALL;
                goto done2;
        }

        GetExitCodeResult = GetExitCodeProcess(childhand, &ierr);
        if (ierr == CONTROL_C_EXIT) {
                pproc->signal = SIGINT;
        } else {
                pproc->exit_code = ierr;
        }
        if (GetExitCodeResult == FALSE) {
                pproc->last_err = GetLastError();
                pproc->lerrno = E_SCALL;
        }

done2:
        if (pproc->lerrno)
                return(-1);
        else
                return(0);

}

/*
 * Description:  Clean up any leftover handles, etc.  It is up to the
 * caller to manage and free the input, output, and stderr buffers.
 */
        void
process_cleanup(
        HANDLE proc)
{
        sub_process *pproc = (sub_process *)proc;
        int i;

        if (pproc->using_pipes) {
                for (i= 0; i <= 1; i++) {
                        if ((HANDLE)pproc->sv_stdin[i]
                            && (HANDLE)pproc->sv_stdin[i] != INVALID_HANDLE_VALUE)
                                CloseHandle((HANDLE)pproc->sv_stdin[i]);
                        if ((HANDLE)pproc->sv_stdout[i]
                            && (HANDLE)pproc->sv_stdout[i] != INVALID_HANDLE_VALUE)
                                CloseHandle((HANDLE)pproc->sv_stdout[i]);
                        if ((HANDLE)pproc->sv_stderr[i]
                            && (HANDLE)pproc->sv_stderr[i] != INVALID_HANDLE_VALUE)
                                CloseHandle((HANDLE)pproc->sv_stderr[i]);
                }
        }
        if ((HANDLE)pproc->pid)
                CloseHandle((HANDLE)pproc->pid);

        free(pproc);
}


/*
 * Description:
 *       Create a command line buffer to pass to CreateProcess
 *
 * Returns:  the buffer or NULL for failure
 *      Shell case:  sh_name a:/full/path/to/script argv[1] argv[2] ...
 *  Otherwise:   argv[0] argv[1] argv[2] ...
 *
 * Notes/Dependencies:
 *   CreateProcess does not take an argv, so this command creates a
 *   command line for the executable.
 */

static char *
make_command_line( char *shell_name, char *full_exec_path, char **argv)
{
        int             argc = 0;
        char**          argvi;
        int*            enclose_in_quotes = NULL;
        int*            enclose_in_quotes_i;
        unsigned int    bytes_required = 0;
        char*           command_line;
        char*           command_line_i;
        int  cygwin_mode = 0; /* HAVE_CYGWIN_SHELL */
        int have_sh = 0; /* HAVE_CYGWIN_SHELL */

#ifdef HAVE_CYGWIN_SHELL
        have_sh = (shell_name != NULL || strstr(full_exec_path, "sh.exe"));
        cygwin_mode = 1;
#endif

        if (shell_name && full_exec_path) {
                bytes_required
                  = strlen(shell_name) + 1 + strlen(full_exec_path);
                /*
                 * Skip argv[0] if any, when shell_name is given.
                 * The special case of "-c" in full_exec_path means
                 * argv[0] is not the shell name, but the command string
                 * to pass to the shell.
                 */
                if (*argv && strcmp(full_exec_path, "-c")) argv++;
                /*
                 * Add one for the intervening space.
                 */
                if (*argv) bytes_required++;
        }

        argvi = argv;
        while (*(argvi++)) argc++;

        if (argc) {
                enclose_in_quotes = (int*) calloc(1, argc * sizeof(int));

                if (!enclose_in_quotes) {
                        return NULL;
                }
        }

        /* We have to make one pass through each argv[i] to see if we need
         * to enclose it in ", so we might as well figure out how much
         * memory we'll need on the same pass.
         */

        argvi = argv;
        enclose_in_quotes_i = enclose_in_quotes;
        while(*argvi) {
                char* p = *argvi;
                unsigned int backslash_count = 0;

                /*
                 * We have to enclose empty arguments in ".
                 */
                if (!(*p)) *enclose_in_quotes_i = 1;

                while(*p) {
                        switch (*p) {
                        case '\"':
                                /*
                                 * We have to insert a backslash for each "
                                 * and each \ that precedes the ".
                                 */
                                bytes_required += (backslash_count + 1);
                                backslash_count = 0;
                                break;

#if !defined(HAVE_MKS_SHELL) && !defined(HAVE_CYGWIN_SHELL)
                        case '\\':
                                backslash_count++;
                                break;
#endif
        /*
         * At one time we set *enclose_in_quotes_i for '*' or '?' to suppress
         * wildcard expansion in programs linked with MSVC's SETARGV.OBJ so
         * that argv in always equals argv out. This was removed.  Say you have
         * such a program named glob.exe.  You enter
         * glob '*'
         * at the sh command prompt.  Obviously the intent is to make glob do the
         * wildcarding instead of sh.  If we set *enclose_in_quotes_i for '*' or '?',
         * then the command line that glob would see would be
         * glob "*"
         * and the _setargv in SETARGV.OBJ would _not_ expand the *.
         */
                        case ' ':
                        case '\t':
                                *enclose_in_quotes_i = 1;
                                /* fall through */

                        default:
                                backslash_count = 0;
                                break;
                        }

                        /*
                         * Add one for each character in argv[i].
                         */
                        bytes_required++;

                        p++;
                }

                if (*enclose_in_quotes_i) {
                        /*
                         * Add one for each enclosing ",
                         * and one for each \ that precedes the
                         * closing ".
                         */
                        bytes_required += (backslash_count + 2);
                }

                /*
                 * Add one for the intervening space.
                 */
                if (*(++argvi)) bytes_required++;
                enclose_in_quotes_i++;
        }

        /*
         * Add one for the terminating NULL.
         */
        bytes_required++;

        command_line = (char*) malloc(bytes_required);

        if (!command_line) {
                free(enclose_in_quotes);
                return NULL;
        }

        command_line_i = command_line;

        if (shell_name && full_exec_path) {
                while(*shell_name) {
                        *(command_line_i++) = *(shell_name++);
                }

                *(command_line_i++) = ' ';

                while(*full_exec_path) {
                        *(command_line_i++) = *(full_exec_path++);
                }

                if (*argv) {
                        *(command_line_i++) = ' ';
                }
        }

        argvi = argv;
        enclose_in_quotes_i = enclose_in_quotes;

        while(*argvi) {
                char* p = *argvi;
                unsigned int backslash_count = 0;

                if (*enclose_in_quotes_i) {
                        *(command_line_i++) = '\"';
                }

                while(*p) {
                        if (*p == '\"') {
                                if (cygwin_mode && have_sh) { /* HAVE_CYGWIN_SHELL */
                                        /* instead of a \", cygwin likes "" */
                                        *(command_line_i++) = '\"';
                                } else {

                                /*
                                 * We have to insert a backslash for the "
                                 * and each \ that precedes the ".
                                 */
                                backslash_count++;

                                while(backslash_count) {
                                        *(command_line_i++) = '\\';
                                        backslash_count--;
                                };
                                }
#if !defined(HAVE_MKS_SHELL) && !defined(HAVE_CYGWIN_SHELL)
                        } else if (*p == '\\') {
                                backslash_count++;
                        } else {
                                backslash_count = 0;
#endif
                        }

                        /*
                         * Copy the character.
                         */
                        *(command_line_i++) = *(p++);
                }

                if (*enclose_in_quotes_i) {
#if !defined(HAVE_MKS_SHELL) && !defined(HAVE_CYGWIN_SHELL)
                        /*
                         * Add one \ for each \ that precedes the
                         * closing ".
                         */
                        while(backslash_count--) {
                                *(command_line_i++) = '\\';
                        };
#endif
                        *(command_line_i++) = '\"';
                }

                /*
                 * Append an intervening space.
                 */
                if (*(++argvi)) {
                        *(command_line_i++) = ' ';
                }

                enclose_in_quotes_i++;
        }

        /*
         * Append the terminating NULL.
         */
        *command_line_i = '\0';

        free(enclose_in_quotes);
        return command_line;
}

/*
 * Description: Given an argv and optional envp, launch the process
 *              using the default stdin, stdout, and stderr handles.
 *              Also, register process so that process_wait_for_any_private()
 *              can be used via process_file_io(NULL) or
 *              process_wait_for_any().
 *
 * Returns:
 *
 * Notes/Dependencies:
 */
HANDLE
process_easy(
        char **argv,
        char **envp,
        int outfd,
        int errfd)
{
  HANDLE hIn = INVALID_HANDLE_VALUE;
  HANDLE hOut = INVALID_HANDLE_VALUE;
  HANDLE hErr = INVALID_HANDLE_VALUE;
  HANDLE hProcess, tmpIn, tmpOut, tmpErr;
  DWORD e;

  if (proc_index >= MAXIMUM_WAIT_OBJECTS) {
        DB (DB_JOBS, ("process_easy: All process slots used up\n"));
        return INVALID_HANDLE_VALUE;
  }
  /* Standard handles returned by GetStdHandle can be NULL or
     INVALID_HANDLE_VALUE if the parent process closed them.  If that
     happens, we open the null device and pass its handle to
     CreateProcess as the corresponding handle to inherit.  */
  tmpIn = GetStdHandle(STD_INPUT_HANDLE);
  if (DuplicateHandle(GetCurrentProcess(),
                      tmpIn,
                      GetCurrentProcess(),
                      &hIn,
                      0,
                      TRUE,
                      DUPLICATE_SAME_ACCESS) == FALSE) {
    if ((e = GetLastError()) == ERROR_INVALID_HANDLE) {
      tmpIn = CreateFile("NUL", GENERIC_READ,
                         FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
                         OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
      if (tmpIn != INVALID_HANDLE_VALUE
          && DuplicateHandle(GetCurrentProcess(),
                             tmpIn,
                             GetCurrentProcess(),
                             &hIn,
                             0,
                             TRUE,
                             DUPLICATE_SAME_ACCESS) == FALSE)
        CloseHandle(tmpIn);
    }
    if (hIn == INVALID_HANDLE_VALUE) {
      fprintf(stderr, "process_easy: DuplicateHandle(In) failed (e=%ld)\n", e);
      return INVALID_HANDLE_VALUE;
    }
  }
  if (outfd >= 0)
    tmpOut = (HANDLE)_get_osfhandle (outfd);
  else
    tmpOut = GetStdHandle (STD_OUTPUT_HANDLE);
  if (DuplicateHandle(GetCurrentProcess(),
                      tmpOut,
                      GetCurrentProcess(),
                      &hOut,
                      0,
                      TRUE,
                      DUPLICATE_SAME_ACCESS) == FALSE) {
    if ((e = GetLastError()) == ERROR_INVALID_HANDLE) {
      tmpOut = CreateFile("NUL", GENERIC_WRITE,
                          FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
                          OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
      if (tmpOut != INVALID_HANDLE_VALUE
          && DuplicateHandle(GetCurrentProcess(),
                             tmpOut,
                             GetCurrentProcess(),
                             &hOut,
                             0,
                             TRUE,
                             DUPLICATE_SAME_ACCESS) == FALSE)
        CloseHandle(tmpOut);
    }
    if (hOut == INVALID_HANDLE_VALUE) {
      fprintf(stderr, "process_easy: DuplicateHandle(Out) failed (e=%ld)\n", e);
      return INVALID_HANDLE_VALUE;
    }
  }
  if (errfd >= 0)
    tmpErr = (HANDLE)_get_osfhandle (errfd);
  else
    tmpErr = GetStdHandle(STD_ERROR_HANDLE);
  if (DuplicateHandle(GetCurrentProcess(),
                      tmpErr,
                      GetCurrentProcess(),
                      &hErr,
                      0,
                      TRUE,
                      DUPLICATE_SAME_ACCESS) == FALSE) {
    if ((e = GetLastError()) == ERROR_INVALID_HANDLE) {
      tmpErr = CreateFile("NUL", GENERIC_WRITE,
                          FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
                          OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
      if (tmpErr != INVALID_HANDLE_VALUE
          && DuplicateHandle(GetCurrentProcess(),
                             tmpErr,
                             GetCurrentProcess(),
                             &hErr,
                             0,
                             TRUE,
                             DUPLICATE_SAME_ACCESS) == FALSE)
        CloseHandle(tmpErr);
    }
    if (hErr == INVALID_HANDLE_VALUE) {
      fprintf(stderr, "process_easy: DuplicateHandle(Err) failed (e=%ld)\n", e);
      return INVALID_HANDLE_VALUE;
    }
  }

  hProcess = process_init_fd(hIn, hOut, hErr);

  if (process_begin(hProcess, argv, envp, argv[0], NULL)) {
    fake_exits_pending++;
    /* process_begin() failed: make a note of that.  */
    if (!((sub_process*) hProcess)->last_err)
      ((sub_process*) hProcess)->last_err = -1;
    ((sub_process*) hProcess)->exit_code = process_last_err(hProcess);

    /* close up unused handles */
    if (hIn != INVALID_HANDLE_VALUE)
      CloseHandle(hIn);
    if (hOut != INVALID_HANDLE_VALUE)
      CloseHandle(hOut);
    if (hErr != INVALID_HANDLE_VALUE)
      CloseHandle(hErr);
  }

  process_register(hProcess);

  return hProcess;
}
