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

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

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

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

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

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

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

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

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

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

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

    if (jobserver_semaphore == NULL)
        return 0;

    return 1;        
}

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

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

    if (jobserver_semaphore == NULL)
        return 0;

    return 1;        
}

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

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

    return (dwEvent == WAIT_OBJECT_0);
}

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

    return (bResult);
}

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

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

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

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

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

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

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

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

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

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

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

	if (!proc_index)
		return;

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

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

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

	if (!proc_index)
		return NULL;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	pproc->using_pipes = 1;

	pproc->lerrno = 0;

	return((HANDLE)pproc);
}


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

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

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

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

	return((HANDLE)pproc);
}


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

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

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

	free(fname);
	return INVALID_HANDLE_VALUE;
}

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

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

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


/*
 * Description:   Create the child process to be helped
 *
 * Returns: success <=> 0
 *
 * Notes/Dependencies:
 */
long
process_begin(
	HANDLE proc,
	char **argv,
	char **envp,
	char *exec_path,
	char *as_user)
{
	sub_process *pproc = (sub_process *)proc;
	char *shell_name = 0;
	int file_not_found=0;
	HANDLE exec_handle;
	char exec_fname[MAX_PATH];
	const char *path_var = NULL;
	char **ep;
	char buf[256];
	DWORD bytes_returned;
	DWORD flags;
	char *command_line;
	STARTUPINFO startInfo;
	PROCESS_INFORMATION procInfo;
	char *envblk=NULL;
	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 (exec_handle == INVALID_HANDLE_VALUE) {
		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) {
			pass_null_exec_path = 1;
			free (argv[0]);
			argv[0] = xstrdup(exec_fname);
		}
		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) ==FALSE) {
			pproc->last_err = 0;
			pproc->lerrno = E_NO_MEM;
			free( command_line );
			return(-1);
		}
	}

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

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

	if (as_user) {
		if (envblk) 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);
			if (envblk) 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 );
	if (envblk) 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, ouput, 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.
		 */
		if (*argv) 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) {
		if (enclose_in_quotes) 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';

	if (enclose_in_quotes) free(enclose_in_quotes);
	return command_line;
}

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

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

  hProcess = process_init_fd(hIn, hOut, hErr);

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

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

  process_register(hProcess);

  return hProcess;
}
