Jeff King wrote: >> --- a/wrapper.c >> +++ b/wrapper.c >> @@ -318,8 +318,10 @@ ssize_t read_in_full(int fd, void *buf, size_t count) >> ssize_t loaded = xread(fd, p, count); >> if (loaded < 0) >> return -1; >> - if (loaded == 0) >> + if (loaded == 0) { >> + errno = EILSEQ; >> return total; >> + } > > If I do this: > > errno = 0; > read_in_full(fd, buf, sizeof(buf)); > if (errno) > die_errno("oops"); > > then we'll claim an error, even though there was none (remember that > it's only an error for _some_ callers to not read the whole length). > > This may be sufficiently odd that we don't need to care about it. There > are some calls (like strtoul) which require this kind of clear-and-check > strategy with errno, but in general we frown on it for calls like > read(). Correct. Actually more than "frown on": except for with the few calls like strtoul that are advertised to work this way, POSIX does not make the guarantee the above code would rely on, at all. So it's not just frowned upon: it's so unportable that the standard calls it out as something that won't work. > We could also introduce a better helper like this: > > int read_exactly(int fd, void *buf, size_t count) > { > ssize_t ret = read_in_full(fd, buf, count); > if (ret < 0) > return -1; > if (ret != count) { > errno = EILSEQ; > return -1; > } > return 0; > } > > Then we know that touching errno always coincides with an error return. > And it's shorter to check "< 0" compared to "!= count" in the caller. > But of course a caller which wants to distinguish the two cases for its > error messages then has to look at errno: That sounds nice, but it doesn't solve the original problem of callers using read_in_full that way. Thanks, Jonathan