diff options
| -rw-r--r-- | src/socket.c | 77 |
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 } |
