From 03915cfec4eb1b5a65e5b6b676c8f4151bc80351 Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Wed, 4 Oct 2017 15:08:07 +0300 Subject: [PATCH] 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. --- src/lib/istream-file.c | 30 ++++++++++++++---------------- src/lib/istream-unix.c | 12 ++++-------- 2 files changed, 18 insertions(+), 24 deletions(-) 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); -- 2.47.3