[PATCH] prevent retries on fclose/fflush after write errors

Rich Felker dalias at aerifal.cx
Tue Mar 13 18:22:22 UTC 2012


On Tue, Mar 13, 2012 at 06:59:03PM +0100, Laurent Bercot wrote:
> > There is no reason to "protect" reads against EINTR because EINTR
> > cannot happen unless the application specifically chooses for it to
> > happen (by installing a non-restarting signal handler). EINTR does not
> > just randomly happen.
> 
>  It can, if you take the standard literally. I agree that you *should*
> be able to assume that unblockable signals have SA_RESTART behaviour,
> that would simplify Unix programming a whole lot. But as of today, you
> can't, and I'd rather be on the safe side.

I'd have to go back and look at the (disorganized) language about it
in the standard, but you may be right about the lack of a strict
requirement. I would consider this a flaw in the standard since it
largely prevents using EINTR in any useful way. There's a similar bug
in the statement of pthread cancellation behavior that makes it so
implementations are allowed (and glibc/uClibc exercise this
allowance!) to leak resources or worse (corrupt fd state) randomly
when cancellation is performed; allowing implementations of such low
quality essentially makes the feature unusable. This should really all
be documented well and submitted as defect reports...

> > My claim is that code doing such protection is wrong and harmful to
> > begin with.
> 
>  I disagree, because it has its uses. But I think we can agree that it
> is wrong to do it *in the libc*. The programmer should have the choice
> to handle EINTR himself.

In some places in a program you might know it's essential to complete
the operation and not lose data, in which case you're right, but this
sort of situation will require specific contracts between the callee
and caller about what to do. In general, I feel like the appropriate
response to EINTR in the absence of a contract with the caller is to
assume that when the caller has arranged for EINTR to happen, the
caller wants you to stop when interrupted.

> > Think of programs that do something like:
> > alarm(1);
> > fgets(buf, sizeof buf, f);
> 
>  SIGALRM is raised. SIGALRM isn't caught. SIGALRM kills the process,
> even if it was blocking on a safe_read() function. Where's the problem?

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.

Rich


More information about the uClibc mailing list