From fe1debbd60349a10e446fc4b039edd0d851cb552 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Fri, 28 Aug 2020 20:54:09 +0000 Subject: ignore EOF when EINTR, but not otherwise git-svn-id: svn://tug.org/texlive/trunk@56202 c570f23f-e606-0410-a88d-b1316a301751 --- Build/source/texk/web2c/lib/ChangeLog | 8 ++++++++ Build/source/texk/web2c/lib/texmfmp.c | 32 ++++++++++++++++++++++++++------ 2 files changed, 34 insertions(+), 6 deletions(-) (limited to 'Build/source/texk') 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 + + * 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 * 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. */ -- cgit v1.2.3