texlive[56202] Build/source/texk/web2c/lib: ignore EOF when EINTR,

commits+karl at tug.org commits+karl at tug.org
Fri Aug 28 22:54:09 CEST 2020


Revision: 56202
          http://tug.org/svn/texlive?view=revision&revision=56202
Author:   karl
Date:     2020-08-28 22:54:09 +0200 (Fri, 28 Aug 2020)
Log Message:
-----------
ignore EOF when EINTR, but not otherwise

Modified Paths:
--------------
    trunk/Build/source/texk/web2c/lib/ChangeLog
    trunk/Build/source/texk/web2c/lib/texmfmp.c

Modified: trunk/Build/source/texk/web2c/lib/ChangeLog
===================================================================
--- trunk/Build/source/texk/web2c/lib/ChangeLog	2020-08-28 20:53:29 UTC (rev 56201)
+++ trunk/Build/source/texk/web2c/lib/ChangeLog	2020-08-28 20:54:09 UTC (rev 56202)
@@ -1,3 +1,11 @@
+2020-08-28  Karl Berry  <karl at 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 at freefriends.org>
 
 	* texmfmp.c: reformat so that all function return types and names

Modified: trunk/Build/source/texk/web2c/lib/texmfmp.c
===================================================================
--- trunk/Build/source/texk/web2c/lib/texmfmp.c	2020-08-28 20:53:29 UTC (rev 56201)
+++ trunk/Build/source/texk/web2c/lib/texmfmp.c	2020-08-28 20:54:09 UTC (rev 56202)
@@ -2498,13 +2498,33 @@
       }
     }
   }
-#endif
+#endif /* WIN32 */
   last = first;
-  while (last < bufsize && (i = getc (f)) != EOF && i != '\n' && i != '\r')
-    buffer[last++] = i;
-#endif
+  do {
+    errno = 0; /* otherwise EINTR might wrongly persist */
+    while (last < bufsize && (i = getc (f)) != EOF && i != '\n' && i != '\r')
+      buffer[last++] = i;
 
-  if (i == EOF && errno != EINTR && last == first)
+    /* 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.  */



More information about the tex-live-commits mailing list.