カメヲラボ

主にプログラミングとお勉強全般について書いてます

パイプテスト

更新: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);
}

}