summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2001-10-20 09:40:32 +0000
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2001-10-20 09:40:32 +0000
commit123885c990cf72ca6ea3972058b2dc1e1effc13d (patch)
tree5197ea720f728070c12b16b1510b72cf1964ab2b
parent2b0e6fb917697b60e3284f7adfdf9f623d022b7b (diff)
downloadgnutls-123885c990cf72ca6ea3972058b2dc1e1effc13d.tar.gz
introduced GNUTLS_E_INTERRUPTED, fixes in error handling
-rw-r--r--NEWS2
-rw-r--r--lib/gnutls_buffers.c11
-rw-r--r--lib/gnutls_errors.c3
-rw-r--r--lib/gnutls_errors_int.h1
-rw-r--r--lib/gnutls_handshake.c6
-rw-r--r--lib/gnutls_record.c8
6 files changed, 22 insertions, 9 deletions
diff --git a/NEWS b/NEWS
index f056ce2faf..07614c8f39 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,8 @@
Version 0.3.0
- AUTH_INFO types and structures were moved to library internals
- AUTH_FAILED is no longer returned in SRP (any fatal error in SRP means auth failed)
+- Introduced GNUTLS_E_INTERRUPTED
+- Added support for Non blocking IO
Version 0.2.4 (12/10/2001)
- Better handling of X.509 certificate extensions
diff --git a/lib/gnutls_buffers.c b/lib/gnutls_buffers.c
index 0b95cda5e7..74d75e0e27 100644
--- a/lib/gnutls_buffers.c
+++ b/lib/gnutls_buffers.c
@@ -156,9 +156,10 @@ static ssize_t _gnutls_Read(int fd, void *iptr, size_t sizeOfPtr, int flag)
while (left > 0) {
i = _gnutls_recv_func(fd, &ptr[i], left, flag);
if (i < 0) {
- if (errno == EAGAIN)
- return GNUTLS_E_AGAIN;
- else
+ if (errno == EAGAIN || errno == EINTR) {
+ if (errno==EAGAIN) return GNUTLS_E_AGAIN;
+ else return GNUTLS_E_INTERRUPTED;
+ } else
return GNUTLS_E_UNKNOWN_ERROR;
} else {
if (i == 0)
@@ -266,14 +267,14 @@ ssize_t _gnutls_read_buffered( int fd, GNUTLS_STATE state, opaque **iptr, size_t
*/
if ( sizeOfPtr - recvlowat > 0) {
ret = _gnutls_Read( fd, &buf[min], sizeOfPtr - recvlowat, flag);
- if (ret==GNUTLS_E_AGAIN)
+ if (ret < 0 && gnutls_is_fatal_error(ret)==0)
return ret;
}
if (ret >= 0 && recvlowat > 0) {
ret2 = _gnutls_Read( fd, &buf[min+ret], recvlowat, MSG_PEEK|flag);
- if (ret2==GNUTLS_E_AGAIN)
+ if (ret2 < 0 && gnutls_is_fatal_error(ret2)==0)
return ret2;
if (ret2 > 0)
diff --git a/lib/gnutls_errors.c b/lib/gnutls_errors.c
index 786b79cf5e..ea39c55dd1 100644
--- a/lib/gnutls_errors.c
+++ b/lib/gnutls_errors.c
@@ -81,6 +81,7 @@ static gnutls_error_entry error_algorithms[] = {
GNUTLS_ERROR_ENTRY( GNUTLS_E_X509_UNSUPPORTED_CRITICAL_EXTENSION, 1),
GNUTLS_ERROR_ENTRY( GNUTLS_E_X509_KEY_USAGE_VIOLATION, 1),
GNUTLS_ERROR_ENTRY( GNUTLS_E_AGAIN, 0),
+ GNUTLS_ERROR_ENTRY( GNUTLS_E_INTERRUPTED, 0),
GNUTLS_ERROR_ENTRY( GNUTLS_E_REHANDSHAKE, 0),
GNUTLS_ERROR_ENTRY( GNUTLS_E_GOT_APPLICATION_DATA, 0),
GNUTLS_ERROR_ENTRY( GNUTLS_E_DB_ERROR, 1),
@@ -100,7 +101,7 @@ static gnutls_error_entry error_algorithms[] = {
/**
* gnutls_is_fatal_error - Returns non-zero in case of a fatal error
- * @error: is an error returned by a gnutls function. Error is always a negative value.
+ * @error: is an error returned by a gnutls function. Error should be a negative value.
*
* If a function returns a negative value you may feed that value
* to this function to see if it is fatal. Returns 1 for a fatal
diff --git a/lib/gnutls_errors_int.h b/lib/gnutls_errors_int.h
index 76f6cd907d..79a8a547ec 100644
--- a/lib/gnutls_errors_int.h
+++ b/lib/gnutls_errors_int.h
@@ -52,5 +52,6 @@
#define GNUTLS_E_NO_CERTIFICATE_FOUND -49
#define GNUTLS_E_INVALID_PARAMETERS -50
#define GNUTLS_E_INVALID_REQUEST -51
+#define GNUTLS_E_INTERRUPTED -52
#define GNUTLS_E_UNIMPLEMENTED_FEATURE -250
diff --git a/lib/gnutls_handshake.c b/lib/gnutls_handshake.c
index 638b5b40f4..0e531903be 100644
--- a/lib/gnutls_handshake.c
+++ b/lib/gnutls_handshake.c
@@ -1294,7 +1294,7 @@ int gnutls_handshake(SOCKET cd, GNUTLS_STATE state)
if (ret < 0) { \
gnutls_assert(); \
ERR( str, ret); \
- if (ret==GNUTLS_E_AGAIN) return ret; \
+ if (gnutls_is_fatal_error(ret)==0) return ret; \
gnutls_clearHashDataBuffer(state); \
return ret; \
}
@@ -1411,6 +1411,7 @@ int gnutls_handshake_client(SOCKET cd, GNUTLS_STATE state)
IMED_RET("send client certificate verify", ret);
STATE = STATE0;
+ default:
}
@@ -1464,6 +1465,7 @@ static int _gnutls_send_handshake_final(SOCKET cd, GNUTLS_STATE state,
}
STATE = STATE0;
+ default:
}
return 0;
@@ -1517,6 +1519,7 @@ static int _gnutls_recv_handshake_final(SOCKET cd, GNUTLS_STATE state,
return ret;
}
STATE = STATE0;
+ default:
}
@@ -1621,6 +1624,7 @@ int gnutls_handshake_server(SOCKET cd, GNUTLS_STATE state)
IMED_RET("recv client certificate verify", ret);
STATE = STATE0; /* finished thus clear state */
+ default:
}
return 0;
diff --git a/lib/gnutls_record.c b/lib/gnutls_record.c
index 3aa8955d43..c08e3abbb6 100644
--- a/lib/gnutls_record.c
+++ b/lib/gnutls_record.c
@@ -585,7 +585,7 @@ ssize_t gnutls_recv_int(SOCKET cd, GNUTLS_STATE state, ContentType type, Handsha
* must be set to non blocking mode
*/
if ( (ret = _gnutls_read_buffered(cd, state, &headers, header_size, flags, -1)) != header_size) {
- if (ret==GNUTLS_E_AGAIN) return ret;
+ if (ret<0 && gnutls_is_fatal_error(ret)==0) return ret;
state->gnutls_internals.valid_connection = VALID_FALSE;
if (type==GNUTLS_ALERT) {
@@ -666,7 +666,7 @@ ssize_t gnutls_recv_int(SOCKET cd, GNUTLS_STATE state, ContentType type, Handsha
/* check if we have that data into buffer.
*/
if ( (ret = _gnutls_read_buffered(cd, state, &recv_data, header_size+length, flags, recv_type)) != length+header_size) {
- if (ret==GNUTLS_E_AGAIN) return ret;
+ if (ret<0 && gnutls_is_fatal_error(ret)==0) return ret;
state->gnutls_internals.valid_connection = VALID_FALSE;
state->gnutls_internals.resumable = RESUME_FALSE;
@@ -1002,6 +1002,10 @@ ssize_t gnutls_send(SOCKET cd, GNUTLS_STATE state, const void *data, size_t size
* The only acceptable flag is currently MSG_DONTWAIT. In that case,
* if the socket is set to non blocking IO it will return GNUTLS_E_AGAIN,
* if there are no data in the socket.
+ *
+ * If the recv() operation is interrupted then GNUTLS_E_INTERRUPTED, will be
+ * returned.
+ *
* Returns the number of bytes received, zero on EOF, or
* a negative error code.
**/