/* Process handling for Windows.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
2006 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 2, 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
GNU Make; see the file COPYING.  If not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.  */

#include <stdlib.h>
#include <stdio.h>
#include <process.h>  /* for msvc _beginthreadex, _endthreadex */
#include <signal.h>
#include <windows.h>

#include "sub_proc.h"
#include "proc.h"
#include "w32err.h"
#include "config.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;
	intptr_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;

/*
 * 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(void)
{
	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, INFINITE);
		which = retval - WAIT_OBJECT_0;
	} else {
		fake_exits_pending--;
		retval = !WAIT_FAILED;
		which = i;
	}

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

/*
 * 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(void)
{
	sub_process* pproc = process_wait_for_any_private();

	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);
}

/*
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));
	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(char *exec_path, LPOFSTRUCT file_info)
{
	HANDLE exec_handle;
	char *fname;
	char *ext;

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

	strcpy(ext, ".exe");
	if ((exec_handle = (HANDLE)(intptr_t)OpenFile(fname, file_info,
			OF_READ | OF_SHARE_COMPAT)) != (HANDLE)HFILE_ERROR) {
		free(fname);
		return(exec_handle);
	}

	strcpy(ext, ".cmd");
	if ((exec_handle = (HANDLE)(intptr_t)OpenFile(fname, file_info,
			OF_READ | OF_SHARE_COMPAT)) != (HANDLE)HFILE_ERROR) {
		free(fname);
		return(exec_handle);
	}

	strcpy(ext, ".bat");
	if ((exec_handle = (HANDLE)(intptr_t)OpenFile(fname, file_info,
			OF_READ | OF_SHARE_COMPAT)) != (HANDLE)HFILE_ERROR) {
		free(fname);
		return(exec_handle);
	}

	/* should .com come before this case? */
	if ((exec_handle = (HANDLE)(intptr_t)OpenFile(exec_path, file_info,
			OF_READ | OF_SHARE_COMPAT)) != (HANDLE)HFILE_ERROR) {
		free(fname);
		return(exec_handle);
	}

	strcpy(ext, ".com");
	if ((exec_handle = (HANDLE)(intptr_t)OpenFile(fname, file_info,
			OF_READ | OF_SHARE_COMPAT)) != (HANDLE)HFILE_ERROR) {
		free(fname);
		return(exec_handle);
	}

	free(fname);
	return(exec_handle);
}


/*
 * 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 buf[256];
	DWORD bytes_returned;
	DWORD flags;
	char *command_line;
	STARTUPINFO startInfo;
	PROCESS_INFORMATION procInfo;
	char *envblk=NULL;
	OFSTRUCT file_info;


	/*
	 *  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)
	 *  We use OpenFile here because it is capable of searching the Path.
	 */

	exec_handle = find_file(exec_path, &file_info);

	/*
	 * If we couldn't open the file, just assume that Windows32 will be able
	 * to find and execute it.
	 */
	if (exec_handle == (HANDLE)HFILE_ERROR) {
		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
		command_line = make_command_line( shell_name, file_info.szPathName,
				 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)) {
		exec_path = 0;	/* Search for the program in %Path% */
	} else {
		exec_path = file_info.szPathName;
	}

	/*
	 *  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 = (intptr_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 */
        CloseHandle((HANDLE)pproc->sv_stdin[1]);
        CloseHandle((HANDLE)pproc->sv_stdout[1]);
        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;
}



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);

}

/*
 * 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();
	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])
				CloseHandle((HANDLE)pproc->sv_stdin[i]);
			if ((HANDLE)pproc->sv_stdout[i])
				CloseHandle((HANDLE)pproc->sv_stdout[i]);
			if ((HANDLE)pproc->sv_stderr[i])
				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)
{
  HANDLE hIn;
  HANDLE hOut;
  HANDLE hErr;
  HANDLE hProcess;

  if (proc_index >= MAXIMUM_WAIT_OBJECTS) {
	DB (DB_JOBS, ("process_easy: All process slots used up\n"));
	return INVALID_HANDLE_VALUE;
  }
  if (DuplicateHandle(GetCurrentProcess(),
                      GetStdHandle(STD_INPUT_HANDLE),
                      GetCurrentProcess(),
                      &hIn,
                      0,
                      TRUE,
                      DUPLICATE_SAME_ACCESS) == FALSE) {
    fprintf(stderr,
            "process_easy: DuplicateHandle(In) failed (e=%ld)\n",
            GetLastError());
    return INVALID_HANDLE_VALUE;
  }
  if (DuplicateHandle(GetCurrentProcess(),
                      GetStdHandle(STD_OUTPUT_HANDLE),
                      GetCurrentProcess(),
                      &hOut,
                      0,
                      TRUE,
                      DUPLICATE_SAME_ACCESS) == FALSE) {
    fprintf(stderr,
           "process_easy: DuplicateHandle(Out) failed (e=%ld)\n",
           GetLastError());
    return INVALID_HANDLE_VALUE;
  }
  if (DuplicateHandle(GetCurrentProcess(),
                      GetStdHandle(STD_ERROR_HANDLE),
                      GetCurrentProcess(),
                      &hErr,
                      0,
                      TRUE,
                      DUPLICATE_SAME_ACCESS) == FALSE) {
    fprintf(stderr,
            "process_easy: DuplicateHandle(Err) failed (e=%ld)\n",
            GetLastError());
    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 */
    CloseHandle(hIn);
    CloseHandle(hOut);
    CloseHandle(hErr);
  }

  process_register(hProcess);

  return hProcess;
}
