#include <stdlib.h>
#include <stdio.h>
#include <process.h>  /* for msvc _beginthreadex, _endthreadex */
#include <windows.h>

#include "sub_proc.h"
#include "proc.h"
#include "w32err.h"

static char *make_command_line( char *shell_name, char *exec_path, char **argv);

typedef struct sub_process_t {
	int sv_stdin[2];
	int sv_stdout[2];
	int sv_stderr[2];
	int using_pipes;
	char *inp;
	DWORD incnt;
	char * volatile outp;
	volatile DWORD outcnt;
	char * volatile errp;
	volatile DWORD errcnt;
	int 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[256];
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[256];
	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)
{
	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(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_errno(HANDLE proc)
{
	return (((sub_process *)proc)->lerrno);
}

long
process_signal(HANDLE proc)
{
	return (((sub_process *)proc)->signal);
}

	long
process_last_err(HANDLE proc)
{
	return (((sub_process *)proc)->last_err);
}

	long
process_exit_code(HANDLE proc)
{
	return (((sub_process *)proc)->exit_code);
}

	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]  = (int) stdin_pipes[0];
	pproc->sv_stdin[1]  = (int) stdin_pipes[1];
	pproc->sv_stdout[0] = (int) stdout_pipes[0];
	pproc->sv_stdout[1] = (int) stdout_pipes[1];
	pproc->sv_stderr[0] = (int) stderr_pipes[0];
	pproc->sv_stderr[1] = (int) 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]  = (int) stdinh;
	pproc->sv_stdout[1] = (int) stdouth;
	pproc->sv_stderr[1] = (int) 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;

	if ((exec_handle = (HANDLE)OpenFile(exec_path, file_info,
			OF_READ | OF_SHARE_COMPAT)) != (HANDLE)HFILE_ERROR) {
		return(exec_handle);
	}

	fname = malloc(strlen(exec_path) + 5);
	strcpy(fname, exec_path);
	ext = fname + strlen(fname);
	strcpy(ext, ".exe");
	if ((exec_handle = (HANDLE)OpenFile(fname, file_info,
			OF_READ | OF_SHARE_COMPAT)) != (HANDLE)HFILE_ERROR) {
		free(fname);
		return(exec_handle);
	}

	strcpy(ext, ".bat");
	if ((exec_handle = (HANDLE)OpenFile(fname, file_info,
			OF_READ | OF_SHARE_COMPAT)) != (HANDLE)HFILE_ERROR) {
		free(fname);
		return(exec_handle);
	}

	strcpy(ext, ".com");
	if ((exec_handle = (HANDLE)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: 
 *
 * 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];

	/*
	 * See if we need to setuid to a different user.
	 */
	if (as_user) {
		return -1;
	}

	if (as_user) {
		return -1;
	} else {
		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, command_line);
			free( command_line );
			return(-1);
		}
	}
	
	pproc->pid = (int)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 (pproc->sv_stdin) {
		CloseHandle((HANDLE)pproc->sv_stdin[1]);
		(HANDLE)pproc->sv_stdin[1] = 0;
	}
	if (pproc->sv_stdout) {
		CloseHandle((HANDLE)pproc->sv_stdout[1]);
		(HANDLE)pproc->sv_stdout[1] = 0;
	}
	if (pproc->sv_stderr) {
		CloseHandle((HANDLE)pproc->sv_stderr[1]);
		(HANDLE)pproc->sv_stderr[1] = 0;
	}

	free( command_line );
	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, tStdout, tStderr;
	DWORD dwStdin, dwStdout, dwStderr;
	HANDLE wait_list[4];
	DWORD wait_count;
	DWORD wait_return;
	HANDLE ready_hand;
	bool_t child_dead = FALSE;


	/*
	 *  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]);
		(HANDLE)pproc->sv_stdin[0] = 0;
	} else {
		tStdin = (HANDLE) _beginthreadex( 0, 1024,
			(unsigned (__stdcall *) (void *))proc_stdin_thread, pproc, 0,
			(unsigned int *) &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,
		(unsigned int *) &dwStdout);
	tStderr = (HANDLE) _beginthreadex( 0, 1024,
		(unsigned (__stdcall *) (void *))proc_stderr_thread, pproc, 0,
		(unsigned int *) &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]);
			(HANDLE)pproc->sv_stdin[0] = 0;
			CloseHandle(tStdin);
			tStdin = 0;
			stdin_eof = TRUE;
		
		} else if (ready_hand == tStdout) {
		
		  	CloseHandle((HANDLE)pproc->sv_stdout[0]);
			(HANDLE)pproc->sv_stdout[0] = 0;
			CloseHandle(tStdout);
			tStdout = 0;
		  	stdout_eof = TRUE;
		
		} else if (ready_hand == tStderr) {
			
			CloseHandle((HANDLE)pproc->sv_stderr[0]);
			(HANDLE)pproc->sv_stderr[0] = 0;
			CloseHandle(tStderr);
			tStderr = 0;
			stderr_eof = TRUE;
		
		} else if (ready_hand == childhand) {
			
			if (GetExitCodeProcess(childhand, &pproc->exit_code) == 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;

	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;
	}

	if (GetExitCodeProcess(childhand, &pproc->exit_code) == 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);
}


/*
 * Try to protect against WINDOWS32 argument munging. This function takes
 * an argv vector and outputs a 'protected' string as a return
 * value. The return code can be safely passed to CreateProcess().
 *
 * The caller should free the return value.
 */

