Posted Mar 17, 2009 23:42 UTC (Tue) by ikm (subscriber, #493)
Parent article: Better than POSIX?
Personally, I'd propose an additional mode letter to the standard fopen() libc function. Surely most people here know the "b" flag which is ignored everywhere except in Windows? Why not do the same thing for atomic updates?
E.g. suppose we call it "f". Then
FILE * f = fopen( "precious_config", "wf" );
...
fwrite(...);
...
fclose( f );
That flag would mean that the original file is to be kept untouched until the stream is closed. Instead, a replacement inode is to be allocated on the same media, getting all new changes. At the moment stream is closed, the new inode is to atomically replace the original one. So you'd either get the old version, or the new version.
Programs that would use the new flag would still be portable, since that flag would just be ignored if not known. Yes, they won't be using rename tricks in that case, but I doubt most people care that much anyway. At least, I don't do rename tricks, but I'd happily use new flag is there was one.
In glibc, the whole thing could be implemented either by using a special flag to the underlying open syscall if one exists, or by just utilizing the rename trick internally otherwise.
Posted Mar 18, 2009 0:17 UTC (Wed) by quotemstr (subscriber, #45331)
[Link]
FILE * f = fopen( "precious_config", "wf" );
All we need is a "t" flag. :-)
In all seriousness, I think that's the wrong level of abstraction for this functionality. A C FILE* returned by fopen should correspond to only one underlying file, and that file shouldn't magically change its name.
Besides, a flag to open won't work because the kernel would have to spool modifications to that file until commit, and that would not only be very complex, but could open up all kind of denial-of-service attacks.
I wouldn't mind, however, a libc function that encapsulated the very common open-write-close-rename sequence. I wouldn't even mind some function that returned a FILE*. I just don't think that function should be called fopen, and don't think that FILE* shouldn't be closed with fclose -- think of something more like popen.