1
0
mirror of https://github.com/janet-lang/janet synced 2024-06-26 07:03:16 +00:00

shell: Handle EINTR on long reads

Many system I/O operations can fail due to being interrupted by a
signal. In the REPL's case, this poses a problem because in most cases
it's assumed that a read error is not recoverable and is equivalent to
EOF. This, however, is not the case for EINTR, in which case the I/O
should be tried again.

This commit fixes the most egregious violations of this, notably the
line getters, which would otherwise make the REPL exit on any signal,
even if the signal was caught and processed outside the REPL's purview.
This commit is contained in:
paulsnar 2022-02-04 02:18:10 +02:00
parent 40ae2e812f
commit 06f2e81dd5
No known key found for this signature in database
GPG Key ID: 37155EB211976FC1

View File

@ -25,6 +25,7 @@
#endif
#include <janet.h>
#include <errno.h>
#ifdef _WIN32
#include <windows.h>
@ -75,6 +76,9 @@ static void simpleline(JanetBuffer *buffer) {
int c;
for (;;) {
c = fgetc(in);
if (c < 0 && !feof(in) && errno == EINTR) {
continue;
}
if (feof(in) || c < 0) {
break;
}
@ -112,7 +116,6 @@ https://github.com/antirez/linenoise/blob/master/linenoise.c
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <ctype.h>
#include <sys/stat.h>
@ -742,7 +745,11 @@ static int line() {
char c;
char seq[3];
if (read(STDIN_FILENO, &c, 1) <= 0) return -1;
int rc;
do {
rc = read(STDIN_FILENO, &c, 1);
} while (rc < 0 && errno == EINTR);
if (rc <= 0) return -1;
switch (c) {
default: