[PATCH] prevent retries on fclose/fflush after write errors
dalias at aerifal.cx
Tue Mar 13 22:44:19 UTC 2012
On Tue, Mar 13, 2012 at 11:15:32PM +0100, Laurent Bercot wrote:
> >>> alarm(1);
> >>> fgets(buf, sizeof buf, f);
> > I was assuming the old standard idiom of installing a do-nothing
> > signal handler (without SA_RESTART) for SIGALRM so that fgets would
> > return with an error and the program could proceed.
> Ugh. I get it. In this case, then, *of course* you want to get EINTR
> reported to the user. And I already agreed that the libc should not
> safe-wrap system calls, so yes, naturally fgets should be interrupted.
Yes, this is the sort of usage case I was talking about all along, and
as far as I can tell, really the only reason anybody would ever want
EINTR in the first place. Otherwise it's just a nuisance.
> But honestly, this seems to me like the lazy (in a bad sense) way to
> write such a program; the right way would be to write a little
> asynchronous select/poll loop with a timeout of 1 second and a reading
> event on fd 0. The main reason why the latter paradigm isn't used as
> much is that stdio doesn't handle partial reads and so is quite unusable
> in asynchronous loops - in other words, stdio sucks.
There are at least 3 ways to do it. You, and many people these days,
favor event-driven programming with select/poll/libevent/whatever.
This is certainly one reasonable design, but it tends to make things
that would otherwise be simple rather complicated, and precludes using
stdio. I wouldn't say this means stdio sucks; rather, it's just meant
for other types of programming.
The other 2 ways are the one I described (using EINTR) and threads
with thread cancellation as the method for getting out of blocked
situations. Both of these work quite well with stdio.
> Whenever I need to listen to signals as events (or, in the case of
> alarm(), as timeouts), I use a self-pipe and a select loop so I can
> listen to any number of events at the same time. It's a bit harder to
> program, but much more robust; the "blocking system calls + EINTR"
> paradigm is ad-hoc and error-prone. It can break so easily, for instance
> when your libc is misguided and safewraps around EINTR. ;)
Well I would call this not just misguided but wrong since POSIX
specifies that fgetc/fputc (and all other stdio functions defined in
terms of them) return failure with errno==EINTR for interrupting
More information about the uClibc