Trojan Horses

Dan Bernstein brnstnd at kramden.acf.nyu.edu
Fri Oct 26 07:49:57 AEST 1990


In article <1893 at necisa.ho.necisa.oz> boyd at necisa.ho.necisa.oz (Boyd Roberts) writes:
> In article <5238:Oct2322:14:3690 at kramden.acf.nyu.edu> brnstnd at kramden.acf.nyu.edu (Dan Bernstein) writes:
> >And if something is not documented as returning error X, and there's no
> >logical reason to expect it to, and there's no good way to handle the
> >error if it does come up?
> Dan, you twist and turn -- like a twisty turny thing.

You're the one trying to change the problem by generalizing it too far.
See below.

> A decent interface returns ok or error.  Now there may be multiple error
> classes, but all you want to distinguish is success or failure.  Failure
> is usually disaster, but in some cases you can act on the error type and
> try to recover.

This generalization isn't true. See below.

> What are you trying to say?  A new type of error has occured and because
> you aren't prepared for it you say ``there's no good way to handle [it]''.
> Are you saying that you treat it as success or do you just ignore it?

In the *particular* case of close(), I just ignore errors that I don't
know how to handle. After all, I use close() merely to indicate to the
system that I'm done with a descriptor. (That is what it's meant for---
right?)

If close() gives EINTR, it might not have completed. This is just like
any other system call. I know a good way to handle this: simply retry
the close(). The system is telling me ``whoops, I know you were giving
me an extra assertion to work with, but I was distracted---say it
again?''

If close() gives EBADF, my program (which I assume keeps proper track of
descriptors) has made an incorrect assumption about its external
environment. It might have been passed a closed stdin, for instance. In
most cases the right way to handle this error is to do nothing and
return success. Some programs might want to report the problem back to
the user, but there's no behavior that becomes undefined if they don't.

There is no reason that I have to handle either error. My goal is only
to give the system as much information as possible, so that it can pass
timely EOFs down pipes, free up the resources for the descriptor so that
I'll have more chances to open() later, etc.

Now let's take an error matching my quoted description. close() is not
documented as returning EDQUOT. There's no logical reason to expect it
to return EDQUOT---even if write()'s buffering weren't hidden below its
interface, it could easily return the error accurately. There's no good
way to handle EDQUOT if it comes up---even if I had some reason to
suspect that close() could return the error, I simply *cannot* replay
data that might have been buffered in the same file by a previous
process. Tell me: Why should I handle EDQUOT? Why should I interpret it
as some sort of error? Who benefits if I thrash about upon this error?

> Surely you mean that if you don't know how to handle a specific recovery
> (for some unspecified error type) it's still treated as failure?

Not at all. This might be true for calls that give me information, but
close() is not such a call. Do you check the return value of assert()?

---Dan



More information about the Comp.unix.internals mailing list