summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNicolas "Pixel" Noble <pixel@nobis-crew.org>2013-12-20 19:04:23 -0800
committerNicolas "Pixel" Noble <pixel@nobis-crew.org>2013-12-20 19:04:23 -0800
commit16594884da1c20c60fa1211c76939696547c02b5 (patch)
tree1e1ae20b323f6e99a36bcf9611032726c76afae6 /src
parent3a91332a70abfc777a352c46727f54426c982371 (diff)
Sockets are now working properly under MSVC. I guess I broke mingw32 though, but we'll fix this later.
Diffstat (limited to 'src')
-rw-r--r--src/Handle.cc4
-rw-r--r--src/Selectable.cc43
-rw-r--r--src/Socket.cc49
3 files changed, 74 insertions, 22 deletions
diff --git a/src/Handle.cc b/src/Handle.cc
index e6c0777..c1542ac 100644
--- a/src/Handle.cc
+++ b/src/Handle.cc
@@ -47,7 +47,7 @@ ssize_t Balau::Handle::write(const void * buf, size_t count) throw (GeneralExcep
}
ssize_t Balau::Handle::forceRead(void * _buf, size_t count, Events::BaseEvent * evt) throw (GeneralException) {
- ssize_t total;
+ ssize_t total = 0;
uint8_t * buf = (uint8_t *) _buf;
if (!canRead())
throw GeneralException("Handle can't read");
@@ -74,7 +74,7 @@ ssize_t Balau::Handle::forceRead(void * _buf, size_t count, Events::BaseEvent *
}
ssize_t Balau::Handle::forceWrite(const void * _buf, size_t count, Events::BaseEvent * evt) throw (GeneralException) {
- ssize_t total;
+ ssize_t total = 0;
const uint8_t * buf = (const uint8_t *) _buf;
if (!canWrite())
throw GeneralException("Handle can't write");
diff --git a/src/Selectable.cc b/src/Selectable.cc
index 40e85bc..798a448 100644
--- a/src/Selectable.cc
+++ b/src/Selectable.cc
@@ -3,6 +3,9 @@
#ifndef _MSC_VER
#include <unistd.h>
#endif
+#ifdef _WIN32
+#include <io.h>
+#endif
#include <fcntl.h>
#include <sys/stat.h>
#include <stdio.h>
@@ -15,7 +18,11 @@
#include "Task.h"
#include "TaskMan.h"
-#ifndef _WIN32
+#ifdef _WIN32
+inline static SOCKET getSocket(int fd) { return _get_osfhandle(fd); }
+#else
+inline static int getSocket(int fd) { return fd; }
+
namespace {
class SigpipeBlocker : public Balau::AtStart {
@@ -60,7 +67,8 @@ void Balau::Selectable::setFD(int fd) throw (GeneralException) {
m_evtW = new SelectableEvent(m_fd, ev::WRITE);
#ifdef _WIN32
u_long iMode = 1;
- ioctlsocket(m_fd, FIONBIO, &iMode);
+ int r = ioctlsocket(_get_osfhandle(m_fd), FIONBIO, &iMode);
+ EAssert(r == NO_ERROR, "ioctlsocket FIONBIO failed with error %i", r);
#else
fcntl(m_fd, F_SETFL, O_NONBLOCK);
#endif
@@ -85,7 +93,7 @@ ssize_t Balau::Selectable::read(void * buf, size_t count) throw (GeneralExceptio
int spins = 0;
do {
- ssize_t r = recv(m_fd, (char *) buf, count, 0);
+ ssize_t r = recv(getSocket(m_fd), (char *) buf, count, 0);
if (r >= 0) {
if (r == 0)
@@ -93,7 +101,19 @@ ssize_t Balau::Selectable::read(void * buf, size_t count) throw (GeneralExceptio
return r;
}
- if ((errno == EAGAIN) || (errno == EINTR) || (errno == EWOULDBLOCK)) {
+#ifndef _WIN32
+ int err = errno;
+#else
+ int err = WSAGetLastError();
+#ifdef _MSC_VER
+ if (err == WSAEWOULDBLOCK)
+#else
+ if (err == WSAWOULDBLOCK)
+#endif
+ err = EAGAIN;
+#endif
+
+ if ((err == EAGAIN) || (err == EINTR) || (err == EWOULDBLOCK)) {
Task::operationYield(m_evtR, Task::INTERRUPTIBLE);
} else {
m_evtR->stop();
@@ -113,7 +133,7 @@ ssize_t Balau::Selectable::write(const void * buf, size_t count) throw (GeneralE
int spins = 0;
do {
- ssize_t r = send(m_fd, (const char *) buf, count, 0);
+ ssize_t r = send(getSocket(m_fd), (const char *) buf, count, 0);
EAssert(r != 0, "send() returned 0 (broken pipe ?)");
@@ -121,13 +141,22 @@ ssize_t Balau::Selectable::write(const void * buf, size_t count) throw (GeneralE
return r;
#ifndef _WIN32
- if (errno == EPIPE) {
+ int err = errno;
+ if (err == EPIPE) {
close();
return 0;
}
+#else
+ int err = WSAGetLastError();
+#ifdef _MSC_VER
+ if (err == WSAEWOULDBLOCK)
+#else
+ if (err == WSAWOULDBLOCK)
+#endif
+ err = EAGAIN;
#endif
- if ((errno == EAGAIN) || (errno == EINTR) || (errno == EWOULDBLOCK)) {
+ if ((err == EAGAIN) || (err == EINTR) || (err == EWOULDBLOCK)) {
Task::operationYield(m_evtW, Task::INTERRUPTIBLE);
} else {
m_evtW->stop();
diff --git a/src/Socket.cc b/src/Socket.cc
index 62fa8bc..7673c45 100644
--- a/src/Socket.cc
+++ b/src/Socket.cc
@@ -1,6 +1,8 @@
#ifndef _WIN32
#include <arpa/inet.h>
#include <sys/socket.h>
+#else
+#include <io.h>
#endif
#include <sys/types.h>
#ifdef _MSC_VER
@@ -19,6 +21,12 @@
#include "Task.h"
#include "TaskMan.h"
+#ifdef _WIN32
+inline static SOCKET getSocket(int fd) { return _get_osfhandle(fd); }
+#else
+inline static int getSocket(int fd) { return fd; }
+#endif
+
static Balau::String getErrorMessage() {
Balau::String msg;
#ifdef _WIN32
@@ -198,7 +206,11 @@ static Balau::DNSRequest * resolveName(const char * name, const char * service =
}
Balau::Socket::Socket() throw (GeneralException) {
+#ifdef _WIN32
+ int fd = _open_osfhandle(WSASocket(AF_INET6, SOCK_STREAM, 0, 0, 0, 0), 0);
+#else
int fd = socket(AF_INET6, SOCK_STREAM, 0);
+#endif
m_name = "Socket(nonconnected)";
RAssert(fd >= 0, "socket() returned %i", fd);
@@ -206,7 +218,7 @@ Balau::Socket::Socket() throw (GeneralException) {
setFD(fd);
int on = 0;
- int r = setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &on, sizeof(on));
+ int r = setsockopt(getSocket(fd), IPPROTO_IPV6, IPV6_V6ONLY, (char *)&on, sizeof(on));
EAssert(r == 0, "setsockopt returned %i", r);
memset(&m_localAddr, 0, sizeof(m_localAddr));
@@ -244,7 +256,7 @@ void Balau::Socket::close() throw (GeneralException) {
if (isClosed())
return;
#ifdef _WIN32
- closesocket(getFD());
+ _close(getFD());
#else
::close(getFD());
#endif
@@ -309,7 +321,7 @@ bool Balau::Socket::setLocal(const char * hostname, int port) {
int enable = 1;
setsockopt(getFD(), SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable));
#endif
- return bind(getFD(), (struct sockaddr *) &m_localAddr, sizeof(m_localAddr)) == 0;
+ return bind(getSocket(getFD()), (struct sockaddr *) &m_localAddr, sizeof(m_localAddr)) == 0;
}
#if defined(_WIN32) && !defined(EISCONN)
@@ -375,7 +387,7 @@ bool Balau::Socket::connect(const char * hostname, int port) {
int r;
int err;
if (spins == 0) {
- r = ::connect(getFD(), (sockaddr *) &m_remoteAddr, sizeof(m_remoteAddr));
+ r = ::connect(getSocket(getFD()), (sockaddr *)&m_remoteAddr, sizeof(m_remoteAddr));
#ifdef _WIN32
err = WSAGetLastError();
#else
@@ -383,7 +395,7 @@ bool Balau::Socket::connect(const char * hostname, int port) {
#endif
} else {
socklen_t sLen = sizeof(err);
- int g = getsockopt(getFD(), SOL_SOCKET, SO_ERROR, (char *) &err, &sLen);
+ int g = getsockopt(getSocket(getFD()), SOL_SOCKET, SO_ERROR, (char *) &err, &sLen);
EAssert(g == 0, "getsockopt failed; g = %i", g);
r = err != 0 ? -1 : 0;
}
@@ -394,10 +406,10 @@ bool Balau::Socket::connect(const char * hostname, int port) {
socklen_t len;
len = sizeof(m_localAddr);
- getsockname(getFD(), (sockaddr *) &m_localAddr, &len);
+ getsockname(getSocket(getFD()), (sockaddr *)&m_localAddr, &len);
len = sizeof(m_remoteAddr);
- getpeername(getFD(), (sockaddr *) &m_remoteAddr, &len);
+ getpeername(getSocket(getFD()), (sockaddr *)&m_remoteAddr, &len);
char prtLocal[INET6_ADDRSTRLEN], prtRemote[INET6_ADDRSTRLEN];
const char * rLocal, * rRemote;
@@ -446,13 +458,13 @@ bool Balau::Socket::listen() {
AAssert(!m_connected, "You can't call Socket::listen() on a connected socket");
AAssert(!isClosed(), "You can't call Socket::listen() on a closed socket");
- if (::listen(getFD(), 16) == 0) {
+ if (::listen(getSocket(getFD()), 16) == 0) {
m_listening = true;
socklen_t len;
len = sizeof(m_localAddr);
- getsockname(getFD(), (sockaddr *) &m_localAddr, &len);
+ getsockname(getSocket(getFD()), (sockaddr *)&m_localAddr, &len);
char prtLocal[INET6_ADDRSTRLEN];
const char * rLocal;
@@ -486,13 +498,24 @@ Balau::IO<Balau::Socket> Balau::Socket::accept() throw (GeneralException) {
sockaddr_in6 remoteAddr;
socklen_t len = sizeof(sockaddr_in6);
Printer::elog(E_SOCKET, "Socket %i (%s) is going to accept()", getFD(), m_name.to_charp());
- int s = ::accept(getFD(), (sockaddr *) &remoteAddr, &len);
+#ifdef _WIN32
+ SOCKET s;
+#else
+ int s;
+#endif
+ s = ::accept(getSocket(getFD()), (sockaddr *)&remoteAddr, &len);
+#ifndef _WIN32
if (s < 0) {
int err = errno;
-#ifdef _WIN32
- err = WSAGetLastError();
+#else
+ if (s == INVALID_SOCKET) {
+ int err = WSAGetLastError();
+#ifdef _MSC_VER
if (err == WSAEWOULDBLOCK)
+#else
+ if (err == WSAWOULDBLOCK)
+#endif
err = EAGAIN;
#endif
if ((err == EAGAIN) || (err == EINTR) || (err == EWOULDBLOCK)) {
@@ -504,7 +527,7 @@ Balau::IO<Balau::Socket> Balau::Socket::accept() throw (GeneralException) {
} else {
Printer::elog(E_SOCKET, "Listener at %p got a new connection", this);
m_evtR->reset();
- return IO<Socket>(new Socket(s));
+ return IO<Socket>(new Socket(_open_osfhandle(s, 0)));
}
}
}