summaryrefslogtreecommitdiff
path: root/src/w32.c
diff options
context:
space:
mode:
authorTed Zlatanov <tzz@lifelogs.com>2011-04-24 20:30:51 -0500
committerTed Zlatanov <tzz@lifelogs.com>2011-04-24 20:30:51 -0500
commite061a11b5a59f02fac66184e991f01a433f6dc8d (patch)
treeccff6a6012dbc1ed4ce247b9e4e84a38c5eb34af /src/w32.c
parent33630d51504adc5b2a0289f356c0a1a49f0bd10a (diff)
downloademacs-e061a11b5a59f02fac66184e991f01a433f6dc8d.tar.gz
Add GnuTLS support for W32 and certificate and hostname verification in GnuTLS.
* src/gnutls.c: Renamed global_initialized to gnutls_global_initialized. Added internals for the :verify-hostname-error, :verify-error, and :verify-flags parameters of `gnutls-boot' and documented those parameters in the docstring. Start callback support. (emacs_gnutls_handshake): Add Woe32 support. Retry handshake unless a fatal error occured. Call gnutls_alert_send_appropriate on error. Return error code. (emacs_gnutls_write): Call emacs_gnutls_handle_error. (emacs_gnutls_read): Likewise. (Fgnutls_boot): Return handshake error code. (emacs_gnutls_handle_error): New function. (wsaerror_to_errno): Likewise. * src/gnutls.h: Add GNUTLS_STAGE_CALLBACKS enum to denote we're in the callbacks stage. * src/w32.c (emacs_gnutls_pull): New function for GnuTLS on Woe32. (emacs_gnutls_push): Likewise. * src/w32.h (emacs_gnutls_pull): Add prototype. (emacs_gnutls_push): Likewise.
Diffstat (limited to 'src/w32.c')
-rw-r--r--src/w32.c69
1 files changed, 68 insertions, 1 deletions
diff --git a/src/w32.c b/src/w32.c
index 85e4a2025b9..065d730333b 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -6124,5 +6124,72 @@ serial_configure (struct Lisp_Process *p, Lisp_Object contact)
p->childp = childp2;
}
-/* end of w32.c */
+#ifdef HAVE_GNUTLS
+
+ssize_t
+emacs_gnutls_pull (gnutls_transport_ptr_t p, void* buf, size_t sz)
+{
+ int n, sc, err;
+ SELECT_TYPE fdset;
+ EMACS_TIME timeout;
+ struct Lisp_Process *process = (struct Lisp_Process *)p;
+ int fd = process->infd;
+
+ for (;;)
+ {
+ n = sys_read(fd, (char*)buf, sz);
+
+ if (n >= 0)
+ return n;
+
+ err = errno;
+
+ if (err == EWOULDBLOCK)
+ {
+ /* Set a small timeout. */
+ EMACS_SET_SECS_USECS(timeout, 1, 0);
+ FD_ZERO (&fdset);
+ FD_SET ((int)fd, &fdset);
+
+ /* Use select with the timeout to poll the selector. */
+ sc = select (fd + 1, &fdset, (SELECT_TYPE *)0, (SELECT_TYPE *)0,
+ &timeout);
+
+ if (sc > 0)
+ continue; /* Try again. */
+
+ /* Translate the WSAEWOULDBLOCK alias EWOULDBLOCK to EAGAIN.
+ Also accept select return 0 as an indicator to EAGAIN. */
+ if (sc == 0 || errno == EWOULDBLOCK)
+ err = EAGAIN;
+ else
+ err = errno; /* Other errors are just passed on. */
+ }
+
+ gnutls_transport_set_errno (process->gnutls_state, err);
+
+ return -1;
+ }
+}
+ssize_t
+emacs_gnutls_push (gnutls_transport_ptr_t p, const void* buf, size_t sz)
+{
+ struct Lisp_Process *process = (struct Lisp_Process *)p;
+ int fd = proc->outfd;
+ ssize_t n = sys_write(fd, buf, sz);
+
+ /* 0 or more bytes written means everything went fine. */
+ if (n >= 0)
+ return n;
+
+ /* Negative bytes written means we got an error in errno.
+ Translate the WSAEWOULDBLOCK alias EWOULDBLOCK to EAGAIN. */
+ gnutls_transport_set_errno (process->gnutls_state,
+ errno == EWOULDBLOCK ? EAGAIN : errno);
+
+ return -1;
+}
+#endif /* HAVE_GNUTLS */
+
+/* end of w32.c */