Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

This code example is noncompliant because any existing destination file is removed by rename().:

Code Block
bgColor#ffcccc
langc
const char *src_file = /* ... */;
const char *dest_file = /* ... */;
if (rename(src_file, dest_file) != 0) {
  /* Handle Error */
}

...

If the programmer's intent is not to remove an existing destination file, the POSIX access() function can be used to check for the existence of a file [Open Group 2004]. This compliant solution renames the source file only if the destination file does not exist.:

Code Block
bgColor#ccccff
langc
const char *src_file = /* ... */;
const char *dest_file = /* ... */;

if (access(dest_file, F_OK) != 0) {
  if (rename(src_file, dest_file) != 0) {
    /* Handle error condition */
  }
} 
else {
  /* Handle file-exists condition */
}

...

If the intent of the programmer is to remove the file referenced by dest_file if it exists prior to calling rename(), this code example is noncompliant on Windows platforms because rename() will fail.:

Code Block
bgColor#ffcccc
langc
const char *src_file = /* ... */;
const char *dest_file = /* ... */;
if (rename(src_file, dest_file) != 0) {
  /* Handle error */
}

...

On Windows systems, it is necessary to explicitly remove the destination file before calling rename() if you want the file to be overwritten and the rename() operation to succeed.:

Code Block
bgColor#ccccff
langc
const char *src_file = /* ... */;
const char *dest_file = /* ... */;

if (_access_s(dest_file, 0) == 0) {
  if (remove(dest_file) != 0) {
    /* Handle error condition */
  }
}

if (rename(src_file, dest_file) != 0) {
  /* Handle error condition */
}

This code contains unavoidable race conditions between the calls to _access_s(), remove(), and rename() and can consequently be safely executed only within a secure directory. (See FIO15-C. Ensure that file operations are performed in a secure directory.)  Another option would be to use the MoveFileEx API, and pass in the MOVEFILE_REPLACE_EXISTING flag.:

Code Block
bgColor#ccccff
langc
const char *src_file = /* ... */;
const char *dest_file = /* ... */;

if (!MoveFileEx(src_file, dest_file, MOVEFILE_REPLACE_EXISTING)) {
  /* Handle error condition */
}

...

On POSIX systems, if the destination file exists prior to calling rename(), the file is automatically removed.:

Code Block
bgColor#ccccff
langc
const char *src_file = /* ... */;
const char *dest_file = /* ... */;
if (rename(src_file, dest_file) != 0) {
  /* Handle error condition */
}

...

This compliant solution ensures that any destination file is portably removed.:

Code Block
bgColor#ccccff
langc
const char *src_file = /* ... */;
const char *dest_file = /* ... */;

(void)remove(dest_file);

if (rename(src_file, dest_file) != 0) {
  /* Handle error condition */
}

...

This compliant solution renames the source file only if the destination file does not exist.:

Code Block
bgColor#ccccff
langc
const char *src_file = /* ... */;
const char *dest_file = /* ... */;

if (!file_exists(dest_file)) {
  if (rename(src_file, dest_file) != 0) {
    /* Handle error condition */
  }
} 
else {
  /* Handle file-exists condition */
}

...