#define TRACE(x)
static char *fix_command_line(char *args[])
{
	int i;
	char *narg;
	char *nargp;
	char *p;
	char *q;
	int alloc_len = 0;

	for (i = 0; args[i]; i++)
		alloc_len += ((strlen(args[i]) * 2) + 1);
	/* account for possible enclosing quotes and null termination */
	alloc_len += 3;

	nargp = narg = malloc(alloc_len);

	for (i = 0; args[i]; i++) {
		p = args[i];
		TRACE(("original arg: %s\n", p));

		if (*p == '\0') {
			*nargp++ = '"';
			*nargp++ = '"';
			*nargp = '\0';
			TRACE(("empty string arg: %s\n", nargp-2));
		} else if (strpbrk(p, "\" \t")) {
			/* point to end of copy buffer */
			q = narg;
			q += (alloc_len-1);
			*q-- = '\0'; /* ensure null terminated string */
			*q-- = '"';  /* terminating quote of argument */

			/* point to end of the input string */
			p = args[i];
			p += strlen(args[i]);
			p--;

			/* 
			 * Because arg is quoted, escape any backslashes 
			 * that might occur at the end of the string which
			 * proceed the closing quote.
			 * Example:
			 * 	foo c:\
			 * Becomes:
			 *	"foo c:\\"
			 */
			while (*p == '\\')
				*q-- = *p--, *q-- = '\\';

			/* copy the string in reverse */
			while (p >= args[i]) {
				/* copy the character */
				*q-- = *p--;

				/* 
				 * Escape any double quote found. Also escape
				 * each backslash preceding the double quote.
				 */
				if (*(p+1) == '"') {
					*q-- = '\\';
					if (p >= args[i] && *p == '\\')
						while (p >= args[i] && *p == '\\')
							*q-- = *p--, *q-- = '\\';
				}
			}

			/* finish quoting arg, q now points to complete arg */
			*q = '"';

			/* rejustify */
			memmove(nargp, q, strlen(q) + 1);
			TRACE(("arg with white space or doublequotes: %s\n", nargp));
			nargp += strlen(nargp);
		} else {
			/* just copy the argument, no protection needed */
			strcpy(nargp, args[i]);
			TRACE(("plain arg: %s\n", nargp));
			nargp += strlen(nargp);
		}

		/* separate arguments with spaces (if more args to gather) */
		if (args[i+1])
			*nargp++ = ' ';
		*nargp   = '\0';
	} /* end for */

	/* NULL terminate the arg list */
	*nargp = '\0';

	return (narg);
}
#undef TRACE

/*
 * 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 *exec_path, char **argv)
{
	char** nargv;
	char*  buf;
	int    i;
 
	if (shell_name) {
		for (i = 0; argv[i]; i++);
		i += 2;
		nargv = (char **) malloc(i * sizeof (char *));
		nargv[0] = shell_name;
		for (i = 1; argv[i-1]; i++)
			nargv[i] = argv[i-1];
		nargv[i] = NULL;
	} else
		nargv = argv;

	/* create string suitable for CreateProcess() */
	buf = fix_command_line(nargv);

	if (shell_name)
		free(nargv);
	
	return buf;
}

/*
 * 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 (DuplicateHandle(GetCurrentProcess(),
                      GetStdHandle(STD_INPUT_HANDLE),
                      GetCurrentProcess(),
                      &hIn,
                      0,
                      TRUE,
                      DUPLICATE_SAME_ACCESS) == FALSE) {
    fprintf(stderr,
            "process_easy: DuplicateHandle(In) failed (e=%d)\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=%d)\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=%d)\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++;
    ((sub_process*) hProcess)->exit_code = process_last_err(hProcess);

    /* close up unused handles */
    CloseHandle(hIn);
    CloseHandle(hOut);
    CloseHandle(hErr);
  }

  process_register(hProcess);

  return hProcess;
}
