Atomically writing contents into a file

Posted on 2016-05-17

Recently at work, I had a need to write some content atomically into a file. Unix/POSIX has no system calls that can open, write and close a file atomically. The content I wanted to write was just one byte, so I was thinking of encoding this info into the file name itself. But my colleague suggested a nicer solution. I think I had seen that solution in quite a few places, but didn’t remember when I wanted it myself, so putting it here as a note to myself.

The idea is simple. In POSIX, rename(2) is guaranteed to be atomic. So, open a temporary file, write into the file and close it and then at the end rename it. If power goes off before rename call, leaving the filesystem inconsistent, the old content of the file is preserved, as we are operating on a temporary file and the original file has not yet been touched.

Without much ado, here is the snippet of code.

...
...
   int fd = open("/foo/bar.tmp", O_WRONLY | O_CREAT | O_TRUNC, (S_IRUSR | S_IWUSR));
   if (fd < 0) {
     ...
   }
   if (write(fd, ..., ...) < 0) {
     ...
   }
   fsync(fd);
   close(fd);
   rename("/foo/bar.tmp", "/foo/bar");
   sync();
...
...