RFR [8055421]: (fs) bad error handling in java.base/unix/native/libnio/fs/UnixNativeDispatcher.c
Ivan Gerasimov
ivan.gerasimov at oracle.com
Sat Aug 23 20:09:06 UTC 2014
On 23.08.2014 1:19, Martin Buchholz wrote:
> I worry more about the integrity of the output file than about the
> file descriptor.
> The big risk is that there is remaining buffered output that would be
> written using fflush, the attempt to write the buffered output fails
> with EINTR, and the resulting file is missing its last few bytes.
>
> In the real world, fclose probably doesn't encounter EINTR very often.
> If this was a real-world problem, I'd expect it to be a well known
> piece of Unix folklore.
>
I think that it's not seen often because SA_RESTART flag is set by
default for the signal handlers on most systems, so that the write
syscall is restarted automatically.
I tried (unsuccessfully) to reproduce the issue with the following program:
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <signal.h>
void my_sighandler(int) {
}
int main(int argc, char** argv) {
struct sigaction sa, sa1;
sa.sa_handler = my_sighandler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_INTERRUPT; // no SA_RESTART
if (sigaction(SIGINT, &sa, &sa1) == -1)
return -1;
while (1) {
int res, fd = dup(STDOUT_FILENO);
FILE* f = fdopen(fd, "a");
setvbuf(f, NULL, _IOFBF, BUFSIZ);
fputc('A', f);
do {
res = fflush(f);
} while (res == -1 && errno == EINTR);
fputc('\n', f);
fclose(f); // will it fail to flush, if interrupted?
}
return 0;
}
And I was signaling it in a loop with
$ while true; do kill -INT $procid; done;
If it had an issue with flushing the stream in fclose, it could have
printed more than one 'A's on one line.
But it stably prints one A on every line.
If we had a reproducible test case, we could see how to fix it.
But now I can't see how else we could break it.
Sincerely yours,
Ivan
More information about the nio-dev
mailing list