diff options
-rw-r--r-- | includes/BString.h | 6 | ||||
-rw-r--r-- | includes/Selectable.h | 3 | ||||
-rw-r--r-- | msvc-config.h | 2 | ||||
-rw-r--r-- | src/Handle.cc | 4 | ||||
-rw-r--r-- | src/Selectable.cc | 43 | ||||
-rw-r--r-- | src/Socket.cc | 49 |
6 files changed, 84 insertions, 23 deletions
diff --git a/includes/BString.h b/includes/BString.h index 9f68e9a..a4178a4 100644 --- a/includes/BString.h +++ b/includes/BString.h @@ -13,7 +13,11 @@ #include <vector> #ifdef _MSC_VER -typedef size_t ssize_t; +#ifdef _WIN64
+typedef __int64 ssize_t;
+#else /* _WIN64 */
+typedef _W64 int ssize_t;
+#endif /* _WIN64 */
#define printfwarning(a, b) #else #define printfwarning(a, b) __attribute__((format(printf, a, b))) diff --git a/includes/Selectable.h b/includes/Selectable.h index 0cfae0c..b3b5b8c 100644 --- a/includes/Selectable.h +++ b/includes/Selectable.h @@ -1,4 +1,7 @@ #pragma once +#ifdef _WIN32 +#include <windows.h> +#endif #include <Handle.h> #include <TaskMan.h> diff --git a/msvc-config.h b/msvc-config.h index 75474ed..02868b4 100644 --- a/msvc-config.h +++ b/msvc-config.h @@ -34,3 +34,5 @@ #define HAVE_FLOOR 1
#define EV_STAT_ENABLE 0
+
+#define EV_USE_WSASOCKET 1
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))); } } } |