/******************************************************************************
 *
 * Copyright (c) 1999	TOSHIYUKI ARAI. ALL RIGHTS RESERVED. 
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions, and the following disclaimer.
 *  
 * 2. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *
 *	Process.cpp
 *
 *****************************************************************************/

// SOL++2000 Sample program

// To see the result of this program, previously run Console program
// SOL++2000.
// 2000.02.18


#include <sol\Application.h>
#include <sol\Stdio.h>
#include <sol\Process.h>
#include <sol\Pipe.h>
#include <sol\Thread.h>

// Reader thread in parent process to read an output from a child process.

class PipeReader :public Thread {
	HANDLE hReader;
	Pipe*	pipe;
public:
	PipeReader(Pipe* p)
		:pipe(p)
	{ }

	void run();
};


void PipeReader::run() 
{
	char buffer[256];

	while (True) {
		unsigned long len = 0;
		len = pipe -> read(buffer, sizeof(buffer)-1);
		if (len>0) {
			buffer[len] = Zero;
			Printf("%s", buffer);
		} else {
			break;
		}
	}
}


// Sample ChildProcess class to launch a child process.
class ChildProcess :public Object {
	Process* child;
	Pipe*	pipe;
	Pipe*   dupPipe;
	PipeReader* reader;

public:
	// Constructor
	ChildProcess(const char* command) {
		// 1 Create an inheritable pipe
		pipe = new Pipe();

		// 2 Duplicate a noninheritable pipe of the above pipe.
		dupPipe =new Pipe(pipe);

		// 3 Create an instance of Process, using a pipe to communicate
		// this parent and child process.
		child = new Process(command, pipe);

		// 4 Close the pipe.
		pipe ->close();

		// 5 Create an instance of PipeReader thread to read an output of
		// the child process from the duplicated pipe of this process.
		reader = new PipeReader(dupPipe);

		// 6 Start the pipeReader thread.
		reader -> start();

		// 7 Wait a completion of the child process.
		child -> wait();
	}

	~ChildProcess() {
		delete child;
		delete pipe;
		delete dupPipe;
		delete reader;
	}
};



void	Main(int argc, char** argv)
{
	Printf("Main() >>\r\n");
	const char* command = "cgi.exe";

	ChildProcess* child = new ChildProcess(command);
	delete child;

	Printf("<< Main() \r\n\r\n");
}
