diff options
-rw-r--r-- | Build/source/texk/web2c/lib/ChangeLog | 8 | ||||
-rw-r--r-- | Build/source/texk/web2c/lib/texmfmp.c | 32 |
2 files changed, 34 insertions, 6 deletions
diff --git a/Build/source/texk/web2c/lib/ChangeLog b/Build/source/texk/web2c/lib/ChangeLog index 4d0a9dd6eb2..221273b2673 100644 --- a/Build/source/texk/web2c/lib/ChangeLog +++ b/Build/source/texk/web2c/lib/ChangeLog @@ -1,3 +1,11 @@ +2020-08-28 Karl Berry <karl@tug.org> + + * texmfmp.c (input_line): always clear errno before calling getc, + else an EINTR errno might persist, masking a real EOF. On the other + hand, loop as long as we have EOF && EINTR so we don't prematurely + stop reading characters. + https://tug.org/pipermail/tex-k/2020-August/003297.html + 2020-07-18 Karl Berry <karl@freefriends.org> * texmfmp.c: reformat so that all function return types and names diff --git a/Build/source/texk/web2c/lib/texmfmp.c b/Build/source/texk/web2c/lib/texmfmp.c index a6e9db18b6c..1502a113b8d 100644 --- a/Build/source/texk/web2c/lib/texmfmp.c +++ b/Build/source/texk/web2c/lib/texmfmp.c @@ -2498,13 +2498,33 @@ input_line (FILE *f) } } } -#endif +#endif /* WIN32 */ last = first; - while (last < bufsize && (i = getc (f)) != EOF && i != '\n' && i != '\r') - buffer[last++] = i; -#endif - - if (i == EOF && errno != EINTR && last == first) + do { + errno = 0; /* otherwise EINTR might wrongly persist */ + while (last < bufsize && (i = getc (f)) != EOF && i != '\n' && i != '\r') + buffer[last++] = i; + + /* The story on EINTR: because we tell libc to pass interrupts + through (see SA_INTERRUPT above), we have to make sure that we + check for and ignore EINTR when getc reads an EOF; hence the + outer do..while loop here (and a similar loop below). + + On the other hand, we have to make sure that we detect a real + EOF. Otherwise, for example, typing CTRL-C and then CTRL-D to the + ** prompt results in an infinite loop, because we + (input_line) would never return false. On glibc 2.28-10 (Debian + 10/buster), and probably other versions, errno is evidently not + cleared as a side effect of getc (and this is allowed). + Therefore we clear errno before calling getc above. + + Original report (thread following has many irrelevant diversions): + https://tug.org/pipermail/tex-k/2020-August/003297.html */ + + } while (i == EOF && errno == EINTR); +#endif /* not IS_pTeX */ + + if (i == EOF && last == first) return false; /* We didn't get the whole line because our buffer was too small. */ |