O_EXCL: Creating A File, But Failing If It Already Exists

Is “Create or Open” Always Wanted?

In O_CREAT: Creating A File, we created a file if it didn’t exist - or just opened it if it existed. This is not always the desired behavior: sometimes a program might want to be sure that a file that it creates is not there, or fail - preventing an accidental overwrite of existing data. This is exactly what the O_EXCL flag (in combination with O_CREAT) is there for.

The following program

  • Creates a new file by using O_CREAT | O_EXCL, in combination with O_WRONLY

  • writes a number of bytes to it

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>


int main(int argc, char** argv)
{
    const char* filename = argv[1];
    int fd;
    const char bytes_to_write[] = "Howdy\n";
    ssize_t nwritten;

    fd = open(filename, O_WRONLY|O_CREAT|O_EXCL, 0666);
    if (fd == -1) {
        perror("open");
        return 1;
    }

    nwritten = write(fd, bytes_to_write, sizeof(bytes_to_write));
    if (nwritten == -1) {
        perror("write");
        return 2;
    }

    close(fd);
    return 0;
}
Build it
$ gcc -o example-O_EXCL example-O_EXCL.c

Sunny Case: File Does Not Exist

$ ./example-O_EXCL /tmp/another-file-that-does-not-exist
$ ls -l /tmp/another-file-that-does-not-exist
-rw-rw-r--. 1 jfasch jfasch 7 May 15 22:16 /tmp/another-file-that-does-not-exist
$ cat /tmp/another-file-that-does-not-exist
Howdy

Error: File Exists

$ ./example-O_EXCL /tmp/another-file-that-does-not-exist
open: File exists