summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/lib
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2020-08-28 20:54:09 +0000
committerKarl Berry <karl@freefriends.org>2020-08-28 20:54:09 +0000
commitfe1debbd60349a10e446fc4b039edd0d851cb552 (patch)
tree8db66d999fc051ff4c11145ba952326556c63cc6 /Build/source/texk/web2c/lib
parent55137b192a5c61251a90cdc55ac41554d75b3967 (diff)
ignore EOF when EINTR, but not otherwise
git-svn-id: svn://tug.org/texlive/trunk@56202 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/web2c/lib')
-rw-r--r--Build/source/texk/web2c/lib/ChangeLog8
-rw-r--r--Build/source/texk/web2c/lib/texmfmp.c32
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. */