#ifdef __MINGW32__
# include <winsock2.h>
+# include <ws2tcpip.h>
#else // __POSIX__
# include <sys/ioctl.h>
return scope.Close(a);
}
+#endif
+
// Creates a new non-blocking socket fd
// t.socket("TCP");
}
}
+#ifdef __POSIX__
int fd = socket(domain, type, 0);
+#else // __MINGW32__
+ int fd = _open_osfhandle(socket(domain, type, 0), 0);
+#endif
if (fd < 0) return ThrowException(ErrnoException(errno, "socket"));
static inline Handle<Value> ParseAddressArgs(Handle<Value> first,
Handle<Value> second,
bool is_bind) {
+#ifdef __POSIX__ // No unix sockets on windows
static struct sockaddr_un un;
+#endif
static struct sockaddr_in in;
static struct sockaddr_in6 in6;
+#ifdef __POSIX__ // No unix sockets on windows
+ static struct sockaddr_un un;
+
if (first->IsString() && !second->IsString()) {
// UNIX
String::Utf8Value path(first->ToString());
addrlen = sizeof(un) - sizeof(un.sun_path) + path.length() + 1;
} else {
+#else // __MINGW32__
+ if (first->IsString() && !second->IsString()) {
+ return ErrnoException(errno, "ParseAddressArgs", "Unix sockets are not supported on windows");
+ } else {
+#endif
// TCP or UDP
memset(&in, 0, sizeof in);
memset(&in6, 0, sizeof in6);
if (!error.IsEmpty()) return ThrowException(error);
int flags = 1;
+#ifdef __POSIX__
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&flags, sizeof(flags));
-
int r = bind(fd, addr, addrlen);
+#else // __MINGW32__
+ setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&flags, sizeof(flags));
+ int r = bind(_get_osfhandle(fd), addr, addrlen);
+#endif
if (r < 0) {
return ThrowException(ErrnoException(errno, "bind"));
return Undefined();
}
-#endif // __POSIX__
-
static Handle<Value> Close(const Arguments& args) {
HandleScope scope;
return Undefined();
}
+#endif // __POSIX__
+
+
+#ifdef __POSIX__
+
#define ADDRESS_TO_JS(info, address_storage) \
do { \
char ip[INET6_ADDRSTRLEN]; \
} \
} while (0)
+#else // __MINGW32__
+
+#define ADDRESS_TO_JS(info, address_storage) \
+do { \
+ char ip[INET6_ADDRSTRLEN]; \
+ int port; \
+ struct sockaddr_in *a4; \
+ struct sockaddr_in6 *a6; \
+ switch ((address_storage).ss_family) { \
+ case AF_INET6: \
+ a6 = (struct sockaddr_in6*)&(address_storage); \
+ inet_ntop(AF_INET6, &(a6->sin6_addr), ip, INET6_ADDRSTRLEN); \
+ port = ntohs(a6->sin6_port); \
+ (info)->Set(address_symbol, String::New(ip)); \
+ (info)->Set(port_symbol, Integer::New(port)); \
+ break; \
+ case AF_INET: \
+ a4 = (struct sockaddr_in*)&(address_storage); \
+ inet_ntop(AF_INET, &(a4->sin_addr), ip, INET6_ADDRSTRLEN); \
+ port = ntohs(a4->sin_port); \
+ (info)->Set(address_symbol, String::New(ip)); \
+ (info)->Set(port_symbol, Integer::New(port)); \
+ break; \
+ default: \
+ (info)->Set(address_symbol, String::Empty()); \
+ } \
+} while (0)
+
+#endif // __MINGW32__
+
+#ifdef __POSIX__
static Handle<Value> GetSockName(const Arguments& args) {
HandleScope scope;
return scope.Close(info);
}
+#endif // __POSIX__
+
static Handle<Value> Listen(const Arguments& args) {
HandleScope scope;
FD_ARG(args[0])
int backlog = args[1]->IsInt32() ? args[1]->Int32Value() : 128;
- if (0 > listen(fd, backlog)) {
+ if (0 > listen(_get_osfhandle(fd), backlog)) {
return ThrowException(ErrnoException(errno, "listen"));
}
struct sockaddr_storage address_storage;
socklen_t len = sizeof(struct sockaddr_storage);
+#ifdef __POSIX__
int peer_fd = accept(fd, (struct sockaddr*) &address_storage, &len);
if (peer_fd < 0) {
if (errno == EAGAIN) return scope.Close(Null());
return ThrowException(ErrnoException(errno, "accept"));
}
+#else // __MINGW32__
+ int peer_handle = accept(_get_osfhandle(fd), (struct sockaddr*) &address_storage, &len);
+
+ if (peer_handle == INVALID_SOCKET) {
+ if (WSAGetLastError() == WSAEWOULDBLOCK) return scope.Close(Null());
+ return ThrowException(ErrnoException(errno, "accept"));
+ }
+
+ int peer_fd = _open_osfhandle(peer_handle, 0);
+#endif // __MINGW32__
if (!SetSockFlags(peer_fd)) {
int fcntl_errno = errno;
}
+#ifdef __POSIX__
+
static Handle<Value> SocketError(const Arguments& args) {
HandleScope scope;
recv_msg_template =
Persistent<FunctionTemplate>::New(FunctionTemplate::New(RecvMsg));
target->Set(String::NewSymbol("recvMsg"), recv_msg_template->GetFunction());
-
- NODE_SET_METHOD(target, "socket", Socket);
#endif //__POSIX__
+ NODE_SET_METHOD(target, "socket", Socket);
NODE_SET_METHOD(target, "close", Close);
#ifdef __POSIX__
NODE_SET_METHOD(target, "socketpair", SocketPair);
NODE_SET_METHOD(target, "connect", Connect);
+#endif // __POSIX__
+
NODE_SET_METHOD(target, "bind", Bind);
NODE_SET_METHOD(target, "listen", Listen);
NODE_SET_METHOD(target, "accept", Accept);
+
+#ifdef __POSIX__
NODE_SET_METHOD(target, "socketError", SocketError);
NODE_SET_METHOD(target, "toRead", ToRead);
NODE_SET_METHOD(target, "setNoDelay", SetNoDelay);