Я пытаюсь создать дочерний процесс, выполняющий любую команду exe, и перенаправить все его stdio и stderr на мой родительский процесс через анонимный канал.Но когда мой родительский процесс пытается выполнить ReadFile () в конце READ анонимного канала после завершения дочернего процесса, он просто блокирует, а не возвращает ошибку.
Вот код:
#include "windows.h"
//==================================================
void createChildPipes(PHANDLE phRead, PHANDLE phWrite){
SECURITY_ATTRIBUTES sa={sizeof(SECURITY_ATTRIBUTES) ,NULL,TRUE};
if ( !CreatePipe(phRead, phWrite, &sa, 2048) ) { //... }
}
//==================================================
void setupStartupInfo(LPSTARTUPINFO lpsi, HANDLE hStdOutput, HANDLE hStdError) {
lpsi->cb = sizeof(STARTUPINFO);
lpsi->lpReserved=NULL;
lpsi->lpDesktop=NULL;
lpsi->lpTitle=NULL;
lpsi->dwX=0;
lpsi->dwY=0;
lpsi->dwXSize=200;
lpsi->dwYSize=500;
lpsi->dwFlags=STARTF_USESTDHANDLES;
lpsi->cbReserved2=0;
lpsi->lpReserved2=NULL;
lpsi->hStdInput=GetStdHandle(STD_INPUT_HANDLE);
lpsi->hStdError= hStdError;
lpsi->hStdOutput=hStdOutput;
}
//==================================================
void createChildProcess(PHANDLE phOutRead, PHANDLE phOutWrite, PHANDLE phErrRead, PHANDLE phErrWrite) {
TCHAR name[]=_T("cl.exe");
createChildPipes(phOutRead, phOutWrite);
STARTUPINFO si;
setupStartupInfo(&si, *phOutWrite, *phOutWrite);
PROCESS_INFORMATION pi;
if (!CreateProcess(NULL, name, NULL, NULL, true, 0, NULL, NULL, &si, &pi)) { //...}
}
//==================================================
void _tmain(int argc, _TCHAR* argv[]){
HANDLE hOutRead, hOutWrite, hErrRead, hErrWrite;
createChildProcess(&hOutRead, &hOutWrite, &hErrRead, &hErrWrite) ;
char buf[10];
BOOL readState;
for (;;) {
DWORD dwBytesRead;
memset(buf, '\0', sizeof(buf));
readState=ReadFile(hOutRead, buf, sizeof(buf)-2 , &dwBytesRead, NULL);
printf("%s", buf);
if (!readState)
break;
}
}
Это то, что делает мой код.Мой _tmain () создает дочерний процесс (я использую команду VC ++ cl.exe в качестве теста) и перенаправляет его stdio и stderr на HANDLE записи анонимного канала.Мой родительский процесс читает из РУЧКИ чтения той же трубы.
Они напечатаны my _tmain (), показывая, что канал может связываться через родительско-дочерние процессы.Это то, что мы ожидаем увидеть, если мы введем cl.exe в командной строке без каких-либо аргументов.Обратите внимание на своеобразное поведение cl.exe: первые две строки взяты из stderr cl.exe, а последняя - из stdout.
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.30319.01 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
usage: cl [ option... ] filename... [ /link linkoption... ]
Теперь о проблеме, строка:
readState=ReadFile(hOutRead, buf, sizeof(buf)-2 , &dwBytesRead, NULL);
в блоках _tmain () после завершения дочернего процесса cl.exe.Но я ожидаю, что вызов ReadFile () вернется с ошибкой ERROR_BROKEN_PIPE и выйдет из родительского цикла вместо блокировки вызова ReadFile ().
Почему блоки ReadFile () блокируются при чтении анонимного канала?