diff options
| -rw-r--r-- | mrblib/socket.rb | 18 | ||||
| -rw-r--r-- | src/socket.c | 14 |
2 files changed, 28 insertions, 4 deletions
diff --git a/mrblib/socket.rb b/mrblib/socket.rb index b8c8b4c18..732a6db8e 100644 --- a/mrblib/socket.rb +++ b/mrblib/socket.rb @@ -224,7 +224,7 @@ end class TCPSocket def initialize(host, service, local_host=nil, local_service=nil) - if self.is_a? TCPServer + if @init_with_fd super(host, service) else s = nil @@ -243,12 +243,20 @@ class TCPSocket end end + def self.new_with_prelude pre, *args + o = self._allocate + o.instance_eval(&pre) + o.initialize(*args) + o + end + #def self.gethostbyname(host) end class TCPServer def initialize(host=nil, service) ai = Addrinfo.getaddrinfo(host, service, nil, nil, nil, Socket::AI_PASSIVE)[0] + @init_with_fd = true super(Socket._socket(ai.afamily, Socket::SOCK_STREAM, 0), "r+") Socket._bind(self.fileno, ai.to_sockaddr) listen(5) @@ -256,7 +264,13 @@ class TCPServer end def accept - TCPSocket.for_fd(self.sysaccept) + fd = self.sysaccept + begin + TCPSocket.new_with_prelude(proc { @init_with_fd = true }, fd, "r+") + rescue + IO._sysclose(fd) rescue nil + raise + end end def accept_nonblock diff --git a/src/socket.c b/src/socket.c index 2cf7ac385..ded5dfa25 100644 --- a/src/socket.c +++ b/src/socket.c @@ -599,6 +599,17 @@ mrb_socket_socket(mrb_state *mrb, mrb_value klass) return mrb_fixnum_value(s); } +static mrb_value +mrb_tcpsocket_allocate(mrb_state *mrb, mrb_value klass) +{ + struct RClass *c = mrb_class_ptr(klass); + enum mrb_vtype ttype = MRB_INSTANCE_TT(c); + + /* copied from mrb_instance_alloc() */ + if (ttype == 0) ttype = MRB_TT_OBJECT; + return mrb_obj_value((struct RObject*)mrb_obj_alloc(mrb, ttype, c)); +} + void mrb_mruby_socket_gem_init(mrb_state* mrb) { @@ -634,8 +645,7 @@ mrb_mruby_socket_gem_init(mrb_state* mrb) mrb_define_method(mrb, ipsock, "recvfrom", mrb_ipsocket_recvfrom, MRB_ARGS_REQ(1)|MRB_ARGS_OPT(1)); tcpsock = mrb_define_class(mrb, "TCPSocket", ipsock); - //mrb_define_class_method(mrb, tcpsock, "open", mrb_tcpsocket_open, MRB_ARGS_REQ(2)|MRB_ARGS_OPT(2)); - //mrb_define_class_method(mrb, tcpsock, "new", mrb_tcpsocket_open, MRB_ARGS_REQ(2)|MRB_ARGS_OPT(2)); + mrb_define_class_method(mrb, tcpsock, "_allocate", mrb_tcpsocket_allocate, MRB_ARGS_NONE()); mrb_define_class(mrb, "TCPServer", tcpsock); udpsock = mrb_define_class(mrb, "UDPSocket", ipsock); |
