Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 1997 - 2001 Pekka Riikonen
+ Copyright (C) 1997 - 2005 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.
+ the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
*/
/* $Id$ */
-#include "silcincludes.h"
+#include "silc.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.
SOCKET fd = sock->sock;
SilcBuffer src = sock->outbuf;
+ if (!src)
+ return -2;
+ if (SILC_IS_DISABLED(sock))
+ return -1;
+
SILC_LOG_DEBUG(("Writing data to socket %d", fd));
if (src->len > 0) {
err = WSAGetLastError();
if (err == WSAEWOULDBLOCK) {
SILC_LOG_DEBUG(("Could not write immediately, will do it later"));
- silc_net_set_socket_nonblock(fd);
return -2;
}
SILC_LOG_ERROR(("Cannot write to socket: %d", (int)fd));
- silc_net_set_socket_nonblock(fd);
+ sock->sock_error = err;
return -1;
}
+ if (ret < src->len) {
+ SILC_LOG_DEBUG(("Wrote data %d of %d bytes, will write rest later",
+ ret, src->len));
+ silc_buffer_pull(src, ret);
+ return -2;
+ }
+
silc_buffer_pull(src, ret);
}
SILC_LOG_DEBUG(("Wrote data %d bytes", ret));
- silc_net_set_socket_nonblock(fd);
return ret;
}
int len = 0, err;
unsigned char buf[SILC_SOCKET_READ_SIZE];
SOCKET fd = sock->sock;
+ int argp;
+
+ if (SILC_IS_DISABLED(sock))
+ return -1;
SILC_LOG_DEBUG(("Reading data from socket %d", fd));
+ /* Check whether there is data available, without calling recv(). */
+ ioctlsocket(fd, FIONREAD, (unsigned long *)&argp);
+ if (argp == 0) {
+ /* Is this kludge or what? Without this thing this contraption
+ does not work at all!?. */
+ SleepEx(1, TRUE);
+ SILC_LOG_DEBUG(("Could not read immediately, will do it later"));
+ return -2;
+ }
+
/* 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"));
- silc_net_set_socket_nonblock(fd);
return -2;
}
SILC_LOG_ERROR(("Cannot read from socket: %d", (int)fd));
- silc_net_set_socket_nonblock(fd);
+ sock->sock_error = err;
return -1;
}
- silc_net_set_socket_nonblock(fd);
-
if (!len)
return 0;
return len;
}
+
+/* Returns human readable socket error message */
+
+SilcBool silc_socket_get_error(SilcSocketConnection sock, char *error,
+ SilcUInt32 error_len)
+{
+ /* XXX TODO */
+ return FALSE;
+}