/* 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 <assert.h>
#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"
#include "os.h"

#define GMAKE_MAXIMUM_WAIT_OBJECTS (MAXIMUM_WAIT_OBJECTS * MAXIMUM_WAIT_OBJECTS)

/* We need to move these special-case return codes out-of-band */
#define GMAKE_WAIT_TIMEOUT      0xFFFF0102L
#define GMAKE_WAIT_ABANDONED_0  0x00080000L

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[GMAKE_MAXIMUM_WAIT_OBJECTS];
static int proc_index = 0;
static int fake_exits_pending = 0;

/*
 * Address the scalability limit intrisic to WaitForMultipleOjects by
 * calling WaitForMultipleObjects on 64 element chunks of the input
 * array with 0 timeout.  Exit with an appropriately conditioned result
 * or repeat again every 10 ms if no handle has signaled and the
 * requested timeout was not zero.
 */
DWORD process_wait_for_multiple_objects(
  DWORD nCount,
  const HANDLE *lpHandles,
  BOOL bWaitAll,
  DWORD dwMilliseconds
)
{
  assert(nCount <= GMAKE_MAXIMUM_WAIT_OBJECTS);

  if (nCount <= MAXIMUM_WAIT_OBJECTS) {
    DWORD retVal =  WaitForMultipleObjects(nCount, lpHandles, bWaitAll, dwMilliseconds);
    return (retVal == WAIT_TIMEOUT) ? GMAKE_WAIT_TIMEOUT : retVal;
  } else {
    for (;;) {
      DWORD objectCount = nCount;
      int blockCount  = 0;
      DWORD retVal;

      assert(bWaitAll == FALSE); /* This logic only works for this use case */
      assert(dwMilliseconds == 0 || dwMilliseconds == INFINITE); /* No support for timeouts */

      for (; objectCount > 0; blockCount++) {
	DWORD n = objectCount <= MAXIMUM_WAIT_OBJECTS ? objectCount : MAXIMUM_WAIT_OBJECTS;
	objectCount -= n;
	retVal = WaitForMultipleObjects(n, &lpHandles[blockCount * MAXIMUM_WAIT_OBJECTS],
					    FALSE, 0);
	switch (retVal) {
	  case WAIT_TIMEOUT:
	    retVal = GMAKE_WAIT_TIMEOUT;
	    continue;
	    break;
	  case WAIT_FAILED:
	    fprintf(stderr,"WaitForMultipleOjbects failed waiting with error %d\n", GetLastError());
	    break;
	  default:
	    if (retVal >= WAIT_ABANDONED_0) {
	      assert(retVal < WAIT_ABANDONED_0 + MAXIMUM_WAIT_OBJECTS);
	      retVal += blockCount * MAXIMUM_WAIT_OBJECTS - WAIT_ABANDONED_0 + GMAKE_WAIT_ABANDONED_0;
	    } else {
	      assert(retVal < WAIT_OBJECT_0 + MAXIMUM_WAIT_OBJECTS);
	      retVal += blockCount * MAXIMUM_WAIT_OBJECTS;
	    }
	    break;
	}

	return retVal;

      }

      if (dwMilliseconds == 0) return retVal;

      Sleep(10);  /* Sleep for 10 ms */
    }
  }
}

/*
 * 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[GMAKE_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 = process_wait_for_multiple_objects(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 == GMAKE_WAIT_TIMEOUT) ? WAIT_TIMEOUT : retval;

        /* return pointer to process */
        if ((retval == GMAKE_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));
}

/*
 * Returns true when we have no more available slots in our process table.
 */
BOOL
process_table_full()
{
  extern int shell_function_pid;

  /* Reserve slots for jobserver_semaphore if we have one and the shell function if not active */
  return(proc_index >= GMAKE_MAXIMUM_WAIT_OBJECTS - jobserver_enabled() - (shell_function_pid == 0));
}

/*
 * Returns the maximum number of job slots we can support when using the jobserver.
 */
int
process_table_usable_size()
{
  /* Reserve slots for jobserver_semaphore and shell function */
  return(GMAKE_MAXIMUM_WAIT_OBJECTS - 2);
}

/*
 * Returns the actual size of the process table.
 */
int
process_table_actual_size()
{
  return(GMAKE_MAXIMUM_WAIT_OBJECTS);
}

/*
 * 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)
{
  assert(proc_index < GMAKE_MAXIMUM_WAIT_OBJECTS);
  proc_array[proc_index++] = (sub_process *) proc;
}

/*
 * 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 (process_table_full()) {
        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;
}
