Mercurial > hg > xemacs-beta
diff src/lstream.c @ 5922:4b055de36bb9 cygwin
merging heads 2
author | Henry Thompson <ht@markup.co.uk> |
---|---|
date | Fri, 27 Feb 2015 17:47:15 +0000 |
parents | a216b3c2b09e |
children |
line wrap: on
line diff
--- a/src/lstream.c Wed Apr 23 22:22:37 2014 +0100 +++ b/src/lstream.c Fri Feb 27 17:47:15 2015 +0000 @@ -28,6 +28,7 @@ #include "buffer.h" #include "insdel.h" #include "lstream.h" +#include "tls.h" #include "sysfile.h" @@ -742,6 +743,12 @@ return Lstream_read_1 (lstr, data, size, 0); } +int +Lstream_errno (Lstream *lstr) +{ + return (lstr->imp->error) ? (lstr->imp->error) (lstr) : 0; +} + Charcount Lstream_character_tell (Lstream *lstr) { @@ -984,6 +991,25 @@ Lstream_unread (lstr, &ch, 1); } +/* Detect an active TLS session */ + +int +Lstream_tls_p (Lstream *lstr) +{ + return (lstr->imp->tls_p) ? (lstr->imp->tls_p) (lstr) : 0; +} + +/* STARTTLS negotiation */ + +int +Lstream_tls_negotiate (Lstream *instr, Lstream *outstr, const Extbyte *host, + Lisp_Object keylist) +{ + return (instr->imp->tls_negotiater) + ? (instr->imp->tls_negotiater) (instr, outstr, host, keylist) + : 0; +} + /************************ some stream implementations *********************/ @@ -1111,6 +1137,7 @@ struct filedesc_stream { + tls_state_t *tls_state; int fd; int pty_max_bytes; Ibyte eof_char; @@ -1118,6 +1145,7 @@ int current_pos; int end_pos; int chars_sans_newline; + int saved_errno; unsigned int closing :1; unsigned int allow_quit :1; unsigned int blocked_ok :1; @@ -1135,18 +1163,20 @@ ignored when writing); -1 for unlimited. */ static Lisp_Object make_filedesc_stream_1 (int filedesc, int offset, int count, int flags, - const char *mode) + tls_state_t *state, const char *mode) { Lstream *lstr = Lstream_new (lstream_filedesc, mode); struct filedesc_stream *fstr = FILEDESC_STREAM_DATA (lstr); - fstr->fd = filedesc; + fstr->tls_state = state; + fstr->fd = state ? tls_get_fd (state) : filedesc; fstr->closing = !!(flags & LSTR_CLOSING); fstr->allow_quit = !!(flags & LSTR_ALLOW_QUIT); fstr->blocked_ok = !!(flags & LSTR_BLOCKED_OK); fstr->pty_flushing = !!(flags & LSTR_PTY_FLUSHING); fstr->blocking_error_p = 0; fstr->chars_sans_newline = 0; - fstr->starting_pos = lseek (filedesc, offset, SEEK_CUR); + fstr->saved_errno = 0; + fstr->starting_pos = lseek (fstr->fd, offset, SEEK_CUR); fstr->current_pos = max (fstr->starting_pos, 0); if (count < 0) fstr->end_pos = -1; @@ -1176,15 +1206,17 @@ */ Lisp_Object -make_filedesc_input_stream (int filedesc, int offset, int count, int flags) +make_filedesc_input_stream (int filedesc, int offset, int count, int flags, + tls_state_t *state) { - return make_filedesc_stream_1 (filedesc, offset, count, flags, "r"); + return make_filedesc_stream_1 (filedesc, offset, count, flags, state, "r"); } Lisp_Object -make_filedesc_output_stream (int filedesc, int offset, int count, int flags) +make_filedesc_output_stream (int filedesc, int offset, int count, int flags, + tls_state_t *state) { - return make_filedesc_stream_1 (filedesc, offset, count, flags, "w"); + return make_filedesc_stream_1 (filedesc, offset, count, flags, state, "w"); } static Bytecount @@ -1192,17 +1224,23 @@ { Bytecount nread; struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream); + str->saved_errno = 0; if (str->end_pos >= 0) size = min (size, (Bytecount) (str->end_pos - str->current_pos)); - nread = str->allow_quit ? - read_allowing_quit (str->fd, data, size) : - retry_read (str->fd, data, size); + nread = str->tls_state + ? tls_read (str->tls_state, data, size, str->allow_quit) + : (str->allow_quit ? + read_allowing_quit (str->fd, data, size) : + retry_read (str->fd, data, size)); if (nread > 0) str->current_pos += nread; if (nread == 0) return 0; /* LSTREAM_EOF; */ if (nread < 0) - return LSTREAM_ERROR; + { + str->saved_errno = errno; + return LSTREAM_ERROR; + } return nread; } @@ -1228,6 +1266,8 @@ Bytecount retval; int need_newline = 0; + str->saved_errno = 0; + /* This function would be simple if it were not for the blasted PTY max-bytes stuff. Why the hell can't they just have written the PTY drivers right so this problem doesn't exist? @@ -1254,9 +1294,11 @@ /**** start of non-PTY-crap ****/ if (size > 0) - retval = str->allow_quit ? - write_allowing_quit (str->fd, data, size) : - retry_write (str->fd, data, size); + retval = str->tls_state + ? tls_write (str->tls_state, data, size, str->allow_quit) + : (str->allow_quit ? + write_allowing_quit (str->fd, data, size) : + retry_write (str->fd, data, size)); else retval = 0; if (retval < 0 && errno_would_block_p (errno) && str->blocked_ok) @@ -1266,7 +1308,10 @@ } str->blocking_error_p = 0; if (retval < 0) - return LSTREAM_ERROR; + { + str->saved_errno = errno; + return LSTREAM_ERROR; + } /**** end non-PTY-crap ****/ if (str->pty_flushing) @@ -1298,7 +1343,10 @@ return 0; } else - return LSTREAM_ERROR; + { + str->saved_errno = errno; + return LSTREAM_ERROR; + } } else return retval; @@ -1334,7 +1382,10 @@ return 0; } else - return LSTREAM_ERROR; + { + str->saved_errno = errno; + return LSTREAM_ERROR; + } } else return retval; @@ -1345,6 +1396,13 @@ } static int +filedesc_error (Lstream *stream) +{ + struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream); + return str->saved_errno; +} + +static int filedesc_rewinder (Lstream *stream) { struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream); @@ -1379,7 +1437,9 @@ filedesc_closer (Lstream *stream) { struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream); - if (str->closing) + if (str->tls_state) + return tls_close (str->tls_state); + else if (str->closing) return retry_close (str->fd); else return 0; @@ -1409,6 +1469,32 @@ return str->fd; } +static int +filedesc_tls_p (Lstream *stream) +{ + struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream); + return str->tls_state != NULL; +} + +static int +filedesc_tls_negotiater (Lstream *instream, Lstream *outstream, + const Extbyte *host, Lisp_Object keylist) +{ + struct filedesc_stream *in_str, *out_str; + + if (!LSTREAM_TYPE_P (outstream, filedesc)) + invalid_argument ("STARTTLS applies to file descriptor streams only", + wrap_lstream (outstream)); + + in_str = FILEDESC_STREAM_DATA (instream); + out_str = FILEDESC_STREAM_DATA (outstream); + in_str->tls_state = out_str->tls_state = + tls_negotiate (out_str->fd, host, keylist); + if (out_str->tls_state != NULL) + in_str->fd = out_str->fd = tls_get_fd (out_str->tls_state); + return out_str->tls_state != NULL; +} + /*********** read from a Lisp string ***********/ #define LISP_STRING_STREAM_DATA(stream) LSTREAM_TYPE_DATA (stream, lisp_string) @@ -1926,10 +2012,13 @@ LSTREAM_HAS_METHOD (filedesc, reader); LSTREAM_HAS_METHOD (filedesc, writer); + LSTREAM_HAS_METHOD (filedesc, error); LSTREAM_HAS_METHOD (filedesc, was_blocked_p); LSTREAM_HAS_METHOD (filedesc, rewinder); LSTREAM_HAS_METHOD (filedesc, seekable_p); LSTREAM_HAS_METHOD (filedesc, closer); + LSTREAM_HAS_METHOD (filedesc, tls_p); + LSTREAM_HAS_METHOD (filedesc, tls_negotiater); LSTREAM_HAS_METHOD (lisp_string, reader); LSTREAM_HAS_METHOD (lisp_string, rewinder);