3

I would like to write code that does the following:

1) Open a file (for writing), creating the file if it doesn't exist.

2) Ensure the file exists while running some other code (by holding the file open).

3) Close the file, and delete the file if it was created during step 1.

Do any of the POSIX/C++17 stdlib/boost filesystem functions make this easy?

NOTE: A solution which involves multiple open calls and gives invalid results if the file is created/deleted between them is not one I want.

Drew
  • 12,578
  • 11
  • 58
  • 98
  • Maybe file watch would solve 2) https://stackoverflow.com/questions/931093/how-do-i-make-my-program-watch-for-file-modification-in-c#931165 ? Although I don't see any "POSIX/C++17 stdlib/boost" multiplatform wrapper over it. – R2RT May 22 '19 at 05:21

2 Answers2

0

Since the logic is different if the file is created (as a temp), you can first check if the file exists. If not create it with O_CREAT | O_EXCL and store the fd in a unique_ptr/shared_ptr with a custom deleter that removes the file, in addition to closing the fd. The O_EXCL is to avoid a race resulting in duplicate removal and ensures you actually created the file. If you expect this to be highly contended, you can check for EEXIST and retry in that case. If you happen to remove a temp-file opened by another parallel version of your call, it will stay around until the fd is closed.

midor
  • 5,487
  • 2
  • 23
  • 52
0

I don't think this can be handled in a portable way, you will likely have to resort to platform specific APIs.

For instance, on Windows, you can use CreateFile() with the CREATE_ALWAYS flag, and if the file is successfully opened, and a subsequent call to GetLastError() returns 0 instead of ERROR_ALREADY_EXISTS, the file was created anew, so call SetFileInformationByHandle(FileDispositionInfo) to enable the FILE_DISPOSITION_INFO::DeleteFile flag on the file. That way, when all open handles to the file are closed, it will be deleted automatically by the OS.

You can then optionally attach the file handle to a std::(i|o)fstream, if needed.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770