/* SSL support via GnuTLS library.
- Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software
+ Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
Foundation, Inc.
This file is part of GNU Wget.
#include <assert.h>
#include <errno.h>
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
+#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <dirent.h>
#include <gnutls/gnutls.h>
#include <gnutls/x509.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
#include "utils.h"
#include "connect.h"
do
ret = gnutls_record_recv (ctx->session, buf, bufsize);
- while (ret == GNUTLS_E_INTERRUPTED);
+ while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);
if (ret < 0)
ctx->last_error = ret;
struct wgnutls_transport_context *ctx = arg;
do
ret = gnutls_record_send (ctx->session, buf, bufsize);
- while (ret == GNUTLS_E_INTERRUPTED);
+ while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);
if (ret < 0)
ctx->last_error = ret;
return ret;
static int
wgnutls_peek (int fd, char *buf, int bufsize, void *arg)
{
- int ret = 0;
+ int ret = 0, read = 0;
struct wgnutls_transport_context *ctx = arg;
int offset = MIN (bufsize, ctx->peeklen);
if (bufsize > sizeof ctx->peekbuf)
if (bufsize > offset)
{
+#ifdef F_GETFL
+ int flags;
+ flags = fcntl (fd, F_GETFL, 0);
+ if (flags < 0)
+ return ret;
+
+ ret = fcntl (fd, F_SETFL, flags | O_NONBLOCK);
+ if (ret < 0)
+ return ret;
+#else
+ /* XXX: Assume it was blocking before. */
+ const int zero = 0;
+ ret = ioctl (fd, FIONBIO, &zero);
+ if (ret < 0)
+ return ret;
+#endif
do
{
ret = gnutls_record_recv (ctx->session, buf + offset,
- bufsize - offset);
+ bufsize - offset);
}
- while (ret == GNUTLS_E_INTERRUPTED);
+ while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);
- if (ret < 0)
+ read = ret;
+
+ if (read < 0)
{
if (offset)
- ret = 0;
+ read = 0;
else
- return ret;
+ return read;
}
- if (ret > 0)
+ if (read > 0)
{
memcpy (ctx->peekbuf + offset, buf + offset,
- ret);
- ctx->peeklen += ret;
+ read);
+ ctx->peeklen += read;
}
+
+#ifdef F_GETFL
+ ret = fcntl (fd, F_SETFL, flags);
+ if (ret < 0)
+ return ret;
+#else
+ const int one = 1;
+ ret = ioctl (fd, FIONBIO, &one);
+ if (ret < 0)
+ return ret;
+#endif
}
- return offset + ret;
+ return offset + read;
}
static const char *