O_CREAT: Creating A File

Creating A File If It Does Not Exist (Bogus Version)

We saw in O_WRONLY: Writing A File (Which Must Exist) that a file is not implicitly created only because we open one, which is a good thing. Lets see how to use the O_CREAT to make this happen.

The following program

  • opens the file for writing [1], declaring that is must be created if it does not exist

    • We pass the O_WRONLY flag since this is our intention

    • We also pass the O_CREAT flag in a bitwise-or combination

#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);
    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_CREAT-bogus example-O_CREAT-bogus.c

Bogus O_CREAT Usage: Mode Parameter Missing

Lets see if a file that does not exist is created, and how that looks like:

$ ./example-O_CREAT-bogus /tmp/file-that-does-not-exist
$ ls -l /tmp/file-that-does-not-exist
--wxr-S---. 1 jfasch jfasch 0 May 13 18:09 /tmp/file-that-does-not-exist
What? Permissions -wxr-S---? This looks like if there’s

something wrong.

This is a consequence of reading manual pages too sloppily

O_CREAT

       ...

       The mode argument specifies the file mode  bits  to  be  applied
       when a new file is created.  If neither O_CREAT nor O_TMPFILE is
       specified in flags, then mode is ignored (and can thus be speci‐
       fied  as  0, or simply omitted).  The mode argument must be sup‐
       plied if O_CREAT or O_TMPFILE is specified in flags;  if  it  is
       not  supplied,  some  arbitrary bytes from the stack will be ap‐
       plied as the file mode.

       ...

Creating A File If It Does Not Exist

Fact is: if a file is created, someone needs to specify access permissions. This is what the optional third open() parameter is there for - mode.

int open(const char *pathname, int flags, mode_t mode);

It is common practice to specify 0666 as mode, and leave the rest to the system. The user can specify via the umask process attribute which permission bits to remove from the mode; see Default Permissions: umask for how that works, and how to specify the umask.

Here’s a fixed version of the bogus program from above:

#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, 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_CREAT example-O_CREAT.c

Footnotes