So I'm running into a strange problem while trying to redirect the output of a process. I created a sample program which first prints a statement and then after 5 seconds prints another statement.
I setup my process via CreateProcesss
and setup my pipe via CreatePipe
etc, all the normal things one has to do. I make sure to close the process's OUT write and IN rd pipes after creation. I use PeekNamedPipe
to determine if there is data to be read. After all this initial setup I do not get any output until the 5 seconds are up. It is only returning data to me after the process exits. I cannot seem to figure out why.
Was wondering if anyone sees something wrong in my logic?
I have the following c code:
#include <windows.h>
#include <stdio.h>
int main(){
// the handles for creating pipes
HANDLE g_hChildStd_IN_Rd = NULL;
HANDLE g_hChildStd_IN_Wr = NULL;
HANDLE g_hChildStd_OUT_Rd = NULL;
HANDLE g_hChildStd_OUT_Wr = NULL;
HANDLE g_hChildStd_Err_Rd = NULL;
HANDLE g_hChildStd_Err_Wr = NULL;
// security attributes for inheriting pipe handles
SECURITY_ATTRIBUTES saAttr;
// Set the bInheritHandle flag so pipe handles are inherited.
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
// Create a pipe for the child process's STDOUT.
if ( ! CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0) )
printf("StdoutRd CreatePipe");
// Ensure the read handle to the pipe for STDOUT is not inherited.
if ( ! SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0) )
printf("Stdout SetHandleInformation");
// Create a pipe for the child process's STDIN.
if (! CreatePipe(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, &saAttr, 0))
printf("Stdin CreatePipe");
// Ensure the write handle to the pipe for STDIN is not inherited.
if ( ! SetHandleInformation(g_hChildStd_IN_Wr, HANDLE_FLAG_INHERIT, 0) )
printf("Stdin SetHandleInformation");
// Create a pipe for the child process's STDERR.
if ( ! CreatePipe(&g_hChildStd_Err_Rd, &g_hChildStd_Err_Wr, &saAttr, 0) )
printf("StdoutRd CreatePipe");
// Ensure the read handle to the pipe for STDOUT is not inherited.
if ( ! SetHandleInformation(g_hChildStd_Err_Rd, HANDLE_FLAG_INHERIT, 0) )
printf("Stdout SetHandleInformation");
STARTUPINFO si={0};
ZeroMemory( &si, sizeof(STARTUPINFO) );
si.cb = sizeof(STARTUPINFO);
si.hStdError = g_hChildStd_OUT_Wr;
si.hStdOutput = g_hChildStd_OUT_Wr;
si.hStdInput = g_hChildStd_IN_Rd;
si.dwFlags |= STARTF_USESTDHANDLES;
PROCESS_INFORMATION pi={0};
int status = CreateProcessA("a.exe", 0, 0, 0, TRUE, 0, 0, 0, &si, &pi);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
// Dont forget to close stderr once we make it. Currently stderr gets combined
// with stdout
CloseHandle(g_hChildStd_OUT_Wr);
CloseHandle(g_hChildStd_IN_Rd);
while (1 )
{
Sleep(200);
DWORD dwRead = 0;
unsigned char out[5] = {0};
PeekNamedPipe(g_hChildStd_OUT_Rd,0,0,0,&dwRead,0);
if (dwRead > 0)
{
ReadFile(g_hChildStd_OUT_Rd,out, 5 ,&dwRead, 0);
printf("STDOUT: %s", out);
}
printf("write file\n");
WriteFile(g_hChildStd_IN_Wr,"hello\n\n",7,&dwRead,0);
}
}
being tested on the following program a.exe:
#include <stdio.h>
#include <windows.h>
int main()
{
char word[250];
printf("HELLO WORLD: ");
Sleep(500);
printf("\nyou printed %s!\n\n",word);
Sleep(5000);
printf("More prints..\n");
return 0;
}