Не могу написать в трубу Windows через стандартный вывод - PullRequest
0 голосов
/ 11 октября 2018

_open_osfhandle создает дескриптор файла C из дескриптора файла Windows, а _dup может изменять базовый объект файла существующего fd.При использовании для перенаправления stdout в CreatePipe канал ReadFile не захватывает выходные данные, записанные в stdout.

Следующий фрагмент кода демонстрирует суть того, что я пытаюсь.Я хочу создать анонимный канал, заменив stdout, чтобы я мог прочитать его из дескриптора чтения.

Документация, которую мне удалось найти, указывает, что _open_osfhandle и _dup2 могут это выполнитьстраница документации об обмане и Microsoft для dup2 специально призывает заменить fd в stdout как возможную.

Учитывая все это, я ожидаю, что следующий код немедленно вернется из ReadFile с записанными байтамиprintf как предыдущие вызовы _write и fprintf работали как положено.

HANDLE hread;
HANDLE hwrite;
SECURITY_ATTRIBUTES sa = { sizeof(sa),NULL,TRUE };
CreatePipe(&hread, &hwrite, &sa, 0);
int fd = _open_osfhandle(intptr_t(hwrite), _O_TEXT);
FILE *fp = _fdopen(fd, "w");
setvbuf(fp, NULL, _IONBF, 0);
_dup2(_fileno(fp), _fileno(stdout));
TCHAR buffer[64] = { 0 };
DWORD bytesRead;
//_write(fd, "_write", 6); // works
//fprintf(fp, "fprintf"); // works
printf("printf");
ReadFile(hread, buffer, sizeof(buffer), &bytesRead, NULL);

1 Ответ

0 голосов
/ 11 октября 2018

Расследование наконец принесло свои плоды.Поток файла, открытый _fdopen, буферизируется по умолчанию, предотвращая запись чего-либо в дескриптор канала ОС.setvbuf может использоваться для отключения, поэтому запись происходит немедленно.

Выполнение dup2 для сброса базового файла, привязанного к файловому дескриптору стандартного вывода, сбрасывает буферизацию, поэтому работает следующий код.Вызов _fdopen сбрасывается по мере необходимости, и `setvbuf 'выполняется на стандартный вывод.

HANDLE hread;
HANDLE hwrite;
SECURITY_ATTRIBUTES sa = { sizeof(sa),NULL,TRUE };
CreatePipe(&hread, &hwrite, &sa, 0);
int fd = _open_osfhandle(intptr_t(hwrite), _O_TEXT);
_dup2(fd, _fileno(stdout));
setvbuf(stdout, NULL, _IONBF, 0);
TCHAR buffer[64] = { 0 };
DWORD bytesRead;
printf("printf");
ReadFile(hread, buffer, sizeof(buffer), &bytesRead, NULL);
...