...
This compliant solution uses only one instance of fopen()
, 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 done without creating a race window. Note that the x
mode provides exclusive access to the file only if the operating platform provides this support.
Code Block |
---|
|
#include <stdio.h>
void open_some_file(const char *file) {
FILE *f;
if ((f = fopen(file, "wb+xwx");
if (f =) != NULL) {
/* Handlehandle error */
}
printf("access granted.\n");
/* write to the file */
if (fclose(f);
}
!= 0) {
/* handle error */
}
} |
Compliant Solution (POSIX write)
...
Code Block |
---|
|
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
void open_some_file(const char *file) {
int fd = open(file, O_CREAT | O_EXCL | O_RDWR);
if (fd != -1) {
FILE *f = fdopen(fd, "rw+");
if (f != NULL) {
printf("access granted.\n");
/* write to file */
if (fclose(f); != 0) {
/* handle error */
}
}
if (close(fd); != 0) {
/* handle error */
}
}
} |
Noncompliant Code Example (POSIX read)
...
Code Block |
---|
|
#include <stdio.h>
#include <unistd.h>
void open_some_file(const char *file) {
FILE *f;
if (access(file, R_OK | W_OK) == 0) {
printf("access granted.\n");
f = fopen(file, "rb+");
if (NULLf == fNULL) {
/* Handle error */
}
/* read file */
if (fclose(f);) != 0) {
/* handle error */
}
}
}
|
Compliant Solution (read)
...
Code Block |
---|
|
#include <stdio.h>
void open_some_file(const char *file) {
FILE *f = fopen(file, "rb+");
if (NULLf == fNULL) {
/* Handle error */
}
printf("access granted.\n");
/* read file */
if (fclose(f);) != 0) {
/* handle error */
}
}
|
Exceptions
FIO45-EX1: Accessing a path multiple times is permitted if it is requested specifically by a user. A program that accepts commands from a user to read or write a specific filename does not violate this standard. Example programs would include file managers or text editors.
...