...
If the intent of the programmer is to remove the file referenced by new_file
if it exists prior to calling rename()
, this code example is non-compliant on Windows platforms because it rename()
will fail, returns a nonzero value, and sets errno
to EACCES
.
Code Block | ||
---|---|---|
| ||
char const *old_file = /* ... */; char const *new_file = /* ... */; if (rename(old_file, new_file) != 0) { /* Handle Error */ } |
...
On Windows systems, it is necessary to explicitly remove the file referenced by new_file
before calling rename()
, if you want the file to be overwritten and the rename()
operation to succeed.
Code Block | ||
---|---|---|
| ||
char const *old_file = /* ... */; char const *new_file = /* ... */; if (_access_s(new_file,0) == 0) { if (remove(new_file) != 0) { /* Handle error condition */ } } if (rename(old_file, new_file) != 0) { /* Handle error condition */ } |
This code contains an unavoidable race condition conditions between the call to calls to _access_s()
, remove()
and the call to rename()
and can consequently only be safely executed within a secure directory (see FIO17-A. Ensure that file operations are performed in a secure directory).
...
On POSIX systems, if the file referenced by new_file
exists prior to calling rename()
, the file is automatically removed.
Code Block | ||
---|---|---|
| ||
char const *old_file = /* ... */; char const *new_file = /* ... */; if (rename(old_file, new_file) != 0) { /* Handle error condition */ } |
...
If the desired behavior is to ensure that any file referenced by new_file
is not removed, POSIX programmers must write implement additional codesafe guards.
Non-Compliant Code Example (POSIX)
If the intent of the programmer is to not remove the file referenced by new_file
if it exists prior to calling rename()
, this This code example is non-compliant because on POSIX systems the file is removedif new_file
exists it will be removed by rename()
.
Code Block | ||
---|---|---|
| ||
char const *old_file = /* ... */; char const *new_file = /* ... */; if (rename(old_file, new_file) != 0) { /* Handle Error */ } |
...