diff options
-rw-r--r-- | camel/ChangeLog | 27 | ||||
-rw-r--r-- | camel/camel-remote-store.c | 11 | ||||
-rw-r--r-- | camel/camel-stream-buffer.c | 10 | ||||
-rw-r--r-- | camel/camel-stream-buffer.h | 4 | ||||
-rw-r--r-- | camel/camel-tcp-stream-openssl.c | 110 | ||||
-rw-r--r-- | camel/camel-tcp-stream-ssl.c | 35 |
6 files changed, 110 insertions, 87 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog index fbf87612d3..0659ce16e3 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,3 +1,30 @@ +2001-10-29 Jeffrey Stedfast <fejj@ximian.com> + + * camel-tcp-stream-openssl.c (my_SSL_write): Removed. + (stream_write): Keep looping (non-blocking case) if errno is + EAGAIN, EINTR or EWOULDBLOCK. For NONBLOCKing I/O, sync up with + CamelTcpStreamRaw. As with CamelTcpStreamRaw/SSL - make sure to + write out everything before returning. + (my_SSL_read): Removed. + (stream_read): Just call ssl_error_to_errno() and check the errno + values that we care about so we can keep the general look of all + this stream code the same. Also when checking the return value of + SSL_read, check for <0 instead of ==-1 since the man page for + SSL_read doesn't say it will return -1 on fail, it just says <0. + (stream_flush): Don't fsync() since syncing on a socket is a Bad + Thing (tm). + + * camel-tcp-stream-ssl.c (stream_write): Make sure we write out + everything just like in camel-tcp-stream-raw.c. + + * camel-stream-buffer.c (camel_stream_buffer_gets): If + camel_stream_read() returns -1, don't necessarily return -1 to our + caller since it's possible that we did actually "read" some data + (ie, we copied some pre-buffered data into the out buffer). + + * camel-stream-buffer.h: Removed CAMEL_STREAM_BUFFER_NEWLINE since + it never got used anywhere and it isn't supported anyway. + 2001-10-30 <NotZed@Ximian.com> * providers/imap/camel-imap-store.c diff --git a/camel/camel-remote-store.c b/camel/camel-remote-store.c index 4148a72c7f..8c299cec0c 100644 --- a/camel/camel-remote-store.c +++ b/camel/camel-remote-store.c @@ -458,7 +458,6 @@ static int remote_recv_line (CamelRemoteStore *store, char **dest, CamelException *ex) { CamelStreamBuffer *stream; - CamelException internal_ex; char *buf; *dest = NULL; @@ -477,18 +476,14 @@ remote_recv_line (CamelRemoteStore *store, char **dest, CamelException *ex) buf = camel_stream_buffer_read_line (stream); - camel_exception_init (&internal_ex); if (buf == NULL) { if (errno == EINTR) - camel_exception_set (&internal_ex, CAMEL_EXCEPTION_USER_CANCEL, _("Operation cancelled")); + camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL, _("Operation cancelled")); else - camel_exception_setv (&internal_ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, + camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, _("Server unexpectedly disconnected: %s"), g_strerror (errno)); - } - - if (camel_exception_is_set (&internal_ex)) { - camel_exception_xfer (ex, &internal_ex); + camel_service_disconnect (CAMEL_SERVICE (store), FALSE, NULL); return -1; } diff --git a/camel/camel-stream-buffer.c b/camel/camel-stream-buffer.c index 3d7ac5e845..fe3458a93f 100644 --- a/camel/camel-stream-buffer.c +++ b/camel/camel-stream-buffer.c @@ -401,9 +401,13 @@ int camel_stream_buffer_gets(CamelStreamBuffer *sbf, char *buf, unsigned int max if (outptr == outend) break; - bytes_read = camel_stream_read(sbf->stream, sbf->buf, sbf->size); - if (bytes_read == -1) - return -1; + bytes_read = camel_stream_read (sbf->stream, sbf->buf, sbf->size); + if (bytes_read == -1) { + if (buf == outptr) + return -1; + else + bytes_read = 0; + } inptr = sbf->ptr = sbf->buf; inend = sbf->end = sbf->buf + bytes_read; } while (bytes_read>0); diff --git a/camel/camel-stream-buffer.h b/camel/camel-stream-buffer.h index db93971fd2..03a8517066 100644 --- a/camel/camel-stream-buffer.h +++ b/camel/camel-stream-buffer.h @@ -41,10 +41,8 @@ extern "C" { #define CAMEL_STREAM_BUFFER_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_STREAM_BUFFER_TYPE, CamelStreamBufferClass)) #define CAMEL_IS_STREAM_BUFFER(o) (CAMEL_CHECK_TYPE((o), CAMEL_STREAM_BUFFER_TYPE)) -typedef enum -{ +typedef enum { CAMEL_STREAM_BUFFER_BUFFER = 0, - CAMEL_STREAM_BUFFER_NEWLINE, CAMEL_STREAM_BUFFER_NONE, CAMEL_STREAM_BUFFER_READ = 0x00, CAMEL_STREAM_BUFFER_WRITE = 0x80, diff --git a/camel/camel-tcp-stream-openssl.c b/camel/camel-tcp-stream-openssl.c index 6e94b29487..17d5ab0961 100644 --- a/camel/camel-tcp-stream-openssl.c +++ b/camel/camel-tcp-stream-openssl.c @@ -176,8 +176,8 @@ errlib_error_to_errno (int ret) if (error == 0) { if (ret == 0) errno = EINVAL; /* unexpected EOF */ - /* otherwise errno should be set */ - } else { + errno = 0; + } else if (!errno) { /* ok, we get the shaft now. */ errno = EINTR; } @@ -210,22 +210,11 @@ ssl_error_to_errno (SSL *ssl, int ret) } } -static int -my_SSL_read (SSL *ssl, void *buf, int num) -{ - int ret; - - do - ret = SSL_read (ssl, buf, num); - while (ret < 0 && (SSL_get_error (ssl, ret) == SSL_ERROR_WANT_READ || - SSL_get_error (ssl, ret) == SSL_ERROR_WANT_WRITE)); - return ret; -} - static ssize_t stream_read (CamelStream *stream, char *buffer, size_t n) { CamelTcpStreamOpenSSL *tcp_stream_openssl = CAMEL_TCP_STREAM_OPENSSL (stream); + SSL *ssl = tcp_stream_openssl->priv->ssl; ssize_t nread; int cancel_fd; @@ -237,8 +226,10 @@ stream_read (CamelStream *stream, char *buffer, size_t n) cancel_fd = camel_operation_cancel_fd (NULL); if (cancel_fd == -1) { do { - nread = my_SSL_read (tcp_stream_openssl->priv->ssl, buffer, n); - } while (nread == -1 && errno == EINTR); + nread = SSL_read (ssl, buffer, n); + if (nread < 0) + ssl_error_to_errno (ssl, nread); + } while (nread < 0 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)); } else { int flags, fdmax; fd_set rdset; @@ -247,51 +238,36 @@ stream_read (CamelStream *stream, char *buffer, size_t n) fcntl (tcp_stream_openssl->priv->sockfd, F_SETFL, flags | O_NONBLOCK); do { - nread = my_SSL_read (tcp_stream_openssl->priv->ssl, buffer, n); - - if (nread == 0) - return nread; + FD_ZERO (&rdset); + FD_SET (tcp_stream_openssl->priv->sockfd, &rdset); + FD_SET (cancel_fd, &rdset); + fdmax = MAX (tcp_stream_openssl->priv->sockfd, cancel_fd) + 1; - if (nread == -1 && errno == EAGAIN) { - FD_ZERO (&rdset); - FD_SET (tcp_stream_openssl->priv->sockfd, &rdset); - FD_SET (cancel_fd, &rdset); - fdmax = MAX (tcp_stream_openssl->priv->sockfd, cancel_fd) + 1; - - select (fdmax, &rdset, 0, 0, NULL); - if (FD_ISSET (cancel_fd, &rdset)) { - fcntl (tcp_stream_openssl->priv->sockfd, F_SETFL, flags); - errno = EINTR; - return -1; - } + select (fdmax, &rdset, 0, 0, NULL); + if (FD_ISSET (cancel_fd, &rdset)) { + fcntl (tcp_stream_openssl->priv->sockfd, F_SETFL, flags); + errno = EINTR; + return -1; } - } while (nread == -1 && errno == EAGAIN); + + do { + nread = SSL_read (ssl, buffer, n); + if (nread < 0) + ssl_error_to_errno (ssl, nread); + } while (nread < 0 && errno == EINTR); + } while (nread < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)); fcntl (tcp_stream_openssl->priv->sockfd, F_SETFL, flags); } - if (nread == -1) - ssl_error_to_errno (tcp_stream_openssl->priv->ssl, -1); - return nread; } -static int -my_SSL_write (SSL *ssl, const void *buf, int num) -{ - int ret; - - do - ret = SSL_write (ssl, buf, num); - while (ret < 0 && (SSL_get_error (ssl, ret) == SSL_ERROR_WANT_READ || - SSL_get_error (ssl, ret) == SSL_ERROR_WANT_WRITE)); - return ret; -} - static ssize_t stream_write (CamelStream *stream, const char *buffer, size_t n) { CamelTcpStreamOpenSSL *tcp_stream_openssl = CAMEL_TCP_STREAM_OPENSSL (stream); + SSL *ssl = tcp_stream_openssl->priv->ssl; ssize_t w, written = 0; int cancel_fd; @@ -303,8 +279,15 @@ stream_write (CamelStream *stream, const char *buffer, size_t n) cancel_fd = camel_operation_cancel_fd (NULL); if (cancel_fd == -1) { do { - written = my_SSL_write (tcp_stream_openssl->priv->ssl, buffer, n); - } while (written == -1 && errno == EINTR); + do { + w = SSL_write (ssl, buffer + written, n - written); + if (w < 0) + ssl_error_to_errno (SSL_get_error (ssl, w)); + } while (w < 0 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)); + + if (w > 0) + written += w; + } while (w != -1 && written < n); } else { fd_set rdset, wrset; int flags, fdmax; @@ -326,26 +309,35 @@ stream_write (CamelStream *stream, const char *buffer, size_t n) return -1; } - w = my_SSL_write (tcp_stream_openssl->priv->ssl, buffer + written, n - written); - if (w > 0) + do { + w = SSL_write (ssl, buffer + written, n - written); + if (w < 0) + ssl_error_to_errno (ssl, w); + } while (w < 0 && errno == EINTR); + + if (w < 0) { + 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; - } while (w != -1 && written < n); + } while (w >= 0 && written < n); fcntl (tcp_stream_openssl->priv->sockfd, F_SETFL, flags); - if (w == -1) - written = -1; } - if (written == -1) - ssl_error_to_errno (tcp_stream_openssl->priv->ssl, -1); - return written; } static int stream_flush (CamelStream *stream) { - return fsync (((CamelTcpStreamOpenSSL *)stream)->priv->sockfd); + return 0; } diff --git a/camel/camel-tcp-stream-ssl.c b/camel/camel-tcp-stream-ssl.c index 4b1ac726f8..9adf49837a 100644 --- a/camel/camel-tcp-stream-ssl.c +++ b/camel/camel-tcp-stream-ssl.c @@ -159,15 +159,20 @@ set_errno (int code) { /* FIXME: this should handle more. */ switch (code) { + case PR_PENDING_INTERRUPT_ERROR: + errno = EINTR; + break; + case PR_IO_PENDING_ERROR: case PR_IO_TIMEOUT_ERROR: errno = EAGAIN; break; + case PR_WOULD_BLOCK_ERROR: + errno = EWOULDBLOCK; + break; case PR_IO_ERROR: + default: errno = EIO; break; - default: - /* what to set by default?? */ - errno = EINTR; } } @@ -179,10 +184,9 @@ stream_read (CamelStream *stream, char *buffer, size_t n) do { nread = PR_Read (tcp_stream_ssl->priv->sockfd, buffer, n); - } while (nread == -1 && PR_GetError () == PR_PENDING_INTERRUPT_ERROR); - - if (nread == -1) - set_errno (PR_GetError ()); + if (nread == -1) + set_errno (PR_GetError ()); + } while (nread == -1 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)); return nread; } @@ -191,14 +195,18 @@ static ssize_t stream_write (CamelStream *stream, const char *buffer, size_t n) { CamelTcpStreamSSL *tcp_stream_ssl = CAMEL_TCP_STREAM_SSL (stream); - ssize_t written = 0; + ssize_t w, written = 0; do { - written = PR_Write (tcp_stream_ssl->priv->sockfd, buffer, n); - } while (written == -1 && PR_GetError () == PR_PENDING_INTERRUPT_ERROR); - - if (written == -1) - set_errno (PR_GetError ()); + do { + w = PR_Write (tcp_stream_ssl->priv->sockfd, buffer + written, n - written); + if (w == -1) + set_errno (PR_GetError ()); + } while (w == -1 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)); + + if (w > 0) + written += w; + } while (w != -1 && written < n); return written; } @@ -367,7 +375,6 @@ ssl_cert_is_saved (const char *certid) { char *filename; struct stat st; - int ret; filename = g_strdup_printf ("%s/.camel_certs/%s", getenv ("HOME"), certid); |