summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/socket.c77
1 files changed, 62 insertions, 15 deletions
diff --git a/src/socket.c b/src/socket.c
index bdfada7b5..506142f3f 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -4,19 +4,28 @@
** See Copyright Notice in mruby.h
*/
-#include "mruby.h"
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <arpa/inet.h>
-#include <fcntl.h>
-#include <netdb.h>
+#ifdef _WIN32
+ #include <winsock2.h>
+ #include <ws2tcpip.h>
+ #include <windows.h>
+
+ #define SHUT_RDWR SD_BOTH
+#else
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <sys/un.h>
+ #include <netinet/in.h>
+ #include <netinet/tcp.h>
+ #include <arpa/inet.h>
+ #include <fcntl.h>
+ #include <netdb.h>
+ #include <unistd.h>
+#endif
+
#include <stddef.h>
#include <string.h>
-#include <unistd.h>
+#include "mruby.h"
#include "mruby/array.h"
#include "mruby/class.h"
#include "mruby/data.h"
@@ -130,6 +139,7 @@ mrb_addrinfo_getnameinfo(mrb_state *mrb, mrb_value self)
return ary;
}
+#ifndef _WIN32
static mrb_value
mrb_addrinfo_unix_path(mrb_state *mrb, mrb_value self)
{
@@ -140,6 +150,7 @@ mrb_addrinfo_unix_path(mrb_state *mrb, mrb_value self)
mrb_raise(mrb, E_SOCKET_ERROR, "need AF_UNIX address");
return mrb_str_new_cstr(mrb, ((struct sockaddr_un *)RSTRING_PTR(sastr))->sun_path);
}
+#endif
static mrb_value
sa2addrlist(mrb_state *mrb, const struct sockaddr *sa, socklen_t salen)
@@ -244,7 +255,8 @@ mrb_basicsocket_getsockname(mrb_state *mrb, mrb_value self)
static mrb_value
mrb_basicsocket_getsockopt(mrb_state *mrb, mrb_value self)
{
- int opt, s;
+ char opt[4];
+ int s;
mrb_int family, level, optname;
mrb_value c, data;
socklen_t optlen;
@@ -252,11 +264,11 @@ mrb_basicsocket_getsockopt(mrb_state *mrb, mrb_value self)
mrb_get_args(mrb, "ii", &level, &optname);
s = socket_fd(mrb, self);
optlen = sizeof(opt);
- if (getsockopt(s, level, optname, &opt, &optlen) == -1)
+ if (getsockopt(s, level, optname, opt, &optlen) == -1)
mrb_sys_fail(mrb, "getsockopt");
c = mrb_const_get(mrb, mrb_obj_value(mrb_class_get(mrb, "Socket")), mrb_intern_lit(mrb, "Option"));
family = socket_family(s);
- data = mrb_str_new(mrb, (char *)&opt, sizeof(int));
+ data = mrb_str_new(mrb, opt, sizeof(int));
return mrb_funcall(mrb, c, "new", 4, mrb_fixnum_value(family), mrb_fixnum_value(level), mrb_fixnum_value(optname), data);
}
@@ -323,10 +335,17 @@ mrb_basicsocket_setnonblock(mrb_state *mrb, mrb_value self)
{
int fd, flags;
mrb_value bool;
+#ifdef _WIN32
+ u_long mode = 1;
+#endif
mrb_get_args(mrb, "o", &bool);
fd = socket_fd(mrb, self);
-
+#ifdef _WIN32
+ flags = ioctlsocket(fd, FIONBIO, &mode);
+ if (flags != NO_ERROR)
+ mrb_sys_fail(mrb, "ioctlsocket");
+#else
flags = fcntl(fd, F_GETFL, 0);
if (flags == 1)
mrb_sys_fail(mrb, "fcntl");
@@ -336,6 +355,7 @@ mrb_basicsocket_setnonblock(mrb_state *mrb, mrb_value self)
flags &= ~O_NONBLOCK;
if (fcntl(fd, F_SETFL, flags) == -1)
mrb_sys_fail(mrb, "fcntl");
+#endif
return mrb_nil_value();
}
@@ -561,6 +581,10 @@ mrb_socket_sockaddr_family(mrb_state *mrb, mrb_value klass)
static mrb_value
mrb_socket_sockaddr_un(mrb_state *mrb, mrb_value klass)
{
+#ifdef _WIN32
+ mrb_sys_fail(mrb, "sockaddr_un unsupported on Windows");
+ return mrb_nil_value();
+#else
struct sockaddr_un *sunp;
mrb_value path, s;
@@ -575,11 +599,16 @@ mrb_socket_sockaddr_un(mrb_state *mrb, mrb_value klass)
sunp->sun_path[RSTRING_LEN(path)] = '\0';
mrb_str_resize(mrb, s, sizeof(struct sockaddr_un));
return s;
+#endif
}
static mrb_value
mrb_socket_socketpair(mrb_state *mrb, mrb_value klass)
{
+#ifdef _WIN32
+ mrb_sys_fail(mrb, "socketpair unsupported on Windows");
+ return mrb_nil_value();
+#else
mrb_value ary;
mrb_int domain, type, protocol;
int sv[2];
@@ -593,6 +622,7 @@ mrb_socket_socketpair(mrb_state *mrb, mrb_value klass)
mrb_ary_push(mrb, ary, mrb_fixnum_value(sv[0]));
mrb_ary_push(mrb, ary, mrb_fixnum_value(sv[1]));
return ary;
+#endif
}
static mrb_value
@@ -622,14 +652,26 @@ mrb_tcpsocket_allocate(mrb_state *mrb, mrb_value klass)
void
mrb_mruby_socket_gem_init(mrb_state* mrb)
{
- struct RClass *io, *ai, *sock, *bsock, *ipsock, *tcpsock, *udpsock, *usock;
+ struct RClass *io, *ai, *sock, *bsock, *ipsock, *tcpsock, *udpsock;
struct RClass *constants;
+#ifdef _WIN32
+ WSADATA wsaData;
+ int result;
+ result = WSAStartup(MAKEWORD(2,2), &wsaData);
+ if (result != NO_ERROR)
+ mrb_sys_fail(mrb, "WSAStartup");
+#else
+ struct RClass *usock;
+#endif
+
ai = mrb_define_class(mrb, "Addrinfo", mrb->object_class);
mrb_mod_cv_set(mrb, ai, mrb_intern_lit(mrb, "_lastai"), mrb_nil_value());
mrb_define_class_method(mrb, ai, "getaddrinfo", mrb_addrinfo_getaddrinfo, MRB_ARGS_REQ(2)|MRB_ARGS_OPT(4));
mrb_define_method(mrb, ai, "getnameinfo", mrb_addrinfo_getnameinfo, MRB_ARGS_OPT(1));
+#ifndef _WIN32
mrb_define_method(mrb, ai, "unix_path", mrb_addrinfo_unix_path, MRB_ARGS_NONE());
+#endif
io = mrb_class_get(mrb, "IO");
@@ -676,7 +718,9 @@ mrb_mruby_socket_gem_init(mrb_state* mrb)
mrb_define_class_method(mrb, sock, "socketpair", mrb_socket_socketpair, MRB_ARGS_REQ(3));
//mrb_define_method(mrb, sock, "sysaccept", mrb_socket_accept, MRB_ARGS_NONE());
+#ifndef _WIN32
usock = mrb_define_class(mrb, "UNIXSocket", bsock);
+#endif
//mrb_define_class_method(mrb, usock, "pair", mrb_unixsocket_open, MRB_ARGS_OPT(2));
//mrb_define_class_method(mrb, usock, "socketpair", mrb_unixsocket_open, MRB_ARGS_OPT(2));
@@ -702,4 +746,7 @@ mrb_mruby_socket_gem_final(mrb_state* mrb)
if (mrb_cptr_p(ai)) {
freeaddrinfo(mrb_cptr(ai));
}
+#ifdef _WIN32
+ WSACleanup();
+#endif
}