2012-06-29 2 views
2

Я пытаюсь отследить проблему в некотором коде Win32, который я унаследовал. Это old standby от CreatePipe() x2, за которым следует DuplicateHandle() x2 и CreateProcess().Что такое флаг DUPLICATE_CLOSE_HANDLE DuplicateHandle?

if (!CreatePipe(&child_stdout_read, &parent_write, &security, 0) || 
     !DuplicateHandle(GetCurrentProcess(), parent_write, 
     GetCurrentProcess(), &child_stdout_write, 0, TRUE, 
     DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE)) { 
     throw std::system_error(GetLastError(), std::system_category()); 
    } 

Что имеет меня путать это флаг DUPLICATE_CLOSE_SOURCE используется в DuplicateHandle() вызовов. Согласно документам Microsoft это означает, что дескриптор источника будет закрыт после дублирования.

Что конкретно может сделать копирование ручки (в трубу) в тот же процесс, а затем закрытие оригинала? Почему бы просто не использовать оригинал?

+0

Это дублируя ручку записи в трубы в дочернем процессе. Я предполагаю, что родитель не должен содержать дескриптор записи, поэтому он позволяет DuplicateHandle() закрывать его. – Luke

+0

Но если вы посмотрите, в этом случае процесс «from» и «to» будут одинаковыми. Я объясню это. –

+0

Ну, это странно. Возможно, код делает что-то странное с handle_write и child_stdout_write. Я не могу на самом деле опасаться угадывания, основанного на минимальном фрагменте. – Luke

ответ

4

Ну, мне кажется, что ключ находится в параметре TRUE. То есть BOOL bInheritHandle, так что этот код делает, чтобы дублировать дескриптор, чтобы сделать его наследуемым.

Обычно это можно сделать, установив security.bInheritHandle на TRUE при создании ручки. Но в этом случае это сделает и обрабатывает наследуемые. И, очевидно, оригинальный автор только хочет наследовать child_stdout_write.

Обратите внимание, что тот же эффект может быть достигнут с менее contrieved код:

SetHandleInformation(handle, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT); 
+0

Ahh. Держу пари, это все. По крайней мере, я думаю, это, наверное, то, что он * пытался сделать. Он * сделал * установил 'security.bInheritHandle = true;'. Тем не менее, есть более поздний код (который он прокомментировал, вероятно, потому, что он не использовал правильные ручки), где он отключает бит «HANDLE_FLAG_INHERIT» на пару дескрипторов. Вероятно, именно то, что он * хотел * сделать, это сделать только два дескриптора для наследуемого клиента, но в итоге он написал много лишнего кода (и его манипуляции были замешаны в процессе). –

+0

Да, перенаправление std {in, out} - беспорядок. 2 трубы раз 2 ручки на трубу раз 2 процесса, равно 8 ручками, чтобы думать в то же время! – rodrigo

+0

... с этим кодом прокомментировал, также он сделал несколько лишних ручек, унаследованных, что стало источником ошибки, которая заставила меня взглянуть на это в первую очередь. Ура! Принимая это, поскольку он отвечает как на мой вопрос, так и на мой мета-вопрос :-). Теперь, чтобы очистить этот код ... –

Смежные вопросы