Choose which descriptors are inherited by the child process.

When creating a child process in C ++ using the Windows API, you can enable the inheritance of handles from parent to child. In the Microsoft example, Creating a child process with redirected inputs and outputs redirecting the child process' std in / out to channels created by the parent, you must enable inheritance for the redirect channels.

I am working on a small demo class that runs an external executable, reads the output, and then returns it to the caller (which writes the returned output to a file). I am trying to create a timeout function where it will only block for a while before calling TerminateProcess() for the child and continue life.

However, I found that by allowing descriptor inheritance, the child process also has a descriptor (visible from Process Explorer ) in the output file. I do not want the child process to receive this descriptor, but the parent in this case (this demo class) also does not know about this descriptor, so I can not use SetHandleInformation() to immediately remove the output file to exclude it from inheritance.

I am sure that there should be a better way to inherit ONLY the specific pens that I want, avoiding the imposition of a “blanket” that skips unintentional and unwanted calls. Unfortunately, I could not find a solution by browsing as many related MSDN articles as possible and finding Googled in a state of despondency.

At least I need to do something to remove the descriptors from the child, not necessarily having these descriptors inside the demo class (they are used by the calling class, and this demo class does not have an explicit knowledge of its existence).

Any solutions for more selective inheritance? I am particularly interested in a solution that allows me to specifically declare which descriptors are inherited, and all unspecified descriptors will not be inherited if such a solution exists.

Thank you.

+6
c ++ windows parent-child handle
source share
2 answers

If the output file descriptor is inherited by the child process, this is because the code in the parent process opened the file, which explicitly states that the file descriptor must be inherited. It passed the value for the lpSecurityAttributes CreateFile parameter. The default state is that the handle is not inherited.

It seems to me that your class creating the process should not try to guess its caller who already opened the file.

However, if you have special knowledge of what exactly the new process handles, then with Windows Vista there is a mechanism for determining which descriptors should be inherited. When you are preparing to call CreateProcess , use STARTUPINFOEX instead of the usual STARTUPINFO . It has a member of lpAttributeList . Select and initialize it, and then UpdateProcThreadAttribute with PROC_THREAD_ATTRIBUTE_HANDLE_LIST to set the list of inherited handles. All handles must be inherited, and you still need to specify bInheritHandles = true when you call CreateProcess . You must also include EXTENDED_STARTUPINFO_PRESENT in the dwCreationFlags parameter. Raymond Chen demonstrated the technique in an article in 2011.

If this added functionality is not available to you, you can, of course, try [list all your open program descriptors] and set all your inheritance properties using SetHandleInformation , but this is beyond the scope of the function whose task is to create child processes. Let the code that creates the handles worry about whether they should be inherited.

+3
source share

You can use SetHandleInformation to clear the HANDLE_FLAG_INHERIT bit from your output descriptor, this will not allow the child process to inherit it.

If this flag is set, the child process created with the bInheritHandles CreateProcess parameter set to TRUE inherits the handle to the object.

+1
source share

All Articles