Merge #7633 'Retry fgets on EINTR'

closes #7632
This commit is contained in:
Justin M. Keyes 2017-11-26 21:17:35 +01:00 committed by GitHub
commit a043899ba2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 59 additions and 16 deletions

View File

@ -3199,8 +3199,14 @@ static char_u *get_one_sourceline(struct source_cookie *sp)
ga_grow(&ga, 120); ga_grow(&ga, 120);
buf = (char_u *)ga.ga_data; buf = (char_u *)ga.ga_data;
retry:
errno = 0;
if (fgets((char *)buf + ga.ga_len, ga.ga_maxlen - ga.ga_len, if (fgets((char *)buf + ga.ga_len, ga.ga_maxlen - ga.ga_len,
sp->fp) == NULL) { sp->fp) == NULL) {
if (errno == EINTR) {
goto retry;
}
break; break;
} }
len = ga.ga_len + (int)STRLEN(buf + ga.ga_len); len = ga.ga_len + (int)STRLEN(buf + ga.ga_len);

View File

@ -4443,22 +4443,32 @@ char *modname(const char *fname, const char *ext, bool prepend_dot)
/// @return true for end-of-file. /// @return true for end-of-file.
bool vim_fgets(char_u *buf, int size, FILE *fp) FUNC_ATTR_NONNULL_ALL bool vim_fgets(char_u *buf, int size, FILE *fp) FUNC_ATTR_NONNULL_ALL
{ {
char *eof; char *retval;
#define FGETS_SIZE 200
char tbuf[FGETS_SIZE];
assert(size > 0);
buf[size - 2] = NUL; buf[size - 2] = NUL;
eof = fgets((char *)buf, size, fp);
if (buf[size - 2] != NUL && buf[size - 2] != '\n') {
buf[size - 1] = NUL; /* Truncate the line */
/* Now throw away the rest of the line: */ do {
errno = 0;
retval = fgets((char *)buf, size, fp);
} while (retval == NULL && errno == EINTR);
if (buf[size - 2] != NUL && buf[size - 2] != '\n') {
char tbuf[200];
buf[size - 1] = NUL; // Truncate the line.
// Now throw away the rest of the line:
do { do {
tbuf[FGETS_SIZE - 2] = NUL; tbuf[sizeof(tbuf) - 2] = NUL;
ignoredp = fgets((char *)tbuf, FGETS_SIZE, fp); errno = 0;
} while (tbuf[FGETS_SIZE - 2] != NUL && tbuf[FGETS_SIZE - 2] != '\n'); retval = fgets((char *)tbuf, sizeof(tbuf), fp);
if (retval == NULL && errno != EINTR) {
break;
}
} while (tbuf[sizeof(tbuf) - 2] != NUL && tbuf[sizeof(tbuf) - 2] != '\n');
} }
return eof == NULL; return retval ? false : feof(fp);
} }
/// Read 2 bytes from "fd" and turn them into an int, MSB first. /// Read 2 bytes from "fd" and turn them into an int, MSB first.

View File

@ -553,9 +553,15 @@ static int cs_cnt_matches(size_t idx)
char *buf = xmalloc(CSREAD_BUFSIZE); char *buf = xmalloc(CSREAD_BUFSIZE);
for (;; ) { for (;; ) {
errno = 0;
if (!fgets(buf, CSREAD_BUFSIZE, csinfo[idx].fr_fp)) { if (!fgets(buf, CSREAD_BUFSIZE, csinfo[idx].fr_fp)) {
if (feof(csinfo[idx].fr_fp)) if (errno == EINTR) {
continue;
}
if (feof(csinfo[idx].fr_fp)) {
errno = EIO; errno = EIO;
}
cs_reading_emsg(idx); cs_reading_emsg(idx);
@ -1380,9 +1386,16 @@ static char *cs_parse_results(size_t cnumber, char *buf, int bufsize,
char *p; char *p;
char *name; char *name;
retry:
errno = 0;
if (fgets(buf, bufsize, csinfo[cnumber].fr_fp) == NULL) { if (fgets(buf, bufsize, csinfo[cnumber].fr_fp) == NULL) {
if (feof(csinfo[cnumber].fr_fp)) if (errno == EINTR) {
goto retry;
}
if (feof(csinfo[cnumber].fr_fp)) {
errno = EIO; errno = EIO;
}
cs_reading_emsg(cnumber); cs_reading_emsg(cnumber);

View File

@ -570,7 +570,12 @@ static int qf_get_next_file_line(qfstate_T *state)
{ {
size_t growbuflen; size_t growbuflen;
retry:
errno = 0;
if (fgets((char *)IObuff, IOSIZE, state->fd) == NULL) { if (fgets((char *)IObuff, IOSIZE, state->fd) == NULL) {
if (errno == EINTR) {
goto retry;
}
return QF_END_OF_INPUT; return QF_END_OF_INPUT;
} }
@ -590,8 +595,12 @@ static int qf_get_next_file_line(qfstate_T *state)
growbuflen = state->linelen; growbuflen = state->linelen;
for (;;) { for (;;) {
errno = 0;
if (fgets((char *)state->growbuf + growbuflen, if (fgets((char *)state->growbuf + growbuflen,
(int)(state->growbufsiz - growbuflen), state->fd) == NULL) { (int)(state->growbufsiz - growbuflen), state->fd) == NULL) {
if (errno == EINTR) {
continue;
}
break; break;
} }
state->linelen = STRLEN(state->growbuf + growbuflen); state->linelen = STRLEN(state->growbuf + growbuflen);
@ -612,9 +621,14 @@ static int qf_get_next_file_line(qfstate_T *state)
while (discard) { while (discard) {
// The current line is longer than LINE_MAXLEN, continue reading but // The current line is longer than LINE_MAXLEN, continue reading but
// discard everything until EOL or EOF is reached. // discard everything until EOL or EOF is reached.
if (fgets((char *)IObuff, IOSIZE, state->fd) == NULL errno = 0;
|| STRLEN(IObuff) < IOSIZE - 1 if (fgets((char *)IObuff, IOSIZE, state->fd) == NULL) {
|| IObuff[IOSIZE - 1] == '\n') { if (errno == EINTR) {
continue;
}
break;
}
if (STRLEN(IObuff) < IOSIZE - 1 || IObuff[IOSIZE - 1] == '\n') {
break; break;
} }
} }