diff options
-rw-r--r-- | camel/ChangeLog | 10 | ||||
-rw-r--r-- | camel/camel-stream-fs.c | 118 | ||||
-rw-r--r-- | camel/camel-tcp-stream-raw.c | 88 |
3 files changed, 139 insertions, 77 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog index 79b420dfad..5d992ada5f 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,3 +1,13 @@ +2001-10-24 Jeffrey Stedfast <fejj@ximian.com> + + * camel-stream-fs.c (stream_read): Same as in the TcpStreamRaw code. + (stream_write): And again here... + + * camel-tcp-stream-raw.c (stream_read): Handle the EAGAIN error + case as well. + (stream_write): Same here, this might fix the SMTP truncation + thing? I hope? + 2001-10-23 Dan Winship <danw@ximian.com> * camel-mime-utils.c (mail_list_magic): Remove an extra * in one 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; } diff --git a/camel/camel-tcp-stream-raw.c b/camel/camel-tcp-stream-raw.c index 34ba1446c5..5a6c8bca3c 100644 --- a/camel/camel-tcp-stream-raw.c +++ b/camel/camel-tcp-stream-raw.c @@ -109,6 +109,35 @@ camel_tcp_stream_raw_get_type (void) } +#ifdef SIMULATE_FLAKY_NETWORK +static ssize_t +tcp_write (int fd, char *buffer, size_t buflen) +{ + size_t len = buflen; + int val; + + val = 1 + (int) (10.0 * rand () / (RAND_MAX + 1.0)); + + switch (val) { + case 1: + errno = EINTR; + return -1; + case 2: + errno = EAGAIN; + return -1; + case 3: + len = 1 + (size_t) (buflen * rand () / (RAND_MAX + 1.0)); + /* fall through... */ + default: + return write (fd, buffer, len); + } +} +#else +#define tcp_write(fd, buf, len) write (fd, buf, len) +#endif /* SIMULATE_FLAKY_NETWORK */ + + + /** * camel_tcp_stream_raw_new: * @@ -130,8 +159,7 @@ stream_read (CamelStream *stream, char *buffer, size_t n) CamelTcpStreamRaw *tcp_stream_raw = CAMEL_TCP_STREAM_RAW (stream); ssize_t nread; int cancel_fd; - int saveerrno; - + if (camel_operation_cancel_check (NULL)) { errno = EINTR; return -1; @@ -141,32 +169,35 @@ stream_read (CamelStream *stream, char *buffer, size_t n) if (cancel_fd == -1) { do { nread = read (tcp_stream_raw->sockfd, buffer, n); - } while (nread == -1 && errno == EINTR); + } while (nread == -1 && (errno == EINTR || errno == EAGAIN)); } else { - int flags, fdmax; + int error, flags, fdmax; fd_set rdset; flags = fcntl (tcp_stream_raw->sockfd, F_GETFL); fcntl (tcp_stream_raw->sockfd, F_SETFL, flags | O_NONBLOCK); - FD_ZERO (&rdset); - FD_SET (tcp_stream_raw->sockfd, &rdset); - FD_SET (cancel_fd, &rdset); - fdmax = MAX (tcp_stream_raw->sockfd, cancel_fd) + 1; - - select (fdmax, &rdset, 0, 0, NULL); - if (FD_ISSET (cancel_fd, &rdset)) { - fcntl (tcp_stream_raw->sockfd, F_SETFL, flags); - errno = EINTR; - return -1; - } - do { - nread = read (tcp_stream_raw->sockfd, buffer, n); - } while (nread == -1 && errno == EINTR); - saveerrno = errno; + FD_ZERO (&rdset); + FD_SET (tcp_stream_raw->sockfd, &rdset); + FD_SET (cancel_fd, &rdset); + fdmax = MAX (tcp_stream_raw->sockfd, cancel_fd) + 1; + + select (fdmax, &rdset, 0, 0, NULL); + if (FD_ISSET (cancel_fd, &rdset)) { + fcntl (tcp_stream_raw->sockfd, F_SETFL, flags); + errno = EINTR; + return -1; + } + + do { + nread = read (tcp_stream_raw->sockfd, buffer, n); + } while (nread == -1 && errno == EINTR); + } while (nread == -1 && errno == EAGAIN); + + error = errno; fcntl (tcp_stream_raw->sockfd, F_SETFL, flags); - errno = saveerrno; + errno = error; } return nread; @@ -179,7 +210,7 @@ stream_write (CamelStream *stream, const char *buffer, size_t n) ssize_t w, written = 0; int cancel_fd; int saveerrno; - + if (camel_operation_cancel_check (NULL)) { errno = EINTR; return -1; @@ -189,9 +220,9 @@ stream_write (CamelStream *stream, const char *buffer, size_t n) if (cancel_fd == -1) { do { do { - w = write (tcp_stream_raw->sockfd, buffer+written, n-written); - } while (w == -1 && errno == EINTR); - + w = tcp_write (tcp_stream_raw->sockfd, buffer + written, n - written); + } while (w == -1 && (errno == EINTR || errno == EAGAIN)); + if (w > 0) written += w; } while (w != -1 && written < n); @@ -217,10 +248,13 @@ stream_write (CamelStream *stream, const char *buffer, size_t n) } do { - w = write (tcp_stream_raw->sockfd, buffer + written, n - written); + w = tcp_write (tcp_stream_raw->sockfd, buffer + written, n - written); } while (w == -1 && errno == EINTR); - - if (w > 0) + + if (w == -1) { + if (errno == EAGAIN) + continue; + } else written += w; } while (w != -1 && written < n); |