Reputation: 206667
I have two programs, let's call them prog-1.exe
and prog-2.exe
. prog-1.exe
starts prog-2.exe
using system
. The first thing I would like to do in prog-2.exe
is close all the open file handles that it inherited from prog-1.exe
. This is what I have tried:
Starting Code for prog-2.exe
static int closeFileHandles()
{
// From http://msdn.microsoft.com/en-us/library/fxfsw25t.aspx
// The _fcloseall function closes all open streams
// except stdin, stdout, stderr
return _fcloseall();
}
int main(int argc, char** argv)
{
// First things first...
// Close all the inherited file handles.
closeFileHandles();
// Continue with the rest of the program
}
Code in prog-1.exe
FILE* in = fopen(inputFile, "r");
// ....
// ....
// Start prog-2.exe
system("prog-2.exe"); // It's in my path.
// prog-2.exe starts another process that stays in background mode
// Call this server.exe.
// Close the file.
fclose(in);
Problem
I want to delete the directory where inputFile
is from prog-1.exe
. I am not able to delete the directory since server.exe
has an open handle to inputFile
(This information is given by Windows when I try to delete the directory in Windows Explorer).
Questions
Am I not using _fcloseall()
correctly?
Is _fcloseall()
the right function to use for my purposes?
Are there any other functions/methods to close all the open file handles inherited from a parent process?
Upvotes: 0
Views: 2504
Reputation: 36328
There is no supported way to enumerate handles, so it is not usually practical to close all inherited handles within the subprocess. (In principle your main process could pass the subprocess a list of handles to close, but if the main process has such a list it would be easier to disable inheritance on those handles.)
However, if you launch the subprocess using CreateProcess
instead of system()
you have the option to disable handle inheritance by setting bInheritHandles
to FALSE
. This is the most straightforward solution in your situation.
Alternatively, if you needed to inherit only one or more specific handles (for example, in order to redirect the standard input or output) you could use PROC_THREAD_ATTRIBUTE_HANDLE_LIST
with UpdateProcThreadAttributeList
and associated functions to specify the handles you want inherited. The attribute list can be passed to CreateProcess
by passing a STARTUPINFOEX
structure and setting EXTENDED_STARTUPINFO_PRESENT
in the dwCreationFlag
parameter.
Upvotes: 2