Merge commit '36d016afd663d34607c843d03371bedb71efa34e'
authorTakeshi Watanabe <[email protected]>
Sun, 25 Mar 2018 12:10:11 +0000 (25 21:10 +0900)
committerTakeshi Watanabe <[email protected]>
Sun, 25 Mar 2018 12:10:11 +0000 (25 21:10 +0900)
1  2 
mrbgems/mruby-socket/src/socket.c

    #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>
@@@ -26,7 -22,6 +26,7 @@@
    #include <fcntl.h>
    #include <netdb.h>
    #include <unistd.h>
 +  typedef size_t fsize_t;
  #endif
  
  #include <stddef.h>
@@@ -40,8 -35,6 +40,8 @@@
  #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();