Asynchronous ReadFile() ?

I'm trying to read from the stdout stream of another process. Luckily, MS had an example already written:

https://msdn.microsoft.com/en-us/library/windows/desktop/ms682499(v=vs.85).aspx

The problem I had with it was that ReadFromPipe blocked if there was no data to read (see function below) - so I tried to make it read asynchronously with a timeout. Unfortunately it still blocks.. maybe I'm missing a FILE_FLAG_OVERLAPPED somewhere?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
//globals
HANDLE g_hChildStd_IN_Rd = NULL;
HANDLE g_hChildStd_IN_Wr = NULL;
HANDLE g_hChildStd_OUT_Rd = NULL;
HANDLE g_hChildStd_OUT_Wr = NULL;

int _tmain(){
   //...

   if(!CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0)) {ErrorExit(TEXT("StdoutRd CreatePipe"));} 
   if(!SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0)){ErrorExit(TEXT("Stdout SetHandleInformation"));} 
   if(!CreatePipe(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, &saAttr, 0)){ErrorExit(TEXT("Stdin CreatePipe"));} 
   if(!SetHandleInformation(g_hChildStd_IN_Wr, HANDLE_FLAG_INHERIT, 0)){ErrorExit(TEXT("Stdin SetHandleInformation"));} 

   // set some flags, CreateProcess()...

   std::cout<<ReadFromPipe()<<"\n";
   std::cout<<ReadFromPipe()<<"\n";

   //...
};


//old, blocking version
std::string ReadFromPipe0(void){
   DWORD dwRead; 
   CHAR chBuf[BUFSIZE]; 
   BOOL bSuccess = FALSE;

   bSuccess = ReadFile( g_hChildStd_OUT_Rd, chBuf, BUFSIZE, &dwRead, NULL);
	  
   if( ! bSuccess || dwRead == 0 ) return ""; 
   return std::string(chBuf, chBuf+dwRead);
}

//new version
std::string ReadFromPipe(void){
   SetLastError(0);

   CHAR chBuf[BUFSIZE]; 
   BOOL bSuccess = FALSE;
   HANDLE evt=CreateEvent(NULL, FALSE, FALSE, L"chstdoutread");
   OVERLAPPED overlapped; //dont think i need to do anything with this as far as freeing mem?
   ZeroMemory(&overlapped, sizeof(overlapped)); //all offsets are 0
   overlapped.hEvent=evt;
  
   std::cout<<"calling readfile...\n";
   ReadFile(g_hChildStd_OUT_Rd, chBuf, BUFSIZE, NULL, &overlapped); //async - return code doesnt matter
   std::cout<<"returned\n";

   if(WaitForSingleObject(evt, 200)==WAIT_OBJECT_0){
	   DWORD bytecnt=0;
	   GetOverlappedResult(g_hChildStd_OUT_Rd, &overlapped, &bytecnt, TRUE);
	   if(GetLastError()==0){
		   CloseHandle(evt);
		   return std::string(chBuf, chBuf+bytecnt);
	   }
	   else{std::cout<<"readfrompipe - error code is "<<GetLastError()<<"\n";}
   }
   CancelIo(g_hChildStd_OUT_Rd); //hopefully this wont screw with cout calls in child proc
   CloseHandle(evt);
   return "";
}
closed account (48bpfSEw)
the answer is out there and it's waiting for you... ^^

https://www.google.de/search?q=cpp+ReadFile+pipe+stackoverflow&ie=utf-8&oe=utf-8&client=firefox-b&gfe_rd=cr&ei=_9JaV_StJaGF8Qej8rywDA

Oh I was dreading the named pipes answer.. guess I'll spend a few more hours on msdn

Edit: never mind.. you can call peek even if the pipe was created anonymously. Thanks!
Last edited on
Topic archived. No new replies allowed.