int main(int argc, char *argv[])
{
FILE *fp = fopen("a.txt", "wt");
fprintf(fp, "AAAA");
// No flush. and No close
raise(SIGTERM);
exit(EXIT_SUCCESS);
}
result: No data has written to a.txt
I expected this is fine. Because the system will close the file handle and then the filesystem driver flushes the unflushed data in his Close handler. But it wasn't. I tested this code on EXT4, ubuntu 11.10
Question:
I thought ALL filesystems must flush unflushed data at his close processing.
Posix doesn't have the rule?
P.S This code worked well (flushed well) on NTFS, Win7
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE h = CreateFile(L"D:\\a.txt", GENERIC_READ|GENERIC_WRITE,
0, 0, OPEN_ALWAYS, 0, 0);
BYTE a[3];
memset(a, 'A', 3);
DWORD dw;
WriteFile(h, (PVOID)a, 3, &dw, 0);
TerminateProcess(GetCurrentProcess(), 1);
return 0;
}
Edit:
I tested it again with system call write
. And it was flushed well.
int main(int argc, char** argv)
{
int fd = open("a.txt", O_CREAT|O_TRUNC|O_WRONLY);
char buf[3];
memset(buf, 'A', 3);
size_t result = write(fd, buf, 3);
raise(SIGTERM);
exit(EXIT_SUCCESS);
return 0;
}
Will buffer be automatically flushed to disk when a process exits? In general the answer is no.
Open stdio(3) streams are not flushed. On the other hand, _exit() does close open file descriptors, and this may cause an unknown delay, waiting for pending output to finish. If the delay is undesired, it may be useful to call functions like tcflush(3) before calling _exit().
This isn't anything to do with the filesystem, rather it's the behaviour of the C implementation you are using that determines when open streams are flushed or not.
Under POSIX, the default action action for the SIGTERM
signal is:
Abnormal termination of the process. The process is terminated with all the consequences of _exit()...
_exit()
is equivalent to _Exit()
according to the C standard and the choice of whether to flush streams is not specified by the standard:
The _Exit() and _exit() functions shall not call functions registered with atexit() nor any registered signal handlers. Whether open streams are flushed or closed, or temporary files are removed is implementation-defined...
Assuming you are using glibc on Linux, from the documentation (emphasis mine):
When a process terminates for any reason—either because the program terminates, or as a result of a signal—the following things happen:
- All open file descriptors in the process are closed. See Low-Level I/O. Note that streams are not flushed automatically when the process terminates; see I/O on Streams.
I'm not familiar with the Windows' WriteFile
and TerminateProcess
so I can't comment on what the documented behaviour is.
It doesn't have anything to do with file system drivers. The issue is that the CRT is buffering the file stream itself. You set the buffer size with setvbuf(), it uses a default if you don't use this function. There's no buffering in the application when you use WriteFile(), output is buffered in the operating system's file system cache. Immune from abrupt app aborts.
You'll have to call fflush() to achieve the same.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With