diff options
Diffstat (limited to 'ext/socket/unixsocket.c')
-rw-r--r-- | ext/socket/unixsocket.c | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/ext/socket/unixsocket.c b/ext/socket/unixsocket.c index 26822e5..3c30e92 100644 --- a/ext/socket/unixsocket.c +++ b/ext/socket/unixsocket.c @@ -13,6 +13,7 @@ #ifdef HAVE_SYS_UN_H struct unixsock_arg { struct sockaddr_un *sockaddr; + socklen_t sockaddrlen; int fd; }; @@ -21,13 +22,14 @@ unixsock_connect_internal(VALUE a) { struct unixsock_arg *arg = (struct unixsock_arg *)a; return (VALUE)rsock_connect(arg->fd, (struct sockaddr*)arg->sockaddr, - (socklen_t)sizeof(*arg->sockaddr), 0); + arg->sockaddrlen, 0); } VALUE rsock_init_unixsock(VALUE sock, VALUE path, int server) { struct sockaddr_un sockaddr; + socklen_t sockaddrlen; int fd, status; rb_io_t *fptr; @@ -39,19 +41,21 @@ rsock_init_unixsock(VALUE sock, VALUE path, int server) MEMZERO(&sockaddr, struct sockaddr_un, 1); sockaddr.sun_family = AF_UNIX; - if (sizeof(sockaddr.sun_path) <= (size_t)RSTRING_LEN(path)) { - rb_raise(rb_eArgError, "too long unix socket path (max: %dbytes)", - (int)sizeof(sockaddr.sun_path)-1); + if (sizeof(sockaddr.sun_path) < (size_t)RSTRING_LEN(path)) { + rb_raise(rb_eArgError, "too long unix socket path (%ldbytes given but %dbytes max)", + RSTRING_LEN(path), (int)sizeof(sockaddr.sun_path)); } memcpy(sockaddr.sun_path, RSTRING_PTR(path), RSTRING_LEN(path)); + sockaddrlen = rsock_unix_sockaddr_len(path); if (server) { - status = bind(fd, (struct sockaddr*)&sockaddr, (socklen_t)sizeof(sockaddr)); + status = bind(fd, (struct sockaddr*)&sockaddr, sockaddrlen); } else { int prot; 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) { @@ -62,7 +66,7 @@ rsock_init_unixsock(VALUE sock, VALUE path, int server) if (status < 0) { close(fd); - rb_sys_fail(sockaddr.sun_path); + rb_sys_fail_str(rb_inspect(path)); } if (server) { @@ -116,9 +120,11 @@ unix_path(VALUE sock) if (NIL_P(fptr->pathv)) { struct sockaddr_un addr; socklen_t len = (socklen_t)sizeof(addr); + socklen_t len0 = len; if (getsockname(fptr->fd, (struct sockaddr*)&addr, &len) < 0) rb_sys_fail(0); - fptr->pathv = rb_obj_freeze(rb_str_new_cstr(rsock_unixpath(&addr, len))); + if (len0 < len) len = len0; + fptr->pathv = rb_obj_freeze(rsock_unixpath_str(&addr, len)); } return rb_str_dup(fptr->pathv); } @@ -445,11 +451,13 @@ unix_peeraddr(VALUE sock) rb_io_t *fptr; struct sockaddr_un addr; socklen_t len = (socklen_t)sizeof addr; + socklen_t len0 = len; GetOpenFile(sock, fptr); if (getpeername(fptr->fd, (struct sockaddr*)&addr, &len) < 0) rb_sys_fail("getpeername(2)"); + if (len0 < len) len = len0; return rsock_unixaddr(&addr, len); } |