knutson@ut-ngp.UUCP (12/08/83)
I can't seem to get this to work. The problem is that binding a pathname causes "No such file or directory". The IPC Primer isn't much help either. It uses bind(s,"/dev/foo", sizeof("/dev/foo")-1); but that doesn't work either. Does anyone know how to properly address AF_UNIX domain sockets? -- Jim Knutson ARPA: knutson@ut-ngp UUCP: {ihnp4,seismo,kpno,ctvax}!ut-sally!ut-ngp!knutson
mogul%shasta@sri-unix.UUCP (12/09/83)
From: Jeff Mogul <mogul@shasta> The primer lies, but "man 2 bind" is more truthful. You've got to #include <sys/un.h> to get the definitions for the Unix addressing domain, then create an appropriate sockaddr_un (limited to 108 bytes, not 109 bytes as the declaration would imply, because the kernel rejects sockaddrs >= MLEN and the sizeof(struct sockaddr_un) == MLEN because the compiler short-aligns it, so passing sizeof(struct sockaddr_un) as the length argument to bind() will get you an error.) By the way, don't even bother trying SOCK_DGRAM in AF_UNIX. It won't work. If you try to use sendto/recvfrom the receiver gets a totally blank address in "from". If you try to use accept() in the receiver and connect()/send() in the sender, the send() fails because it thinks you haven't yet supplied a destination address! Following connect() by sendto() fails because "you've already supplied a destination address"(!) Using sendto() by itself fails to wake up the receiver from its accept(). I spent a few days staring at the kernel sources and I think the problems with connection-based SOCK_DGRAMs (sort of a contradiction in terms anyway) might be fixed with about 4 lines of code -- but I haven't been brave enough to try it. The problems with unconnected DGRAMs are deeper, but I think it's possible to provide at least a kludgey solution. I just gave up and used AF_INET, which works more or less, but I'm not happy. -Jeff P.S.: To top it all off, there's a "man 4 inet" page but no corresponding page for the Unix domain, at least on our tape.
msc@qubix.UUCP (Mark Callow) (12/09/83)
The "4.2 IPC Primer" is long out of date. The correct syntax for
binding a name to a socket in the Unix domain is as follows:
struct sockaddr socketname = { AF_UNIX, { "/dev/foo" } };
bind(s, &socketname, sizeof( socketname ));
where struct sockaddr is declared as follows:
struct sockaddr {
u_short sa_family; /* address family */
char sa_data[14]; /* up to 14 bytes of direct address */
};
--
From the Tardis of Mark Callow
msc@qubix.UUCP, decwrl!qubix!msc@Berkeley.ARPA
...{decvax,ucbvax,ihnp4}!decwrl!qubix!msc, ...{ittvax,amd70}!qubix!msc
jim@haring.UUCP (Jim McKie) (12/11/83)
Here is a sample fragment of code which does the trick, the IPC primer is wrong. .... #include <sys/types.h> #include <sys/socket.h> #include <sys/un.h> #define SOCKET "NameOfSomeFile" .... struct sockaddr_un socket; .... socket.sun_family = AF_UNIX; sprintf(socket.sun_path, "%s", SOCKET); if((s = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1){ perror("program: socket"); exit(1); } (void) unlink(socket.sun_path); if(bind(s, &socket, strlen(socket.sun_path)+2) == -1){ perror("program: bind"); exit(1); } .... Jim McKie Mathematisch Centrum, Amsterdam ....mcvax!jim
sam@ucbvax.UUCP (12/14/83)
I sure would like to see the "4 lines of code" which would fix the UNIX domain addressing problems. To be simple, naming in the UNIX domain needs an extensive overhaul. Because the sockets are tied to inodes one can't simply record bound names and expect them to remain constant across the lifetime of a socket (remember the socket could be be moved elsewhere in the file system while it's in use). Also, since socket names are pathnames, each send requires a call to namei resulting in abominable performance. There's an obvious need to be able to "bind" (not bind(2)) UNIX domain sockets to files in the UNIX file system, but the way it's done now was as much for expediency as anything else. P.S. You could probably fix the wandering name problem which currently exists by putting pwd in the kernel...just kidding Rob.