Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Added a paragraph about an alternative POSIX solution using link()

...

Wiki Markup
If the programmer's intent is to not remove an existing destination file, the POSIX {{access()}} function can be used to check for the existence of a file \[[Open Group 04|AA. References#Open Group 04]\]. This compliant solution only renames the source file only if the destination file does not exist.

...

This code contains an unavoidable race condition between the call to access() and the call to rename() and can consequently be safely executed only when the destination file is located within a secure directory (see FIO15-C. Ensure that file operations are performed in a secure directory).

On file systems where the program does not have sufficient permissions in the directory to view the file, access() may return -1 even when the file exists. In such cases, rename() will also fail because the program lacks adequate permissions to perform the operation.

In situations where the source file is supposed not to be a directory or symbolic link, an alternative solution is to use link() to link the source file to the destination file and then use unlink() (or remove()) to delete the source file. Since link() fails if the destination file exists, this avoids the need for calling access(). However, this solution has two race conditions related to the source file. Firstly, before calling link() the program must use lstat() to check that the source file is not a directory or symbolic link. Secondly, there is the time window between the link() and the unlink() during which the source file could change. Consequently this alternative solution can be safely executed only when the source file is located within a secure directory.

Compliant Solution (Windows)

...