From: Timo Sirainen Date: Wed, 4 Oct 2017 12:08:07 +0000 (+0300) Subject: lib: istream-file/unix - don't ignore EINTR for blocking istream reads X-Git-Tag: 2.3.0.rc1~914 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=03915cfec4eb1b5a65e5b6b676c8f4151bc80351;p=thirdparty%2Fdovecot%2Fcore.git lib: istream-file/unix - don't ignore EINTR for blocking istream reads Just fail the istream read entirely. Although there's a small possibility that this interrupt was unwanted and should be retried, it's more likely that a blocking istream is hanging and admin wants to stop the process. If the EINTR is ignored all the time, it's not possible to abort a blocking read with ^C or anything else than SIGKILL. --- diff --git a/src/lib/istream-file.c b/src/lib/istream-file.c index a15af40b13..e002146c21 100644 --- a/src/lib/istream-file.c +++ b/src/lib/istream-file.c @@ -58,20 +58,18 @@ ssize_t i_stream_file_read(struct istream_private *stream) } offset = stream->istream.v_offset + (stream->pos - stream->skip); - do { - if (fstream->file) { - ret = pread(stream->fd, stream->w_buffer + stream->pos, - size, offset); - } else if (fstream->seen_eof) { - /* don't try to read() again. EOF from keyboard (^D) - requires this to work right. */ - ret = 0; - } else { - ret = read(stream->fd, stream->w_buffer + stream->pos, - size); - } - } while (unlikely(ret < 0 && errno == EINTR && - stream->istream.blocking)); + + if (fstream->file) { + ret = pread(stream->fd, stream->w_buffer + stream->pos, + size, offset); + } else if (fstream->seen_eof) { + /* don't try to read() again. EOF from keyboard (^D) + requires this to work right. */ + ret = 0; + } else { + ret = read(stream->fd, stream->w_buffer + stream->pos, + size); + } if (ret == 0) { /* EOF */ @@ -81,8 +79,8 @@ ssize_t i_stream_file_read(struct istream_private *stream) } if (unlikely(ret < 0)) { - if (errno == EINTR || errno == EAGAIN) { - i_assert(!stream->istream.blocking); + if ((errno == EINTR || errno == EAGAIN) && + !stream->istream.blocking) { ret = 0; } else { i_assert(errno != 0); diff --git a/src/lib/istream-unix.c b/src/lib/istream-unix.c index 3d79bedf9c..ce9b0195a2 100644 --- a/src/lib/istream-unix.c +++ b/src/lib/istream-unix.c @@ -34,12 +34,8 @@ static ssize_t i_stream_unix_read(struct istream_private *stream) if (!i_stream_try_alloc(stream, 1, &size)) return -2; - do { - ret = fd_read(stream->fd, - stream->w_buffer + stream->pos, size, - &ustream->read_fd); - } while (unlikely(ret < 0 && errno == EINTR && - stream->istream.blocking)); + ret = fd_read(stream->fd, stream->w_buffer + stream->pos, size, + &ustream->read_fd); if (ustream->read_fd != -1) ustream->next_read_fd = FALSE; @@ -51,8 +47,8 @@ static ssize_t i_stream_unix_read(struct istream_private *stream) } if (unlikely(ret < 0)) { - if (errno == EINTR || errno == EAGAIN) { - i_assert(!stream->istream.blocking); + if ((errno == EINTR || errno == EAGAIN) && + !stream->istream.blocking) { return 0; } else { i_assert(errno != 0);