/* Process handling for Windows.
Copyright (C) 1996-2016 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;


/*
 * Fill a HANDLE list with handles to wait for.
 */
DWORD
process_set_handles(HANDLE *handles)
{
    DWORD count = 0;
    int i;

    /* 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[count++] = (HANDLE) proc_array[i]->pid;
    }

    return count;
}

/*
 * 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
         */
        memset(&startInfo, '\0', sizeof(startInfo));
        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;
}
