Bugs item #8597, was opened at 2007-02-13 07:10
You can respond by visiting: 
http://rubyforge.org/tracker/?func=detail&atid=1698&aid=8597&group_id=426

>Category: Network / Comm / Process
Group: 1.8.4
Status: Open
Resolution: None
Priority: 3
Submitted By: Kristoffer Lundén (stoffe)
Assigned to: Nobody (None)
Summary: Socket library should support abstract unix sockets

Initial Comment:
See this post about abstract unix sockets, discussion is about implementing native D-BUS support in Ruby: http://sourceforge.net/mailarchive/message.php?msg_id=38052001

On 1/25/07, Sjoerd Simons <sjoerd / sp...> wrote:
> You connect to an abstract socket by specifying the first byte of the path as
> '\0', unfortunately the ruby socket layer doesn't allow you to do this.. It
> gives you:
> ArgumentError: string contains null byte

If he's right, it may be enough to alter the sanity check somewhere and this would work?

----------------------------------------------------------------------

Comment By: Bram Senders (bram)
Date: 2007-02-16 15:29

Message:
I have patched ruby's socket.c to make this possible; patch is below.  This is pretty much the first time I patched anything, so hopefully I did it right. :)  It works for me, at least.

Cheers!


--- ruby-1.8.5-p12/ext/socket/socket.c.orig	2007-02-16 17:59:47.000000000 +0100
+++ ruby-1.8.5-p12/ext/socket/socket.c	2007-02-16 21:08:46.000000000 +0100
@@ -1552,6 +1552,7 @@
 #ifdef HAVE_SYS_UN_H
 struct unixsock_arg {
     struct sockaddr_un *sockaddr;
+    int addrlen;
     int fd;
 };
 
@@ -1559,8 +1560,7 @@
 unixsock_connect_internal(arg)
     struct unixsock_arg *arg;
 {
-    return (VALUE)ruby_connect(arg->fd, arg->sockaddr, sizeof(*arg->sockaddr),
-			       0);
+    return (VALUE)ruby_connect(arg->fd, arg->sockaddr, arg->addrlen, 0);
 }
 
 static VALUE
@@ -1570,7 +1570,7 @@
     int server;
 {
     struct sockaddr_un sockaddr;
-    int fd, status;
+    int fd, status, addrlen;
     OpenFile *fptr;
 
     SafeStringValue(path);
@@ -1585,15 +1585,18 @@
         rb_raise(rb_eArgError, "too long unix socket path (max: %dbytes)",
             (int)sizeof(sockaddr.sun_path)-1);
     }
-    strcpy(sockaddr.sun_path, StringValueCStr(path));
+    memcpy(sockaddr.sun_path, StringValuePtr(path), RSTRING(path)->len + 1);
+    addrlen = (long) ((char *) &((struct sockaddr_un *) 0)->sun_path) +
+        RSTRING(path)->len;
 
     if (server) {
-        status = bind(fd, (struct sockaddr*)&sockaddr, sizeof(sockaddr));
+        status = bind(fd, (struct sockaddr*)&sockaddr, addrlen);
     }
     else {
 	int prot;
 	struct unixsock_arg arg;
 	arg.sockaddr = &sockaddr;
+	arg.addrlen = addrlen;
 	arg.fd = fd;
         status = rb_protect(unixsock_connect_internal, (VALUE)&arg, &prot);
 	if (prot) {


----------------------------------------------------------------------

You can respond by visiting: 
http://rubyforge.org/tracker/?func=detail&atid=1698&aid=8597&group_id=426