4 ms·
It's crazy how we still don't have the ability to atomically create/replace a file on the popular operating systems and filesystems , despite that being a super
by CodesInChaos 4y ago
It's crazy how we still don't have the ability to atomically create/replace a file on the popular operating systems and filesystems , despite that being a super common use-case (without workarounds like renaming which have annoying limitations).
- mhandley 4y agoWhat would you want from an atomic replace of the contents of a file that rename() doesn't provide? Surely you've got to write the new contents somewhere before calling your atomic replace, and that's exactly what happens with rename/mv.
- spullara 4y agoRename does it and that it the workaround for issues like this.
- CodesInChaos 4y agoHow do you atomically replace an existing file using rename? I believe rename fails if the target file already exists, instead of atomically replacing it. Plus you end up with orphaned temporary files if you crash at the wrong point. There is another workaround using unnamed tempfiles on Linux, but I think even that approach doesn't work for replacing files. And then there is the issue that this creates a new file with the same name, instead of replacing the contents of the existing file. I think that's often not the desired behaviour regarding symlinks or inode ids. And finally all those workarounds are overly complicated, so almost no application uses them, while pretty much every application that saves some kind of document (image, textfile, etc.) would benefit from atomic saving.
- mhandley 4y agomv uses rename(). No issue with the target file existing beforehand. No issue with symlinks going stale, because they link to the name not the inode. Hard links will preserve the old file and still refer to that though (which is sometimes what you want, sometimes not). But for most, symlinks are far more common. $ echo "File 1" > file1 $ echo "File 2" > file2 $ ln -s file2 file3 $ cat file3 File 2 $ echo "File 4" > file4 $ mv file4 file2 $ cat file3 File 4