...
This compliant solution invokes fopen()
at a single location and uses the x
mode of fopen()
, which was added in C11. This mode causes fopen()
to fail if the file exists. This check and subsequent open is performed without creating a race window. Note that the The x
mode provides exclusive access to the file only if the host environment provides this support.
...
FIO45-C-EX2: Accessing a file name or path name multiple times is permitted if the file referenced resides in a secure directory. (for For more information, see FIO15-C. Ensure that file operations are performed in a secure directory.).
FIO45-C-EX3: Accessing a file name or path name multiple times is permitted if the program can verify that every operation operates on the same file.
This POSIX code example verifies that each subsequent file access operates on the same file. In POSIX, every file can be uniquely identified by using its device and i-node attributes. This code example checks that a file name refers to a regular file (and not a directory, symbolic link, or other special file) by invoking lstat()
. This call also retrieves its device and i-node. The file is subsequently opened. Finally, the program verifies that the file that was opened is the same one (matching device and i-nodes) as the file that was confirmed as a regular file.
Code Block | ||||
---|---|---|---|---|
| ||||
#include <sys/stat.h> #include <fcntl.h> int open_regular_file(char *filename, int flags) { struct stat lstat_info; struct stat fstat_info; int f; if (lstat(filename, &lstat_info) == -1) { /* File does not exist, handle error */ } if (!S_ISREG(lstat_info.st_mode)) { /* File is not a regular file, handle error */ } if ((f = open(filename, flags)) == -1) { /* File has disappeared, handle error */ } if (fstat(f, &fstat_info) == -1) { /* Handle error */ } if (lstat_info.st_ino != fstat_info.st_ino || lstat_info.st_dev != fstat_info.st_dev) { /* Open file is not the expected regular file, handle error */ } /* f is the expected regular open file */ return f; } |
...