o All Windows messages are dispatched from this function.
o The Operating System has Winsock 2.
- MSDN References:
+ References:
o http://msdn.microsoft.com/library/default.asp?
url=/library/en-us/winui/hh/winui/messques_77zk.asp
o http://msdn.microsoft.com/library/default.asp?
url=/library/en-us/winsock/hh/winsock/apistart_9g1e.asp
+ o http://developer.novell.com/support/winsock/doc/toc.htm
*/
and wait just for windows messages. */
if (nhandles == 0 && timeout) {
UINT timer = SetTimer(NULL, 0, timeo, NULL);
- if (timer) {
+ curtime = GetTickCount();
+ while (timer)
WaitMessage();
KillTimer(NULL, timer);
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
+ if (msg.message == WM_TIMER)
+ return 0;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
- return 0;
+ if (timeo != INFINITE) {
+ timeo -= GetTickCount() - curtime;
+ if (timeo < 0)
+ timeo = 0;
+ timer = SetTimer(NULL, 0, timeo, NULL);
+ }
}
}
--- /dev/null
+/*
+
+ silcwin32sockconn.c
+
+ Author: Pekka Riikonen <priikone@silcnet.org>
+
+ Copyright (C) 1997 - 2001 Pekka Riikonen
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+*/
+/* $Id$ */
+
+#include "silcincludes.h"
+
+/* Writes data from encrypted buffer to the socket connection. If the
+ data cannot be written at once, it will be written later with a timeout.
+ The data is written from the data section of the buffer, not from head
+ or tail section. This automatically pulls the data section towards end
+ after writing the data. */
+
+int silc_socket_write(SilcSocketConnection sock)
+{
+ int ret = 0, err;
+ SOCKET fd = sock->sock;
+ SilcBuffer src = sock->outbuf;
+
+ SILC_LOG_DEBUG(("Writing data to socket %d", fd));
+
+ if (src->len > 0) {
+ ret = recv(fd, src->data, src->len, 0);
+ if (ret == SOCKET_ERROR) {
+ err = WSAGetLastError();
+ if (err == WSAEWOULDBLOCK) {
+ SILC_LOG_DEBUG(("Could not write immediately, will do it later"));
+ return -2;
+ }
+ SILC_LOG_ERROR(("Cannot write to socket: %d", (int)fd));
+ return -1;
+ }
+
+ silc_buffer_pull(src, ret);
+ }
+
+ SILC_LOG_DEBUG(("Wrote data %d bytes", ret));
+
+ return ret;
+}
+
+/* Reads data from the socket connection into the incoming data buffer.
+ It reads as much as possible from the socket connection. This returns
+ amount of bytes read or -1 on error or -2 on case where all of the
+ data could not be read at once. */
+
+int silc_socket_read(SilcSocketConnection sock)
+{
+ int len = 0, err;
+ unsigned char buf[SILC_SOCKET_READ_SIZE];
+ SOCKET fd = sock->sock;
+
+ SILC_LOG_DEBUG(("Reading data from socket %d", fd));
+
+ /* Read the data from the socket. */
+ len = recv(fd, buf, sizeof(buf), 0);
+ if (len == SOCKET_ERROR) {
+ err = WSAGetLastError();
+ if (err == WSAEWOULDBLOCK || err == WSAEINTR) {
+ SILC_LOG_DEBUG(("Could not read immediately, will do it later"));
+ return -2;
+ }
+ SILC_LOG_ERROR(("Cannot read from socket: %d", (int)fd));
+ return -1;
+ }
+
+ if (!len)
+ return 0;
+
+ /* Insert the data to the buffer. */
+
+ if (!sock->inbuf)
+ sock->inbuf = silc_buffer_alloc(SILC_SOCKET_BUF_SIZE);
+
+ /* If the data does not fit to the buffer reallocate it */
+ if ((sock->inbuf->end - sock->inbuf->tail) < len)
+ sock->inbuf = silc_buffer_realloc(sock->inbuf, sock->inbuf->truelen +
+ (len * 2));
+ silc_buffer_put_tail(sock->inbuf, buf, len);
+ silc_buffer_pull_tail(sock->inbuf, len);
+
+ SILC_LOG_DEBUG(("Read %d bytes", len));
+
+ return len;
+}