Consider this example:
FILE* stream = fopen("my_file", "w");
fputs("hello", stream);
What can happen if power is lost during the execution of fputs()?
Afterwards, could I ever find "my_file" with non-zero size but with the first byte not being 'h'? If yes, is it guaranteed to be zero, or could it contain an arbitrary value?
Assume, of course, that nobody else is touching our file.
EDIT: Assume also that the target disk drive/device is of a type that is able to keep power long enough to write all the data that it has buffered internally.
Does POSIX have anything to say about this? Does Linux? Does Windows?
EDIT: It was not my intention to focus on the details of how the STDIO streams API is implemented. Assuming POSIX, here is what I really mean:
int fd = open("my_file", O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
write(fd, "hello", 5);
EDIT: POSIX considers the size as meta data for the file, so the question could probably be rephrased as: Can the file data and the meta data for that file ever be committed to disk in separate stages as a result of the code above?
EDIT: Found this in http://www.sqlite.org/atomiccommit.html:
7.5 Filesystems With Safe Append Semantics
Another optimization introduced in SQLite version 3.5.0 makes use of "safe append" behavior of the underlying disk. Recall that SQLite assumes that when data is appended to a file (specifically to the rollback journal) that the size of the file is increased first and that the content is written second. So if power is lost after the file size is increased but before the content is written, the file is left containing invalid "garbage" data. The xDeviceCharacteristics method of the VFS might, however, indicate that the filesystem implements "safe append" semantics. This means that the content is written before the file size is increased so that it is impossible for garbage to be introduced into the rollback journal by a power loss or system crash.
This seems to provide at least a partial answer.