I'm able to create a child process and pipe its stdin and stdout. It works fine when it is in text mode. However, when I try to set the I/O in the child process to be in the binary format (i.e. no 0x0A to 0x0D 0x0A translation) the child process fails. _setmode returns -1 which has been documented to indicate failure. Why is that and how can it be fixed?
Parent code resembles the following:
const std::string path; // = "path_to.exe"
PROCESS_INFORMATION info;
SECURITY_ATTRIBUTES sec_attr;
//in-out from the CHILD process' perspective
HANDLE out_r = nullptr;
HANDLE out_w = nullptr;
HANDLE in_r = nullptr;
HANDLE in_w = nullptr;
sec_attr.nLength = sizeof(SECURITY_ATTRIBUTES);
sec_attr.lpSecurityDescriptor = NULL;
sec_attr.bInheritHandle = TRUE; //inherit by child processes
if (!CreatePipe(&out_r, &out_w, &sec_attr, 0))
throw std::exception();
if (!SetHandleInformation(out_r, HANDLE_FLAG_INHERIT, 0))
throw std::exception();
if (!CreatePipe(&in_r, &in_w, &sec_attr, 0))
throw std::exception();
if (!SetHandleInformation(in_r, HANDLE_FLAG_INHERIT, 0))
throw std::exception();
if (out_r && out_w && in_r && in_w)
{
startup_info.hStdError = out_w;
startup_info.hStdOutput = out_w;
startup_info.hStdInput = in_r;
startup_info.dwFlags = STARTF_USESTDHANDLES;
}
if (CreateProcessA(path.c_str(), (char*)cmd, NULL, NULL, TRUE, 0, NULL, NULL, &startup_info, &info)
!= TRUE)
{
DWORD error = GetLastError();
//error handling
}
// ... read data using ReadFile
Child code resembles the following:
int status = _setmode(_fileno(stdin), _O_BINARY);
if (status == -1)
throw std::exception();
status = _setmode(_fileno(stdout), _O_BINARY);
if (status == -1)
throw std::exception();
puts("hello from the child process");