パイプテスト
更新:2006.12.10 (dmd 0.177)
dmd test.d win32/winbase.d -unittest
import std.stdio;
import std.stream;
import std.string;import win32.windows;
import win32.psapi;
import win32.winbase;void main(char[][]argv){
}unittest{
PipeTest a = new PipeTest();
a.createPipe("0.in");
a.createProcess("a.exe");
a.resume(0);
a.writeToPipe();
a.readFromPipe();
}class PipeTest
{
private:
const uint BUFSIZE = 4096;
HANDLE hChildStdinRd;
HANDLE hChildStdinWr;
HANDLE hChildStdoutRd;
HANDLE hChildStdoutWr;
HANDLE hInputFile;
HANDLE hStdout;
PROCESS_INFORMATION piProcInfo;
STARTUPINFO siStartInfo;
PROCESS_MEMORY_COUNTERS memInfo;
SECURITY_ATTRIBUTES saAttr;bool useInput = true;
char[] outputData;
long outputLimit;
long memoryLimit;
long timeLimit;
long maxMemory;
long startTime;
long execTime;
long outputSize;public:
void createPipe(char[] dataFile)
{
// Set the bInheritHandle flag so pipe handles are inherited.
saAttr.nLength = SECURITY_ATTRIBUTES.sizeof;
saAttr.bInheritHandle = true;
saAttr.lpSecurityDescriptor = null;// Get the handle to the current STDOUT.
hStdout = GetStdHandle(STD_OUTPUT_HANDLE);// Create a pipe for the child process's STDOUT.
assert( CreatePipe(&hChildStdoutRd,
&hChildStdoutWr,
&saAttr,
0)
);// Ensure the read handle to the pipe for STDOUT is not inherited.
SetHandleInformation( hChildStdoutRd, HANDLE_FLAG_INHERIT, 0);// Create a pipe for the child process's STDIN.
assert( CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0) );// Ensure the write handle to the pipe for STDIN is not inherited.
SetHandleInformation( hChildStdinWr, HANDLE_FLAG_INHERIT, 0);
hInputFile = CreateFile(cast(char*)dataFile, GENERIC_READ, 0, null,
OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, null);assert( hInputFile != INVALID_HANDLE_VALUE);
}
void createProcess(char[]szCmdline)
{
siStartInfo.hStdError = hChildStdoutWr;
siStartInfo.hStdOutput = hChildStdoutWr;
siStartInfo.hStdInput = hChildStdinRd;
siStartInfo.dwFlags |= STARTF_USESTDHANDLES;// Create the child process.
assert( CreateProcess(
null,
cast(char*)szCmdline, // command line
null, // process security attributes
null, // primary thread security attributes
true, // handles are inherited
CREATE_SUSPENDED | NORMAL_PRIORITY_CLASS, // creation flags
null, // use parent's environment
null, // use parent's current directory
&siStartInfo, // STARTUPINFO pointer
&piProcInfo) ); // receives PROCESS_INFORMATION
}void resume(long time)
{
// startTime = time;
ResumeThread(piProcInfo.hThread);
}void writeToPipe()
{
if( !useInput ) return;DWORD dwRead, dwWritten;
char[BUFSIZE] chBuf;
// Read from a file and write its contents to a pipe.
for (;;)
{
if (! ReadFile(hInputFile, chBuf.ptr, BUFSIZE, &dwRead, null) ||
dwRead == 0) break;// checkLimit();
if (! WriteFile(hChildStdinWr, chBuf.ptr, dwRead,
&dwWritten, null)) break;
}
// Close the pipe handle so the child process stops reading.
assert( CloseHandle(hChildStdinWr) );
}void readFromPipe()
{
DWORD dwRead, dwWritten;
char[BUFSIZE] chBuf;// Close the write end of the pipe before reading from the
// read end of the pipe.
assert( CloseHandle(hChildStdoutWr) );// Read output from the child process, and write to parent's STDOUT.
outputSize = 0;
outputData = "";
for (;;)
{
if( !ReadFile( hChildStdoutRd, chBuf.ptr, BUFSIZE, &dwRead, null) || dwRead == 0) break;// Judge逕ィ縺ォstdout莉・螟悶↓繧ゆソ晏ュ倥@縺ヲ縺翫¥
outputData ~= chBuf[0..dwRead-1];
// Output Size, Memory Size, Time 縺ョ貂ャ螳夂畑
outputSize += dwRead;//strlen(chBuf);
// checkLimit();// if( execMode == TEST )
{
if (! WriteFile(hStdout, chBuf.ptr, dwRead, &dwWritten, null)) break;
}
}
// writefln(outputData);
}}