[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Unix-domain (local) sockets do not support getsockname() or getpeername(
From: |
Deven T. Corzine |
Subject: |
Unix-domain (local) sockets do not support getsockname() or getpeername(). |
Date: |
Wed, 23 Mar 2005 10:19:46 -0500 |
User-agent: |
Mozilla Thunderbird 0.7.3 (Windows/20040803) |
Hi folks...
I'll start with a very brief introduction -- I just joined this mailing
list, so that I could report a Hurd bug I found last night. I never
used the Hurd before yesterday, but I would be interested in working
with it, if I can just find the time...
Anyway, I was on #hug on IRC last night, talking to "bddebian", who was
having trouble getting "orbit2" (GNOME's CORBA broker) to run on the
Hurd. I offered to help, so he gave me an account on his machine and I
traced the problem, which turned out to be that getsockname() was
returning a null pathname instead of the correct pathname of the
Unix-domain socket. Since orbit2 expects this call to work, it broke
the software. After I found the problem, I stripped down the code to a
36-line test case (attached) which exhibits the bug. Under Linux,
getsockname() returns the same sockaddr_un structure that was sent to
bind(), while the Hurd is returning a null path instead.
This morning, I took a quick glance at the Hurd sources, and noticed the
following comment on S_socket_whatis_address() in hurd/pflocal/pf.c:
/* Implement socket_whatis_address as described in <hurd/socket.defs>.
Since we cannot tell what our adress is, return an empty string as
the file name. This is primarily for the implementation of accept
and recvfrom. The functions getsockname and getpeername remain
unsupported for the local namespace. */
So it appears that no attempt was ever made to implement getsockname()
or getpeername() for Unix-domain sockets.
Since this bug (unsupported feature) may break other applications
besides orbit2, perhaps someone would like to take a stab at filling in
the gap?
Deven
#include <stdio.h>
#include <malloc.h>
#include <sys/socket.h>
#include <sys/un.h>
#define PATH "./getsockname_bug.socket"
main()
{
unlink(PATH);
int saddr_len = sizeof(struct sockaddr_un);
struct sockaddr_un *saddr = (struct sockaddr_un *) malloc(saddr_len);
if (!saddr) exit(1);
memset(saddr, 0, saddr_len);
saddr->sun_family = AF_UNIX;
strcpy(saddr->sun_path, PATH);
int pathlen = strlen(PATH) + 1;
saddr_len = sizeof(struct sockaddr_un) - sizeof(saddr->sun_path) +
pathlen;
int fd = socket(PF_UNIX, SOCK_STREAM, 0);
if (fd < 0) exit(1);
if (bind(fd, (struct sockaddr *) saddr, saddr_len)) exit(1);
printf("before: path = \"%s\", saddr_len = %d\n", saddr->sun_path,
saddr_len);
if (getsockname(fd, (struct sockaddr *) saddr, &saddr_len)) exit(1);
printf("after: path = \"%s\", saddr_len = %d\n", saddr->sun_path,
saddr_len);
close(fd);
unlink(PATH);
}
- Unix-domain (local) sockets do not support getsockname() or getpeername().,
Deven T. Corzine <=