Re: Solaris cloning woes partly diagnosed
- From
Linus Torvalds <torvalds@osdl.org>
- Date
- Apr 3, 2006, 03:06 UTC
- Message-ID
- <Pine.LNX.4.64.0604021951310.23419@g5.osdl.org>
- In-Reply-To
- <Pine.LNX.4.64.0604021159110.3050@g5.osdl.org>
On Sun, 2 Apr 2006, Linus Torvalds wrote:
Show 13 quoted lines
>
> - while (fgets(line, sizeof(line), stdin) != NULL) {
> + for (;;) {
> unsigned char sha1[20];
> +
> + if (!fgets(line, sizeof(line), stdin)) {
> + if (feof(stdin))
> + break;
> + if (!ferror(stdin))
> + die("fgets returned NULL, not EOF, not error!");
> + if (errno == EINTR)
> + continue;
> + die("fgets: %s", strerror(errno));While it shouldn't actually matter, I just realized that this incredibly anal sequence isn't actually quite anal enough, sinceit really should have a "clearerr(stdin)" for the continue case when we ignore the EINTR thing.
Otherwise, some stdio implementation might just decide to continue to return NULL from fgets(), since the error indicator is technically sticky. I don't know if they do so, but it's entirely possible.
So I'd almost suggest something like
char *safe_fgets(char *s, int size, FILE *stream)
{
for (;;) {
if (fgets(s, size, stream))
return s;
if (feof(stream))
return NULL;
if (!ferror(stream))
die("fgets returned NULL, not EOF, not error!");
if (errno != EINTR)
die("fgets: %s", strerror(errno));
clearerr(stream);
}
}which sbould then hopefully work as a sane fgets()-replacement for broken environments.
(And then we can just do
while (safe_fgets(..))
like normal people again, and not be afraid of strange stdio implementations).
Linus