diff options
Diffstat (limited to 'gweb')
-rw-r--r-- | gweb/giognutls.c | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/gweb/giognutls.c b/gweb/giognutls.c index e6c1bde3..06eff4af 100644 --- a/gweb/giognutls.c +++ b/gweb/giognutls.c @@ -44,6 +44,7 @@ struct _GIOGnuTLSChannel { gnutls_certificate_credentials_t cred; gnutls_session session; gboolean established; + gboolean again; }; struct _GIOGnuTLSWatch { @@ -68,15 +69,18 @@ static GIOStatus check_handshake(GIOChannel *channel, GError **err) DBG("channel %p", channel); -again: if (gnutls_channel->established == TRUE) return G_IO_STATUS_NORMAL; +again: result = gnutls_handshake(gnutls_channel->session); if (result == GNUTLS_E_INTERRUPTED || result == GNUTLS_E_AGAIN) { GIOFlags flags = g_io_channel_get_flags(channel); + if (gnutls_channel->again == TRUE) + return G_IO_STATUS_AGAIN; + if (flags & G_IO_FLAG_NONBLOCK) return G_IO_STATUS_AGAIN; @@ -124,6 +128,9 @@ again: if (result == GNUTLS_E_INTERRUPTED || result == GNUTLS_E_AGAIN) { GIOFlags flags = g_io_channel_get_flags(channel); + if (gnutls_channel->again == TRUE) + return G_IO_STATUS_AGAIN; + if (flags & G_IO_FLAG_NONBLOCK) return G_IO_STATUS_AGAIN; @@ -172,6 +179,9 @@ again: if (result == GNUTLS_E_INTERRUPTED || result == GNUTLS_E_AGAIN) { GIOFlags flags = g_io_channel_get_flags(channel); + if (gnutls_channel->again == TRUE) + return G_IO_STATUS_AGAIN; + if (flags & G_IO_FLAG_NONBLOCK) return G_IO_STATUS_AGAIN; @@ -352,6 +362,11 @@ static ssize_t g_io_gnutls_push_func(gnutls_transport_ptr_t transport_data, result = write(fd, buf, count); + if (result < 0 && errno == EAGAIN) + gnutls_channel->again = TRUE; + else + gnutls_channel->again = FALSE; + DBG("result %zd", result); return result; @@ -370,6 +385,11 @@ static ssize_t g_io_gnutls_pull_func(gnutls_transport_ptr_t transport_data, result = read(fd, buf, count); + if (result < 0 && errno == EAGAIN) + gnutls_channel->again = TRUE; + else + gnutls_channel->again = FALSE; + DBG("result %zd", result); return result; |