X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/5e1a8e278f3210fd6f37af7867bbb42cf160fb92..4017be6d5375063f59b63474490ac072e7f09b1a:/raw.c diff --git a/raw.c b/raw.c index ff37b6d0..2c3e8522 100644 --- a/raw.c +++ b/raw.c @@ -14,8 +14,6 @@ static SOCKET s = INVALID_SOCKET; -#define iswritable(x) ( (x) != IAC && (x) != CR ) - static void raw_size(void); static int sb_opt, sb_len; @@ -50,14 +48,8 @@ static void s_write (void *buf, int len) { } static void c_write (char *buf, int len) { - while (len--) { - int new_head = (inbuf_head + 1) & INBUF_MASK; - int c = (unsigned char) *buf; - if (new_head != inbuf_reap) { - inbuf[inbuf_head] = *buf++; - inbuf_head = new_head; - } - } + while (len--) + c_write1(*buf++); } /* @@ -132,7 +124,7 @@ static char *raw_init (HWND hwnd, char *host, int port, char **realhost) { default: return "connect(): unknown error"; } - if (WSAAsyncSelect (s, hwnd, WM_NETEVENT, FD_READ | + if (hwnd && WSAAsyncSelect (s, hwnd, WM_NETEVENT, FD_READ | FD_WRITE | FD_OOB | FD_CLOSE) == SOCKET_ERROR) switch (WSAGetLastError()) { case WSAENETDOWN: return "Network is down"; @@ -150,14 +142,22 @@ static int raw_msg (WPARAM wParam, LPARAM lParam) { int ret; char buf[256]; - if (s == INVALID_SOCKET) /* how the hell did we get here?! */ - return -5000; + /* + * Because reading less than the whole of the available pending + * data can generate an FD_READ event, we need to allow for the + * possibility that FD_READ may arrive with FD_CLOSE already in + * the queue; so it's possible that we can get here even with s + * invalid. If so, we return 1 and don't worry about it. + */ + if (s == INVALID_SOCKET) + return 1; if (WSAGETSELECTERROR(lParam) != 0) return -WSAGETSELECTERROR(lParam); switch (WSAGETSELECTEVENT(lParam)) { case FD_READ: + case FD_CLOSE: ret = recv(s, buf, sizeof(buf), 0); if (ret < 0 && WSAGetLastError() == WSAEWOULDBLOCK) return 1; @@ -165,7 +165,7 @@ static int raw_msg (WPARAM wParam, LPARAM lParam) { return -10000-WSAGetLastError(); if (ret == 0) { s = INVALID_SOCKET; - return 0; /* can't happen, in theory */ + return 0; } c_write( buf, ret ); return 1; @@ -184,9 +184,6 @@ static int raw_msg (WPARAM wParam, LPARAM lParam) { if (outbuf_head != outbuf_reap) try_write(); return 1; - case FD_CLOSE: - s = INVALID_SOCKET; - return 0; } return 1; /* shouldn't happen, but WTF */ } @@ -218,10 +215,13 @@ static void raw_special (Telnet_Special code) { return; } +SOCKET raw_socket(void) { return s; } + Backend raw_backend = { raw_init, raw_msg, raw_send, raw_size, - raw_special + raw_special, + raw_socket };