diff options
-rw-r--r-- | camel/ChangeLog | 12 | ||||
-rw-r--r-- | camel/camel-stream-fs.c | 66 | ||||
-rw-r--r-- | camel/camel-tcp-stream-raw.c | 99 |
3 files changed, 111 insertions, 66 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog index 447a2f2e14..5e7e5220dd 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,5 +1,17 @@ 2002-05-02 Jeffrey Stedfast <fejj@ximian.com> + * camel-stream-fs.c (stream_read): Same fix as the tcp stream. + (stream_write): Again here. Just like tcp stream's stream_write(), + also make sure to save errno before calling fcntl to restore the + fd flags. + + * camel-tcp-stream-raw.c (stream_read): Handle EINTR errors for + select(). + (stream_write): Same and also preserve errno when setting the fd + flags back. If w == -1, return -1. + +2002-05-02 Jeffrey Stedfast <fejj@ximian.com> + * camel-mime-utils.c (header_decode_mailbox): Fixed the fix for stupidly-broken-mailer bug #5 to work when multiple unescaped characters were in a row. Fixes bug #24140. diff --git a/camel/camel-stream-fs.c b/camel/camel-stream-fs.c index b2eb9d5050..a1d7cbaca3 100644 --- a/camel/camel-stream-fs.c +++ b/camel/camel-stream-fs.c @@ -242,16 +242,20 @@ stream_read (CamelStream *stream, char *buffer, size_t n) 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 = -1; + if (select (fdmax, &rdset, 0, 0, NULL) != -1) { + 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); + } else if (errno == EINTR) { + errno = EAGAIN; } - - do { - nread = read (stream_fs->fd, buffer, n); - } while (nread == -1 && errno == EAGAIN); } while (nread == -1 && errno == EAGAIN); error = errno; @@ -307,31 +311,37 @@ stream_write (CamelStream *stream, const char *buffer, size_t n) 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; - } - - do { - w = write (stream_fs->fd, buffer + written, n - written); - } while (w == -1 && errno == EINTR); - - if (w == -1) { - if (errno == EAGAIN) { - w = 0; - } else { - error = errno; + w = -1; + if (select (fdmax, &rdset, &wrset, 0, NULL) != -1) { + if (FD_ISSET (cancel_fd, &rdset)) { fcntl (stream_fs->fd, F_SETFL, flags); - errno = error; + errno = EINTR; return -1; } - } else - written += w; + + do { + w = write (stream_fs->fd, buffer + written, n - written); + } while (w == -1 && errno == EINTR); + + if (w == -1) { + if (errno == EAGAIN) { + w = 0; + } else { + error = errno; + fcntl (stream_fs->fd, F_SETFL, flags); + errno = error; + return -1; + } + } else + written += w; + } else if (errno == EINTR) { + w = 0; + } } while (w != -1 && written < n); + error = errno; fcntl (stream_fs->fd, F_SETFL, flags); + errno = error; } if (written > 0) diff --git a/camel/camel-tcp-stream-raw.c b/camel/camel-tcp-stream-raw.c index d8aef35079..5f5f1b8bf6 100644 --- a/camel/camel-tcp-stream-raw.c +++ b/camel/camel-tcp-stream-raw.c @@ -32,6 +32,8 @@ #include <fcntl.h> #include <errno.h> #include <string.h> +#include <time.h> + #include "camel-tcp-stream-raw.h" #include "camel-operation.h" @@ -259,16 +261,20 @@ stream_read (CamelStream *stream, char *buffer, size_t n) 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; + nread = -1; + if (select (fdmax, &rdset, 0, 0, NULL) != -1) { + 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); + } else if (errno == EINTR) { + errno = EAGAIN; } - - do { - nread = read (tcp_stream_raw->sockfd, buffer, n); - } while (nread == -1 && errno == EINTR); } while (nread == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)); error = errno; @@ -315,33 +321,42 @@ stream_write (CamelStream *stream, const char *buffer, size_t n) FD_SET (tcp_stream_raw->sockfd, &wrset); FD_SET (cancel_fd, &rdset); - select (fdmax, &rdset, &wrset, 0, NULL); - if (FD_ISSET (cancel_fd, &rdset)) { - fcntl (tcp_stream_raw->sockfd, F_SETFL, flags); - errno = EINTR; - return -1; - } - - do { - w = write (tcp_stream_raw->sockfd, buffer + written, n - written); - } while (w == -1 && errno == EINTR); - - if (w == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) { - w = 0; - } else { - error = errno; + w = -1; + if (select (fdmax, &rdset, &wrset, 0, NULL) != -1) { + if (FD_ISSET (cancel_fd, &rdset)) { fcntl (tcp_stream_raw->sockfd, F_SETFL, flags); - errno = error; + errno = EINTR; return -1; } - } else - written += w; + + do { + w = write (tcp_stream_raw->sockfd, buffer + written, n - written); + } while (w == -1 && errno == EINTR); + + if (w == -1) { + if (errno == EAGAIN || errno == EWOULDBLOCK) { + w = 0; + } else { + error = errno; + fcntl (tcp_stream_raw->sockfd, F_SETFL, flags); + errno = error; + return -1; + } + } else + written += w; + } else if (errno == EINTR) { + w = 0; + } } while (w != -1 && written < n); + error = errno; fcntl (tcp_stream_raw->sockfd, F_SETFL, flags); + errno = error; } + if (w == -1) + return -1; + return written; } @@ -396,13 +411,14 @@ socket_connect (struct hostent *h, int port) return fd; } else { + int flags, fdmax, status; fd_set rdset, wrset; - int flags, fdmax; + time_t timeout, now; flags = fcntl (fd, F_GETFL); fcntl (fd, F_SETFL, flags | O_NONBLOCK); - ret = connect (fd, (struct sockaddr *)&sin, sizeof (sin)); + ret = connect (fd, (struct sockaddr *) &sin, sizeof (sin)); if (ret == 0) { fcntl (fd, F_SETFL, flags); return fd; @@ -413,15 +429,22 @@ socket_connect (struct hostent *h, int port) return -1; } - FD_ZERO (&rdset); - FD_ZERO (&wrset); - FD_SET (fd, &wrset); - FD_SET (cancel_fd, &rdset); - fdmax = MAX (fd, cancel_fd) + 1; - tv.tv_usec = 0; - tv.tv_sec = 60 * 4; + now = time (NULL); + timeout = now + 60 * 4; + do { + FD_ZERO (&rdset); + FD_ZERO (&wrset); + FD_SET (fd, &wrset); + FD_SET (cancel_fd, &rdset); + fdmax = MAX (fd, cancel_fd) + 1; + tv.tv_sec = timeout - now; + tv.tv_usec = 0; + + status = select (fdmax, &rdset, &wrset, 0, &tv); + now = time (NULL); + } while (now < timeout && status == -1 && errno == EINTR); - if (select (fdmax, &rdset, &wrset, 0, &tv) <= 0) { + if (status <= 0) { close (fd); errno = ETIMEDOUT; return -1; |