diff options
author | Ted Zlatanov <tzz@lifelogs.com> | 2011-04-24 20:30:51 -0500 |
---|---|---|
committer | Ted Zlatanov <tzz@lifelogs.com> | 2011-04-24 20:30:51 -0500 |
commit | e061a11b5a59f02fac66184e991f01a433f6dc8d (patch) | |
tree | ccff6a6012dbc1ed4ce247b9e4e84a38c5eb34af /src/w32.c | |
parent | 33630d51504adc5b2a0289f356c0a1a49f0bd10a (diff) | |
download | emacs-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.c | 69 |
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 */ |