Computer Chess Club Archives


Search

Terms

Messages

Subject: Re: 4 specific questions about Chest

Author: Tim Foden

Date: 11:58:14 04/05/02

Go up one level in this thread


On April 05, 2002 at 13:58:17, Roy Eassa wrote:

>I understand that it reads stdin.  I was wondering if there was a way for
>another app to "send" something that, to Chest, looked like it was coming from
>stdin.  This question is aimed at those who are experienced with programming
>tricks in Windows and/or DOS.

Yes it is possible.  Under Win32 you follow the following procedure.

1.  Save your current processes stdin, stdout and stderr.
2.  Replace your stdin, stdout and stderr with pipes.
3.  Create the child process, inheriting handles.
4.  Restore your saved stdin, stdout and stderr.
5.  Communicate with the child process using your end of the pipes.

Cheers, Tim.

~~~~~~~~~~~~~~~~~

NB: I have some code that does this (irrelevent code snipped out)...

class CEngine
{
public:
	bool		Open();
	bool		SetupPipe( int which )

private:
	enum { cHandleStdin, cHandleStdout, cHandleStderr };

private:
	CString				m_workingDir;
	CString				m_command;
	CStringArray		m_args;

	bool				m_isOpen;
	PROCESS_INFORMATION	m_processInfo;

	HANDLE				m_hSaved[3];
	HANDLE				m_hChild[3];
};

bool	CEngine::SetupPipe( int which )
{
	SECURITY_ATTRIBUTES saAttr;

	// Set the bInheritHandle flag so pipe handles are inherited.
	saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
	saAttr.bInheritHandle = TRUE;
	saAttr.lpSecurityDescriptor = NULL;

	// The steps for redirecting child process's STDOUT:
	//     1. Save current STDOUT, to be restored later.
	//     2. Create anonymous pipe to be STDOUT for child process.
	//     3. Set STDOUT of the parent process to be write handle to
	//        the pipe, so it is inherited by the child process.
	//     4. Create a noninheritable duplicate of the read handle and
	//        close the inheritable read handle.

	// get Window handle enum
	DWORD	winStd[3] = { STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, STD_ERROR_HANDLE };
	DWORD	winWhich = winStd[which];

	// Save the handle to the current STDOUT.
	m_hSaved[which] = GetStdHandle(winWhich);

	// Create a pipe for the child process's STDOUT.
	HANDLE	hRead, hWrite;
	if( !CreatePipe(&hRead, &hWrite, &saAttr, 0) )
		return false;

	// if we are creating a handle for STDIN, we swap the read and write
	//	handles around now
	if( which == cHandleStdin )
	{
		HANDLE	hTemp = hRead;
		hRead = hWrite;
		hWrite = hTemp;
	}

	// setup the standard handle to be inherited by the child process
	if( !SetStdHandle(winWhich, hWrite) )
		return false;

	// Create noninheritable handle and close the inheritable handle.
	HANDLE	hReadDup;
	if( !DuplicateHandle(GetCurrentProcess(), hRead, GetCurrentProcess(),
						 &hReadDup, 0, false, DUPLICATE_SAME_ACCESS) )
		return false;

	CloseHandle( hRead );

	// save the handle we will used to communicate with the child process
	m_hChild[which] = hReadDup;

	return true;
}

bool	CEngine::Open()
{
	Close();

	CString	application;
	application = m_command;
	for( int i = 0; i < m_args.GetSize(); i++ )
		application += " \"" + m_args[i] + "\"";

	if( !SetupPipe(cHandleStdin) )
		return false;

	if( !SetupPipe(cHandleStdout) )
		return false;

	if( !SetupPipe(cHandleStderr) )
		return false;

	STARTUPINFO	si;
	memset( &si, 0, sizeof(si) );
	si.cb = sizeof(si);

	memset( &m_processInfo, 0, sizeof(m_processInfo) );

	if( !CreateProcess(application, NULL, NULL, NULL, true,
						NORMAL_PRIORITY_CLASS, NULL,
						m_workingDir, &si, &m_processInfo) )
	{
		return false;
	}

	SetStdHandle( STD_INPUT_HANDLE,  m_hSaved[cHandleStdin] );
	SetStdHandle( STD_OUTPUT_HANDLE, m_hSaved[cHandleStdout] );
	SetStdHandle( STD_ERROR_HANDLE,  m_hSaved[cHandleStderr] );

	m_isOpen = true;
	m_readBufferUsed = 0;
	return true;
}

void	CEngine::Close()
{
	if( !m_isOpen )
		return;

	Send("quit\n");
	WaitForSingleObject( m_processInfo.hProcess, 10000 );

	CloseHandle( m_processInfo.hThread );
	CloseHandle( m_processInfo.hProcess );

	m_isOpen = false;
}





This page took 0 seconds to execute

Last modified: Thu, 15 Apr 21 08:11:13 -0700

Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.