diff options
Diffstat (limited to 'camel/camel-stream-fs.c')
-rw-r--r-- | camel/camel-stream-fs.c | 118 |
1 files changed, 68 insertions, 50 deletions
diff --git a/camel/camel-stream-fs.c b/camel/camel-stream-fs.c index 63c1b2eae0..6bc10427e1 100644 --- a/camel/camel-stream-fs.c +++ b/camel/camel-stream-fs.c @@ -216,47 +216,55 @@ stream_read (CamelStream *stream, char *buffer, size_t n) CamelSeekableStream *seekable = CAMEL_SEEKABLE_STREAM (stream); ssize_t nread; int cancel_fd; - + if (camel_operation_cancel_check(NULL)) { errno = EINTR; return -1; } - + if (seekable->bound_end != CAMEL_STREAM_UNBOUND) n = MIN (seekable->bound_end - seekable->position, n); - + cancel_fd = camel_operation_cancel_fd(NULL); if (cancel_fd == -1) { do { nread = read (stream_fs->fd, buffer, n); - } while (nread == -1 && errno == EINTR); + } while (nread == -1 && (errno == EINTR || errno == EAGAIN)); } else { fd_set rdset; int error, flags, fdmax; - - flags = fcntl(stream_fs->fd, F_GETFL); - fcntl(stream_fs->fd, F_SETFL, flags | O_NONBLOCK); - FD_ZERO(&rdset); - FD_SET(stream_fs->fd, &rdset); - FD_SET(cancel_fd, &rdset); - fdmax = MAX(stream_fs->fd, cancel_fd)+1; - select(fdmax, &rdset, 0, 0, NULL); - if (FD_ISSET(cancel_fd, &rdset)) { - fcntl(stream_fs->fd, F_SETFL, flags); - errno = EINTR; - return -1; - } - nread = read(stream_fs->fd, buffer, n); + + flags = fcntl (stream_fs->fd, F_GETFL); + fcntl (stream_fs->fd, F_SETFL, flags | O_NONBLOCK); + + do { + FD_ZERO (&rdset); + FD_SET (stream_fs->fd, &rdset); + FD_SET (cancel_fd, &rdset); + fdmax = MAX (stream_fs->fd, cancel_fd) + 1; + + select (fdmax, &rdset, 0, 0, NULL); + if (FD_ISSET (cancel_fd, &rdset)) { + fcntl (stream_fs->fd, F_SETFL, flags); + errno = EINTR; + return -1; + } + + do { + nread = read (stream_fs->fd, buffer, n); + } while (nread == -1 && errno == EAGAIN); + } while (nread == -1 && errno == EAGAIN); + error = errno; - fcntl(stream_fs->fd, F_SETFL, flags); + fcntl (stream_fs->fd, F_SETFL, flags); errno = error; } - + if (nread > 0) seekable->position += nread; else if (nread == 0) stream->eos = TRUE; - + return nread; } @@ -265,59 +273,69 @@ stream_write (CamelStream *stream, const char *buffer, size_t n) { CamelStreamFs *stream_fs = CAMEL_STREAM_FS (stream); CamelSeekableStream *seekable = CAMEL_SEEKABLE_STREAM (stream); - ssize_t v, written = 0; + ssize_t w, written = 0; int cancel_fd; - + if (camel_operation_cancel_check(NULL)) { errno = EINTR; return -1; } - + if (seekable->bound_end != CAMEL_STREAM_UNBOUND) n = MIN (seekable->bound_end - seekable->position, n); - + cancel_fd = camel_operation_cancel_fd(NULL); if (cancel_fd == -1) { do { do { - v = write (stream_fs->fd, buffer+written, n-written); - } while (v == -1 && errno == EINTR); - - if (v > 0) - written += v; - } while (v != -1 && written < n); + w = write (stream_fs->fd, buffer + written, n - written); + } while (w == -1 && (errno == EINTR || errno == EAGAIN)); + + if (w > 0) + written += w; + } while (w != -1 && written < n); } else { fd_set rdset, wrset; int error, flags, fdmax; - - flags = fcntl(stream_fs->fd, F_GETFL); - fcntl(stream_fs->fd, F_SETFL, flags | O_NONBLOCK); - fdmax = MAX(stream_fs->fd, cancel_fd)+1; + + flags = fcntl (stream_fs->fd, F_GETFL); + fcntl (stream_fs->fd, F_SETFL, flags | O_NONBLOCK); + + fdmax = MAX (stream_fs->fd, cancel_fd)+1; do { - FD_ZERO(&rdset); - FD_ZERO(&wrset); - FD_SET(stream_fs->fd, &wrset); - FD_SET(cancel_fd, &rdset); - select(fdmax, &rdset, &wrset, 0, NULL); - if (FD_ISSET(cancel_fd, &rdset)) { - fcntl(stream_fs->fd, F_SETFL, flags); + FD_ZERO (&rdset); + FD_ZERO (&wrset); + FD_SET (stream_fs->fd, &wrset); + FD_SET (cancel_fd, &rdset); + + select (fdmax, &rdset, &wrset, 0, NULL); + if (FD_ISSET (cancel_fd, &rdset)) { + fcntl (stream_fs->fd, F_SETFL, flags); errno = EINTR; return -1; } - v = write(stream_fs->fd, buffer+written, n-written); - if (v>0) - written += v; - } while (v != -1 && written < n); + + do { + w = write (stream_fs->fd, buffer + written, n - written); + } while (w == -1 && errno == EINTR); + + if (w == -1) { + if (errno == EAGAIN) + continue; + } else + written += w; + } while (w != -1 && written < n); + error = errno; - fcntl(stream_fs->fd, F_SETFL, flags); + fcntl (stream_fs->fd, F_SETFL, flags); errno = error; } - + if (written > 0) seekable->position += written; - else if (v == -1) + else if (w == -1) return -1; - + return written; } |