> > *Every* blocking fd operation should be followed by a check to > > see if the > > operation failed, succeeded, or partially succeeded. If it partially > > succeeded, it needs to be continued. If it failed, you need to > > check if the > > error is fatal or transient. If transient, you need to back off > > and retry. > > It has, sadly, always been this way. (Programs can get signals, > > debuggers > > can interrupt a system call, the unexpected happens.)
> Well, that's partly nonsense. The only error condition which is > always being > checked in correctly written software is EINTR - if you've got an > interrupt, > continue/retry the I/O. > Checking and retrying for EAGAIN is umm.. plain wrong. You'll get a nice > busywait eating 100% CPU this way, till the I/O actually happens, and will > get another the next try. I said back off and retry. > Checking I/Os for every possible weird condition is just non-productive. > > It's like this: > > if (fcntl(fd, F_SETFL, ~O_NONBLOCK) < 0) error_out(); > if (fcntl(fd, F_GETFL, 0) & O_NOBLOCK) ??? what to do? > while(do_something()) > if (fcntl(fd, F_GETFL, 0) & O_NOBLOCK) > if (fcntl(fd, F_SETFL, ~O_NONBLOCK) < 0) error_out(); > > (don't pay attention to ~O_NONBLOCK thing - it's wrong, but it's > used like that just to show the "idea" - which is to clear O_NONBLOCK) I agree that checking for a condition that there's no sane way to handle is non-productive. But here we're talking about testing for a condition that has been proven to happen and for which a sane way to handle it is obvious -- back off and retry. > Which is a complete nonsense. It's either set or cleared, and once > set or cleared it should stay that way, period. Until the app changes > it again. Until anything with access to it changes it. > >> Worse, it cannot be worked around by dup() because duped fds > >> are still sharing O_NONBLOCK. How can I work around this? > > > > If this causes your code a problem, your code is broken. What > > does your code > > With dup() - maybe. But definitely NOT with fork(). With 'fork', you either give the other process the file descriptor or you share it. Any shared resource requires cooperation for sane results. > > currently do if it gets a non-fatal error from a blocking > > operation? If it > > does anything other than back off and retry, it's mishandling > > the condition. > Retrying I/O in case of EAGAIN is *wrong*. See above. You missed the "back off" part. DS - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/