Ted Ts'o says that the good behaviour for saving a file is

One argument that has commonly been made on the various comment streams is that when replacing a file by writing a new file and the renaming “file.new” to “file”, most applications don’t need a guarantee that new contents of the file are committed to stable store at a certain point in time; only that either the new or the old contents of the file will be present on the disk. So the argument is essentially that the sequence:

fd = open(“foo.new”, O_WRONLY);
write(fd, buf, bufsize);
fsync(fd);
close(fd);
rename(“foo.new”, “foo”);

and he adds :

Openoffice, being a portable application, that has to work on other operating systems and filesystems (for example, like Solaris's UFS), does do open/write/close/fsync/rename. So you're safe if you're using OpenOffice (and emacs, and vim).

So i looked on my Debian/Sid at my favorite editors:

  • Vim 7.2
  • Emacs 22
  • Gedit 2.24.0
  • OpenOffice.org 3.0.1

see how they really do (and if they preserve ACL when saving a file named “foo”).

Only the Paranoid survive

Vim

  1. copy “foo” to “foo~”, with protective mode and ACL
  2. write the new content to “foo”
  3. fsync on “foo”

FAILED

  • not what Ted Ts'o told us ! If a crash happens, you get a corrupted “foo” and as the backup “foo~” is not fsync'ed, it may be also corrupted. Complete disaster;
  • file doesn't change, so it's the same inode, same mode and same ACL;
  • writes the file content 2 times (backup + new).

(PS: also checked vi on solaris, it behaves just like vim, total disaster.)

Emacs

  1. rename “foo” to “foo~”
  2. re-create “foo” for writing the new content
  3. fscync on “foo”
  4. chmod to restore mode
  5. remove “foo~”

FAILED

  • again, not what Ted Ts'o told us :) If a crash happens, you get a corrupted “foo”, but at least the backup file is safe. Half-disaster;
  • file has been re-created, so it's a new inode, ACL are not preserved.

Gedit

  1. open “.gedit-save-XXXXXX”
  2. chmod + chown + setxattr on that temp file to restore mode and ACL
  3. write to that temporary file the new content
  4. rename “foo” to “foo~”
  5. rename “.gedit-save-XXXXXX” to “foo”

FAILED

  • no fsync at all ! If it wasn't missing, it would do what Ted Ts'o's advises;
  • Half-disaster: “foo” may be incomplete, you would have to restore the “foo~” backup file (actually it's the original file).

OpenOffice.org

  1. backup “foo” to ~/.openoffice.org/3/user/backup/
  2. overwrites “foo” reading data from a temporary in “/tmp/svmpb.tmp/”

FAILED

  • no fsync;
  • Complete disaster: both “foo” and its backup may be broken;
  • writes twice the data;
  • file doesn't change, so it's the same inode, same mode and same ACL.

Suddenly, i don't feel like editing /etc/passwd with these text editors (but i haven't find a replacement yet). If the server was to crash, it might not reboot at all. Brrrr.

TODO:

  • look/open bug for emacs about ACL;
  • check newer gedit;
  • find out why Ted Ts'o thinks vim/emacs/openoffice behave safely.

It looks like Ted Ts'o was wrong :/