/* 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 have_sh = 0; /* HAVE_CYGWIN_SHELL */
        int cygwin_mode = 0; /* HAVE_CYGWIN_SHELL */

#ifdef HAVE_CYGWIN_SHELL
        cygwin_mode = 1;
#endif

        if (shell_name && full_exec_path) {
                have_sh = cygwin_mode && strstr(full_exec_path, "sh.exe");
                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;
}
