R Sahu
R Sahu

Reputation: 206667

How can I close all the open file handles in a child process?

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

Answers (1)

Harry Johnston
Harry Johnston

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

Related Questions