From 752f7c1526ab2eace3c8d49cc73f963b00e1c3c7 Mon Sep 17 00:00:00 2001 From: Rubyist Date: Fri, 17 Jul 2015 23:45:02 -0700 Subject: Minimal semi-working compile on Windows platforms. --- src/socket.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 62 insertions(+), 15 deletions(-) (limited to 'src') 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 -#include -#include -#include -#include -#include -#include -#include +#ifdef _WIN32 + #include + #include + #include + + #define SHUT_RDWR SD_BOTH +#else + #include + #include + #include + #include + #include + #include + #include + #include + #include +#endif + #include #include -#include +#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 } -- cgit v1.2.3 From a426f0e2b580ce4c7335c4040458b1239148b6e2 Mon Sep 17 00:00:00 2001 From: Rubyist Date: Sat, 18 Jul 2015 23:22:57 -0700 Subject: Overrided close and write to work on Win32 platforms --- src/socket.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'src') diff --git a/src/socket.c b/src/socket.c index 506142f3f..00f1c6ce4 100644 --- a/src/socket.c +++ b/src/socket.c @@ -649,6 +649,37 @@ mrb_tcpsocket_allocate(mrb_state *mrb, mrb_value klass) return mrb_obj_value((struct RObject*)mrb_obj_alloc(mrb, ttype, c)); } +/* Windows overrides for IO methods on BasicSocket objects. + * This is because sockets on Windows are not the same as file + * descriptors, and thus functions which operate on file descriptors + * will break on socket descriptors. + */ +#ifdef _WIN32 +static mrb_value +mrb_win32_basicsocket_close(mrb_state *mrb, mrb_value self) +{ + if (closesocket(socket_fd(mrb, self)) != NO_ERROR) + mrb_sys_fail(mrb, "closesocket"); + return mrb_nil_value(); +} + +static mrb_value +mrb_win32_basicsocket_write(mrb_state *mrb, mrb_value self) +{ + int n; + SOCKET sd; + mrb_value str; + + sd = socket_fd(mrb, self); + mrb_get_args(mrb, "S", &str); + n = send(sd, RSTRING_PTR(str), RSTRING_LEN(str), 0); + if (n == SOCKET_ERROR) + mrb_sys_fail(mrb, "write"); + return mrb_fixnum_value(n); +} + +#endif + void mrb_mruby_socket_gem_init(mrb_state* mrb) { @@ -728,6 +759,12 @@ mrb_mruby_socket_gem_init(mrb_state* mrb) //mrb_define_method(mrb, usock, "recvfrom", mrb_unixsocket_peeraddr, MRB_ARGS_NONE()); //mrb_define_method(mrb, usock, "send_io", mrb_unixsocket_peeraddr, MRB_ARGS_NONE()); + /* Windows IO Method Overrides on BasicSocket */ +#ifdef _WIN32 + mrb_define_method(mrb, bsock, "close", mrb_win32_basicsocket_close, MRB_ARGS_NONE()); + mrb_define_method(mrb, bsock, "write", mrb_win32_basicsocket_write, MRB_ARGS_REQ(1)); +#endif + constants = mrb_define_module_under(mrb, sock, "Constants"); #define define_const(SYM) \ -- cgit v1.2.3 From 7ee9ab89f9577130fc15e6d0934655aa1f4df124 Mon Sep 17 00:00:00 2001 From: Rubyist Date: Tue, 21 Jul 2015 03:37:28 -0700 Subject: Changed some uses of mrb_sys_fail to instead use mrb_raise where appropriate --- src/socket.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/socket.c b/src/socket.c index 00f1c6ce4..277e221ee 100644 --- a/src/socket.c +++ b/src/socket.c @@ -582,7 +582,7 @@ static mrb_value mrb_socket_sockaddr_un(mrb_state *mrb, mrb_value klass) { #ifdef _WIN32 - mrb_sys_fail(mrb, "sockaddr_un unsupported on Windows"); + mrb_raise(mrb, E_NOTIMP_ERROR, "sockaddr_un unsupported on Windows"); return mrb_nil_value(); #else struct sockaddr_un *sunp; @@ -606,7 +606,7 @@ static mrb_value mrb_socket_socketpair(mrb_state *mrb, mrb_value klass) { #ifdef _WIN32 - mrb_sys_fail(mrb, "socketpair unsupported on Windows"); + mrb_raise(mrb, E_NOTIMP_ERROR, "socketpair unsupported on Windows"); return mrb_nil_value(); #else mrb_value ary; @@ -659,7 +659,7 @@ static mrb_value mrb_win32_basicsocket_close(mrb_state *mrb, mrb_value self) { if (closesocket(socket_fd(mrb, self)) != NO_ERROR) - mrb_sys_fail(mrb, "closesocket"); + mrb_sys_fail(mrb, "close"); return mrb_nil_value(); } @@ -691,7 +691,7 @@ mrb_mruby_socket_gem_init(mrb_state* mrb) int result; result = WSAStartup(MAKEWORD(2,2), &wsaData); if (result != NO_ERROR) - mrb_sys_fail(mrb, "WSAStartup"); + mrb_raise(mrb, E_RUNTIME_ERROR, "WSAStartup failed"); #else struct RClass *usock; #endif -- cgit v1.2.3 From 4ab922044de80da5e6167799d070cec2e73b4204 Mon Sep 17 00:00:00 2001 From: Rubyist Date: Tue, 21 Jul 2015 15:56:27 -0700 Subject: Removed unnecessary/incorrect use of sizeof(int) and corrected more improper usages of mrb_sys_fail --- src/socket.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/socket.c b/src/socket.c index 277e221ee..fc2abed5b 100644 --- a/src/socket.c +++ b/src/socket.c @@ -255,7 +255,7 @@ mrb_basicsocket_getsockname(mrb_state *mrb, mrb_value self) static mrb_value mrb_basicsocket_getsockopt(mrb_state *mrb, mrb_value self) { - char opt[4]; + char opt[8]; int s; mrb_int family, level, optname; mrb_value c, data; @@ -268,7 +268,7 @@ mrb_basicsocket_getsockopt(mrb_state *mrb, mrb_value self) 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, opt, sizeof(int)); + data = mrb_str_new(mrb, opt, optlen); return mrb_funcall(mrb, c, "new", 4, mrb_fixnum_value(family), mrb_fixnum_value(level), mrb_fixnum_value(optname), data); } @@ -659,7 +659,7 @@ static mrb_value mrb_win32_basicsocket_close(mrb_state *mrb, mrb_value self) { if (closesocket(socket_fd(mrb, self)) != NO_ERROR) - mrb_sys_fail(mrb, "close"); + mrb_raise(mrb, E_SOCKET_ERROR, "closesocket unsuccessful"); return mrb_nil_value(); } @@ -674,7 +674,7 @@ mrb_win32_basicsocket_write(mrb_state *mrb, mrb_value self) mrb_get_args(mrb, "S", &str); n = send(sd, RSTRING_PTR(str), RSTRING_LEN(str), 0); if (n == SOCKET_ERROR) - mrb_sys_fail(mrb, "write"); + mrb_sys_fail(mrb, "send"); return mrb_fixnum_value(n); } -- cgit v1.2.3