O_WRONLY: Writing A File (Which Must Exist)

Writing (And Not Creating) A File

Continuing from O_RDONLY: Reading a File, lets see how a file is written. This is where the O_WRONLY (or O_RDWR if combined reading and writing is desired) is passed to open().

The following program

  • opens the file for writing

    • This time we pass the O_WRONLY flag since this is our intention

  • 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);
    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_WRONLY example-O_WRONLY.c

Error: File Not Writeable

Lets start with an error: /etc/passwd is clearly not writeable for others, and this is what we see:

$ ./example-O_WRONLY /etc/passwd
open: Permission denied

Error: File Not Even There ⟶ Not Implicitly Created

$ ./example-O_WRONLY something-thats-not-there
open: No such file or directory

This obviously means that, just because I declare my intention to write to a file, that file is not automatically created.

This is intended: if such files were create, we would litter our filesystems with garbage just because we misspelled filenames.

Sunny Case: File Exists, And Is Writeable

Now that we know that a file must exist for O_WRONLY to work, we create one, and then write to it:

$ touch /tmp/something-thats-not-there
$ ./example-O_WRONLY /tmp/something-thats-not-there
$ cat /tmp/something-thats-not-there
Howdy

That was easy.