diff options
Diffstat (limited to 'ext/socket/unixsocket.c')
| -rw-r--r-- | ext/socket/unixsocket.c | 53 |
1 files changed, 30 insertions, 23 deletions
diff --git a/ext/socket/unixsocket.c b/ext/socket/unixsocket.c index ecffbd4e92..2ec9376074 100644 --- a/ext/socket/unixsocket.c +++ b/ext/socket/unixsocket.c @@ -10,19 +10,18 @@ #include "rubysocket.h" -#ifdef HAVE_SYS_UN_H +#ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN struct unixsock_arg { struct sockaddr_un *sockaddr; socklen_t sockaddrlen; - int fd; + VALUE io; }; static VALUE unixsock_connect_internal(VALUE a) { struct unixsock_arg *arg = (struct unixsock_arg *)a; - return (VALUE)rsock_connect(arg->fd, (struct sockaddr*)arg->sockaddr, - arg->sockaddrlen, 0, NULL); + return (VALUE)rsock_connect(arg->io, (struct sockaddr*)arg->sockaddr, arg->sockaddrlen, 0, RUBY_IO_TIMEOUT_DEFAULT); } static VALUE @@ -43,11 +42,16 @@ unixsock_path_value(VALUE path) } } #endif - return rb_get_path(path); + path = rb_get_path(path); +#ifdef _WIN32 + /* UNIXSocket requires UTF-8 per spec. */ + path = rb_str_export_to_enc(path, rb_utf8_encoding()); +#endif + return path; } VALUE -rsock_init_unixsock(VALUE sock, VALUE path, int server) +rsock_init_unixsock(VALUE self, VALUE path, int server) { struct sockaddr_un sockaddr; socklen_t sockaddrlen; @@ -69,43 +73,46 @@ rsock_init_unixsock(VALUE sock, VALUE path, int server) rsock_sys_fail_path("socket(2)", path); } + VALUE io = rsock_init_sock(self, fd); + RB_IO_POINTER(io, fptr); + if (server) { status = bind(fd, (struct sockaddr*)&sockaddr, sockaddrlen); } else { - int prot; + int error_tag; struct unixsock_arg arg; arg.sockaddr = &sockaddr; arg.sockaddrlen = sockaddrlen; - arg.fd = fd; - status = (int)rb_protect(unixsock_connect_internal, (VALUE)&arg, &prot); - if (prot) { - close(fd); - rb_jump_tag(prot); + arg.io = io; + + status = (int)rb_protect(unixsock_connect_internal, (VALUE)&arg, &error_tag); + + if (error_tag) { + rb_io_close(io); + rb_jump_tag(error_tag); } } if (status < 0) { int e = errno; - close(fd); + rb_io_close(io); rsock_syserr_fail_path(e, "connect(2)", path); } if (server) { if (listen(fd, SOMAXCONN) < 0) { int e = errno; - close(fd); + rb_io_close(io); rsock_syserr_fail_path(e, "listen(2)", path); } } - rsock_init_sock(sock, fd); if (server) { - GetOpenFile(sock, fptr); fptr->pathv = rb_str_new_frozen(path); } - return sock; + return io; } /* @@ -121,9 +128,9 @@ rsock_init_unixsock(VALUE sock, VALUE path, int server) * */ static VALUE -unix_init(VALUE sock, VALUE path) +unix_init(VALUE self, VALUE path) { - return rsock_init_unixsock(sock, path, 0); + return rsock_init_unixsock(self, path, 0); } /* @@ -284,7 +291,7 @@ unix_send_io(VALUE sock, VALUE val) #endif arg.fd = fptr->fd; - while ((int)BLOCKING_REGION_FD(sendmsg_blocking, &arg) == -1) { + while ((int)rb_io_blocking_region(fptr, sendmsg_blocking, &arg) == -1) { if (!rb_io_wait_writable(arg.fd)) rsock_sys_fail_path("sendmsg(2)", fptr->pathv); } @@ -386,7 +393,7 @@ retry: #endif arg.fd = fptr->fd; - while ((int)BLOCKING_REGION_FD(recvmsg_blocking, &arg) == -1) { + while ((int)rb_io_blocking_region(fptr, recvmsg_blocking, &arg) == -1) { int e = errno; if (e == EMSGSIZE && !(gc_reason & GC_REASON_EMSGSIZE)) { /* FreeBSD gets here when we're out of FDs */ @@ -536,7 +543,7 @@ unix_peeraddr(VALUE sock) * * Creates a pair of sockets connected to each other. * - * _socktype_ should be a socket type such as: :STREAM, :DGRAM, :RAW, etc. + * _type_ should be a socket type such as: :STREAM, :DGRAM, :RAW, etc. * * _protocol_ should be a protocol defined in the domain. * 0 is default protocol for the domain. @@ -571,7 +578,7 @@ unix_s_socketpair(int argc, VALUE *argv, VALUE klass) void rsock_init_unixsocket(void) { -#ifdef HAVE_SYS_UN_H +#ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN /* * Document-class: UNIXSocket < BasicSocket * |
