#include <windows.h>
#define SHUT_RDWR SD_BOTH
+ #ifndef _SSIZE_T_DEFINED
+ typedef int ssize_t;
+ #endif
+ typedef int fsize_t;
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <netdb.h>
#include <unistd.h>
+ typedef size_t fsize_t;
#endif
#include <stddef.h>
#include "mruby/variable.h"
#include "error.h"
+#include "mruby/ext/io.h"
+
#define E_SOCKET_ERROR (mrb_class_get(mrb, "SocketError"))
#if !defined(mrb_cptr)
@@@ -138,23 -131,23 +138,27 @@@ mrb_addrinfo_getaddrinfo(mrb_state *mrb
}
memset(&hints, 0, sizeof(hints));
- hints.ai_flags = flags;
+ hints.ai_flags = (int)flags;
if (mrb_fixnum_p(family)) {
- hints.ai_family = mrb_fixnum(family);
+ hints.ai_family = (int)mrb_fixnum(family);
}
if (mrb_fixnum_p(socktype)) {
- hints.ai_socktype = mrb_fixnum(socktype);
+ hints.ai_socktype = (int)mrb_fixnum(socktype);
+ }
+
+ if (mrb_fixnum_p(protocol)) {
+ hints.ai_protocol = (int)mrb_fixnum(protocol);
}
+ if (mrb_fixnum_p(protocol)) {
+ hints.ai_protocol = mrb_fixnum(protocol);
+ }
+
lastai = mrb_cv_get(mrb, klass, mrb_intern_lit(mrb, "_lastai"));
if (mrb_cptr_p(lastai)) {
- freeaddrinfo(mrb_cptr(lastai));
+ freeaddrinfo((struct addrinfo*)mrb_cptr(lastai));
mrb_cv_set(mrb, klass, mrb_intern_lit(mrb, "_lastai"), mrb_nil_value());
}
mrb_cv_set(mrb, klass, mrb_intern_lit(mrb, "_lastai"), mrb_cptr_value(mrb, res0));
for (res = res0; res != NULL; res = res->ai_next) {
- sa = mrb_str_new(mrb, (void *)res->ai_addr, res->ai_addrlen);
+ sa = mrb_str_new(mrb, (char*)res->ai_addr, res->ai_addrlen);
ai = mrb_funcall(mrb, klass, "new", 4, sa, mrb_fixnum_value(res->ai_family), mrb_fixnum_value(res->ai_socktype), mrb_fixnum_value(res->ai_protocol));
mrb_ary_push(mrb, ary, ai);
mrb_gc_arena_restore(mrb, arena_idx);
@@@ -193,7 -186,7 +197,7 @@@ mrb_addrinfo_getnameinfo(mrb_state *mrb
if (!mrb_string_p(sastr)) {
mrb_raise(mrb, E_SOCKET_ERROR, "invalid sockaddr");
}
- error = getnameinfo((struct sockaddr *)RSTRING_PTR(sastr), (socklen_t)RSTRING_LEN(sastr), RSTRING_PTR(host), NI_MAXHOST, RSTRING_PTR(serv), NI_MAXSERV, flags);
+ error = getnameinfo((struct sockaddr *)RSTRING_PTR(sastr), (socklen_t)RSTRING_LEN(sastr), RSTRING_PTR(host), NI_MAXHOST, RSTRING_PTR(serv), NI_MAXSERV, (int)flags);
if (error != 0) {
mrb_raisef(mrb, E_SOCKET_ERROR, "getnameinfo: %s", gai_strerror(error));
}
@@@ -254,7 -247,7 +258,7 @@@ sa2addrlist(mrb_state *mrb, const struc
static int
socket_fd(mrb_state *mrb, mrb_value sock)
{
- return mrb_fixnum(mrb_funcall(mrb, sock, "fileno", 0));
+ return (int)mrb_fixnum(mrb_funcall(mrb, sock, "fileno", 0));
}
static int
@@@ -302,7 -295,7 +306,7 @@@ mrb_basicsocket_getpeername(mrb_state *
if (getpeername(socket_fd(mrb, self), (struct sockaddr *)&ss, &salen) != 0)
mrb_sys_fail(mrb, "getpeername");
- return mrb_str_new(mrb, (void *)&ss, salen);
+ return mrb_str_new(mrb, (char*)&ss, salen);
}
static mrb_value
@@@ -315,7 -308,7 +319,7 @@@ mrb_basicsocket_getsockname(mrb_state *
if (getsockname(socket_fd(mrb, self), (struct sockaddr *)&ss, &salen) != 0)
mrb_sys_fail(mrb, "getsockname");
- return mrb_str_new(mrb, (void *)&ss, salen);
+ return mrb_str_new(mrb, (char*)&ss, salen);
}
static mrb_value
@@@ -330,7 -323,7 +334,7 @@@ mrb_basicsocket_getsockopt(mrb_state *m
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, (int)level, (int)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);
static mrb_value
mrb_basicsocket_recv(mrb_state *mrb, mrb_value self)
{
- int n;
+ ssize_t n;
mrb_int maxlen, flags = 0;
mrb_value buf;
mrb_get_args(mrb, "i|i", &maxlen, &flags);
buf = mrb_str_buf_new(mrb, maxlen);
- n = recv(socket_fd(mrb, self), RSTRING_PTR(buf), maxlen, flags);
+ n = recv(socket_fd(mrb, self), RSTRING_PTR(buf), (fsize_t)maxlen, (int)flags);
if (n == -1)
mrb_sys_fail(mrb, "recv");
- mrb_str_resize(mrb, buf, n);
+ mrb_str_resize(mrb, buf, (mrb_int)n);
return buf;
}
static mrb_value
mrb_basicsocket_recvfrom(mrb_state *mrb, mrb_value self)
{
- int n;
+ ssize_t n;
mrb_int maxlen, flags = 0;
mrb_value ary, buf, sa;
socklen_t socklen;
buf = mrb_str_buf_new(mrb, maxlen);
socklen = sizeof(struct sockaddr_storage);
sa = mrb_str_buf_new(mrb, socklen);
- n = recvfrom(socket_fd(mrb, self), RSTRING_PTR(buf), maxlen, flags, (struct sockaddr *)RSTRING_PTR(sa), &socklen);
+ n = recvfrom(socket_fd(mrb, self), RSTRING_PTR(buf), (fsize_t)maxlen, (int)flags, (struct sockaddr *)RSTRING_PTR(sa), &socklen);
if (n == -1)
mrb_sys_fail(mrb, "recvfrom");
- mrb_str_resize(mrb, buf, n);
- mrb_str_resize(mrb, sa, socklen);
+ mrb_str_resize(mrb, buf, (mrb_int)n);
+ mrb_str_resize(mrb, sa, (mrb_int)socklen);
ary = mrb_ary_new_capa(mrb, 2);
mrb_ary_push(mrb, ary, buf);
mrb_ary_push(mrb, ary, sa);
static mrb_value
mrb_basicsocket_send(mrb_state *mrb, mrb_value self)
{
- int n;
+ ssize_t n;
mrb_int flags;
mrb_value dest, mesg;
dest = mrb_nil_value();
mrb_get_args(mrb, "Si|S", &mesg, &flags, &dest);
if (mrb_nil_p(dest)) {
- n = send(socket_fd(mrb, self), RSTRING_PTR(mesg), RSTRING_LEN(mesg), flags);
+ n = send(socket_fd(mrb, self), RSTRING_PTR(mesg), (fsize_t)RSTRING_LEN(mesg), (int)flags);
} else {
- n = sendto(socket_fd(mrb, self), RSTRING_PTR(mesg), RSTRING_LEN(mesg), flags, (const void *)RSTRING_PTR(dest), RSTRING_LEN(dest));
+ n = sendto(socket_fd(mrb, self), RSTRING_PTR(mesg), (fsize_t)RSTRING_LEN(mesg), (int)flags, (const struct sockaddr*)RSTRING_PTR(dest), (fsize_t)RSTRING_LEN(dest));
}
if (n == -1)
mrb_sys_fail(mrb, "send");
- return mrb_fixnum_value(n);
+ return mrb_fixnum_value((mrb_int)n);
}
static mrb_value
mrb_basicsocket_setnonblock(mrb_state *mrb, mrb_value self)
{
int fd, flags;
- mrb_value bool;
+ mrb_bool nonblocking;
#ifdef _WIN32
u_long mode = 1;
#endif
- mrb_get_args(mrb, "o", &bool);
+ mrb_get_args(mrb, "b", &nonblocking);
fd = socket_fd(mrb, self);
#ifdef _WIN32
flags = ioctlsocket(fd, FIONBIO, &mode);
flags = fcntl(fd, F_GETFL, 0);
if (flags == 1)
mrb_sys_fail(mrb, "fcntl");
- if (mrb_test(bool))
+ if (nonblocking)
flags |= O_NONBLOCK;
else
flags &= ~O_NONBLOCK;
static mrb_value
mrb_basicsocket_setsockopt(mrb_state *mrb, mrb_value self)
{
- int argc, s;
- mrb_int level = 0, optname;
+ int s;
+ mrb_int argc, level = 0, optname;
mrb_value optval, so;
argc = mrb_get_args(mrb, "o|io", &so, &optname, &optval);
/* that's good */
} else if (mrb_type(optval) == MRB_TT_TRUE || mrb_type(optval) == MRB_TT_FALSE) {
mrb_int i = mrb_test(optval) ? 1 : 0;
- optval = mrb_str_new(mrb, (char *)&i, sizeof(i));
+ optval = mrb_str_new(mrb, (char*)&i, sizeof(i));
} else if (mrb_fixnum_p(optval)) {
if (optname == IP_MULTICAST_TTL || optname == IP_MULTICAST_LOOP) {
- char uc = mrb_fixnum(optval);
+ char uc = (char)mrb_fixnum(optval);
optval = mrb_str_new(mrb, &uc, sizeof(uc));
} else {
mrb_int i = mrb_fixnum(optval);
- optval = mrb_str_new(mrb, (char *)&i, sizeof(i));
+ optval = mrb_str_new(mrb, (char*)&i, sizeof(i));
}
} else {
mrb_raise(mrb, E_ARGUMENT_ERROR, "optval should be true, false, an integer, or a string");
}
s = socket_fd(mrb, self);
- if (setsockopt(s, level, optname, RSTRING_PTR(optval), RSTRING_LEN(optval)) == -1)
+ if (setsockopt(s, (int)level, (int)optname, RSTRING_PTR(optval), (socklen_t)RSTRING_LEN(optval)) == -1)
mrb_sys_fail(mrb, "setsockopt");
return mrb_fixnum_value(0);
}
@@@ -476,27 -469,12 +480,27 @@@ mrb_basicsocket_shutdown(mrb_state *mrb
mrb_int how = SHUT_RDWR;
mrb_get_args(mrb, "|i", &how);
- if (shutdown(socket_fd(mrb, self), how) != 0)
+ if (shutdown(socket_fd(mrb, self), (int)how) != 0)
mrb_sys_fail(mrb, "shutdown");
return mrb_fixnum_value(0);
}
static mrb_value
+mrb_basicsocket_set_is_socket(mrb_state *mrb, mrb_value self)
+{
+ mrb_bool b;
+ struct mrb_io *io_p;
+ mrb_get_args(mrb, "b", &b);
+
+ io_p = (struct mrb_io*)DATA_PTR(self);
+ if (io_p) {
+ io_p->is_socket = b;
+ }
+
+ return mrb_bool_value(b);
+}
+
+static mrb_value
mrb_ipsocket_ntop(mrb_state *mrb, mrb_value klass)
{
mrb_int af, n;
mrb_get_args(mrb, "is", &af, &addr, &n);
if ((af == AF_INET && n != 4) || (af == AF_INET6 && n != 16))
mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid address");
- if (inet_ntop(af, addr, buf, sizeof(buf)) == NULL)
+ if (inet_ntop((int)af, addr, buf, sizeof(buf)) == NULL)
mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid address");
return mrb_str_new_cstr(mrb, buf);
}
@@@ -517,7 -495,7 +521,7 @@@ mrb_ipsocket_pton(mrb_state *mrb, mrb_v
char *bp, buf[50];
mrb_get_args(mrb, "is", &af, &bp, &n);
- if (n > sizeof(buf) - 1)
+ if ((size_t)n > sizeof(buf) - 1)
mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid address");
memcpy(buf, bp, n);
buf[n] = '\0';
struct in_addr in;
if (inet_pton(AF_INET, buf, (void *)&in.s_addr) != 1)
goto invalid;
- return mrb_str_new(mrb, (char *)&in.s_addr, 4);
+ return mrb_str_new(mrb, (char*)&in.s_addr, 4);
} else if (af == AF_INET6) {
struct in6_addr in6;
if (inet_pton(AF_INET6, buf, (void *)&in6.s6_addr) != 1)
goto invalid;
- return mrb_str_new(mrb, (char *)&in6.s6_addr, 16);
+ return mrb_str_new(mrb, (char*)&in6.s6_addr, 16);
} else
mrb_raise(mrb, E_ARGUMENT_ERROR, "unsupported address family");
@@@ -546,8 -524,7 +550,8 @@@ mrb_ipsocket_recvfrom(mrb_state *mrb, m
struct sockaddr_storage ss;
socklen_t socklen;
mrb_value a, buf, pair;
- mrb_int flags, maxlen, n;
+ mrb_int flags, maxlen;
+ ssize_t n;
int fd;
fd = socket_fd(mrb, self);
mrb_get_args(mrb, "i|i", &maxlen, &flags);
buf = mrb_str_buf_new(mrb, maxlen);
socklen = sizeof(ss);
- n = recvfrom(fd, RSTRING_PTR(buf), maxlen, flags,
+ n = recvfrom(fd, RSTRING_PTR(buf), (fsize_t)maxlen, (int)flags,
(struct sockaddr *)&ss, &socklen);
if (n == -1) {
mrb_sys_fail(mrb, "recvfrom");
}
- mrb_str_resize(mrb, buf, n);
+ mrb_str_resize(mrb, buf, (mrb_int)n);
a = sa2addrlist(mrb, (struct sockaddr *)&ss, socklen);
pair = mrb_ary_new_capa(mrb, 2);
mrb_ary_push(mrb, pair, buf);
@@@ -579,10 -556,10 +583,10 @@@ mrb_socket_gethostname(mrb_state *mrb,
#else
bufsize = 256;
#endif
- buf = mrb_str_buf_new(mrb, bufsize);
- if (gethostname(RSTRING_PTR(buf), bufsize) != 0)
+ buf = mrb_str_buf_new(mrb, (mrb_int)bufsize);
+ if (gethostname(RSTRING_PTR(buf), (fsize_t)bufsize) != 0)
mrb_sys_fail(mrb, "gethostname");
- mrb_str_resize(mrb, buf, strlen(RSTRING_PTR(buf)));
+ mrb_str_resize(mrb, buf, (mrb_int)strlen(RSTRING_PTR(buf)));
return buf;
}
@@@ -597,7 -574,7 +601,7 @@@ mrb_socket_accept(mrb_state *mrb, mrb_v
mrb_get_args(mrb, "i", &s0);
socklen = sizeof(struct sockaddr_storage);
sastr = mrb_str_buf_new(mrb, socklen);
- s1 = accept(s0, (struct sockaddr *)RSTRING_PTR(sastr), &socklen);
+ s1 = (int)accept(s0, (struct sockaddr *)RSTRING_PTR(sastr), &socklen);
if (s1 == -1) {
mrb_sys_fail(mrb, "accept");
}
@@@ -654,11 -631,11 +658,11 @@@ mrb_socket_sockaddr_family(mrb_state *m
mrb_get_args(mrb, "S", &sa);
#ifdef __linux__
- if (RSTRING_LEN(sa) < offsetof(struct sockaddr, sa_family) + sizeof(sa_family_t)) {
+ if ((size_t)RSTRING_LEN(sa) < offsetof(struct sockaddr, sa_family) + sizeof(sa_family_t)) {
mrb_raisef(mrb, E_SOCKET_ERROR, "invalid sockaddr (too short)");
}
#else
- if (RSTRING_LEN(sa) < sizeof(struct sockaddr)) {
+ if ((size_t)RSTRING_LEN(sa) < sizeof(struct sockaddr)) {
mrb_raisef(mrb, E_SOCKET_ERROR, "invalid sockaddr (too short)");
}
#endif
@@@ -676,7 -653,7 +680,7 @@@ mrb_socket_sockaddr_un(mrb_state *mrb,
mrb_value path, s;
mrb_get_args(mrb, "S", &path);
- if (RSTRING_LEN(path) > sizeof(sunp->sun_path) - 1) {
+ if ((size_t)RSTRING_LEN(path) > sizeof(sunp->sun_path) - 1) {
mrb_raisef(mrb, E_ARGUMENT_ERROR, "too long unix socket path (max: %ubytes)", (unsigned int)sizeof(sunp->sun_path) - 1);
}
s = mrb_str_buf_new(mrb, sizeof(struct sockaddr_un));
@@@ -719,7 -696,7 +723,7 @@@ mrb_socket_socket(mrb_state *mrb, mrb_v
int s;
mrb_get_args(mrb, "iii", &domain, &type, &protocol);
- s = socket(domain, type, protocol);
+ s = (int)socket((int)domain, (int)type, (int)protocol);
if (s == -1)
mrb_sys_fail(mrb, "socket");
return mrb_fixnum_value(s);
@@@ -771,7 -748,7 +775,7 @@@ mrb_win32_basicsocket_sysread(mrb_stat
}
sd = socket_fd(mrb, self);
- ret = recv(sd, RSTRING_PTR(buf), maxlen, 0);
+ ret = recv(sd, RSTRING_PTR(buf), (int)maxlen, 0);
switch (ret) {
case 0: /* EOF */
@@@ -810,7 -787,7 +814,7 @@@ mrb_win32_basicsocket_syswrite(mrb_stat
sd = socket_fd(mrb, self);
mrb_get_args(mrb, "S", &str);
- n = send(sd, RSTRING_PTR(str), RSTRING_LEN(str), 0);
+ n = send(sd, RSTRING_PTR(str), (int)RSTRING_LEN(str), 0);
if (n == SOCKET_ERROR)
mrb_sys_fail(mrb, "send");
return mrb_fixnum_value(n);
@@@ -830,6 -807,8 +834,6 @@@ mrb_mruby_socket_gem_init(mrb_state* mr
result = WSAStartup(MAKEWORD(2,2), &wsaData);
if (result != NO_ERROR)
mrb_raise(mrb, E_RUNTIME_ERROR, "WSAStartup failed");
-#else
- struct RClass *usock;
#endif
ai = mrb_define_class(mrb, "Addrinfo", mrb->object_class);
// #sendmsg_nonblock
mrb_define_method(mrb, bsock, "setsockopt", mrb_basicsocket_setsockopt, MRB_ARGS_REQ(1)|MRB_ARGS_OPT(2));
mrb_define_method(mrb, bsock, "shutdown", mrb_basicsocket_shutdown, MRB_ARGS_OPT(1));
+ mrb_define_method(mrb, bsock, "_is_socket=", mrb_basicsocket_set_is_socket, MRB_ARGS_REQ(1));
ipsock = mrb_define_class(mrb, "IPSocket", bsock);
mrb_define_class_method(mrb, ipsock, "ntop", mrb_ipsocket_ntop, MRB_ARGS_REQ(1));
//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(mrb, "UNIXSocket", bsock);
//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));
//mrb_define_method(mrb, usock, "recv_io", mrb_unixsocket_peeraddr, MRB_ARGS_NONE());
//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());
+#endif
/* Windows IO Method Overrides on BasicSocket */
#ifdef _WIN32
@@@ -920,7 -898,7 +924,7 @@@ mrb_mruby_socket_gem_final(mrb_state* m
mrb_value ai;
ai = mrb_mod_cv_get(mrb, mrb_class_get(mrb, "Addrinfo"), mrb_intern_lit(mrb, "_lastai"));
if (mrb_cptr_p(ai)) {
- freeaddrinfo(mrb_cptr(ai));
+ freeaddrinfo((struct addrinfo*)mrb_cptr(ai));
}
#ifdef _WIN32
WSACleanup();