1

I have a C++ program that runs a java process and reads it's output. I used the following MSDN code:

http://msdn.microsoft.com/en-us/library/ms682499%28v=vs.85%29.aspx

However, when reading the final line of the output

bSuccess = ReadFile(g_hInputFile, chBuf, BUFSIZE, &dwRead, NULL);

bsucces equals 1, so the program continue to the next loop, and when reaching the same line, the program just "fly", with no exception, stopping to debug, the breakpoint never moves to then next line.

I guess this is because there is no EOF to indicate stop reading. However, java do not have a EOF charcater. The java program simply does:

System.out.close();

at end.

What can I do in the C++\Java code in order to fix it?

EDIT:

Here is the code.

It doesn't work with any console application, read to end and then "hang".

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_hInputFile = NULL;
PROCESS_INFORMATION piProcInfo;

void CreateChildProcess()
// Create a child process that uses the previously created pipes for STDIN and STDOUT.
{
    std::string d=processLoaction;
    TCHAR *cmdline=new TCHAR[d.size()+1];
    cmdline[d.size()]=0;
    std::copy(d.begin(),d.end(),cmdline);
   STARTUPINFO siStartInfo;
   BOOL bSuccess = FALSE; 

// Set up members of the PROCESS_INFORMATION structure. 

   ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );

// Set up members of the STARTUPINFO structure. 
// This structure specifies the STDIN and STDOUT handles for redirection.

   ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
   siStartInfo.cb = sizeof(STARTUPINFO); 
   siStartInfo.hStdError = g_hChildStd_OUT_Wr;
   siStartInfo.hStdOutput = g_hChildStd_OUT_Wr;
   siStartInfo.dwFlags |= STARTF_USESTDHANDLES;

// Create the child process. 
   bSuccess = CreateProcess(NULL, cmdline, NULL, NULL, TRUE, 0, NULL, NULL, &siStartInfo, &piProcInfo);  // receives PROCESS_INFORMATION 

   // If an error occurs, exit the application. 
   if ( ! bSuccess ) 
      throw new Exception("Failed to create process");
   else 
   {
      // Close handles to the child process and its primary thread.
      // Some applications might keep these handles to monitor the status
      // of the child process, for example. 

      CloseHandle(piProcInfo.hProcess);
      CloseHandle(piProcInfo.hThread);
   }
}

void ReadFromPipe(void) 
// Read output from the child process's pipe for STDOUT
// and write to the parent process's pipe for STDOUT. 
// Stop when there is no more data. 
{ 
   DWORD dwRead, dwWritten,status; 
   CHAR chBuf[BUFSIZE]; 
   BOOL bSuccess = FALSE;
   HANDLE hParentStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
   BOOL res;
   for (;;) 
   { 
      bSuccess = ReadFile( g_hChildStd_OUT_Rd, chBuf, BUFSIZE, &dwRead, NULL);
      if( ! bSuccess || dwRead == 0 ) 
          break; 
      chBuf[dwRead] = NULL;
      bSuccess = WriteFile(hParentStdOut, chBuf, dwRead, &dwWritten, NULL);
      if (! bSuccess ) 
          break; 
   } 

}

int main(int argc, char** argv)
{ 
          //run the Jar to validate manifest & jeff
          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) )
              throw new Exception("faild to create a pipe for the child process's STDOUT");

          // Ensure the read handle to the pipe for STDOUT is not inherited.
          if ( ! SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0) )
              throw new Exception("Read handle to the pipe for STDOUT is inherited");
          CreateChildProcess();
          ReadFromPipe();
            ...
}
2
  • Are you sure you are reading from the right file/handle? - In the example code, data is read from the child process via bSuccess = ReadFile( g_hChildStd_OUT_Rd, chBuf, BUFSIZE, &dwRead, NULL);. Commented Nov 28, 2012 at 13:38
  • @HannoBinder yes, all the lines are read successfully, and written to my own console. At the end I just left "hanging" Commented Nov 28, 2012 at 13:41

1 Answer 1

1

The problem seems to be addressed in some comments of the page you linked: you have to close the writing side of the pipe after creating the child process, but before starting reading from the other side. If you fail to do that, even if the child process closes its output, the writing side of the pipe is still opened (by the parent process) and so the EOF is never reached.

Ah and don't forget to close all the handles of the parent process. The example in the linked page does not, and it leaks!

Sign up to request clarification or add additional context in comments.

1 Comment

@sara: Even if you don't use it, you have the handle and you must close it. The pipe itself will not be marked as EOF'ed as long as there is any writing handle opened.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.