Xref: utzoo comp.protocols.tcp-ip:2495 comp.protocols.misc:224 comp.protocols.iso:38 comp.protocols.ibm:80 comp.unix.questions:5528 comp.dcom.lans:1022 comp.os.vms:4623 Path: utzoo!utgpu!water!watmath!clyde!bellcore!faline!thumper!ulysses!ucbvax!sequoia.Berkeley.EDU!sklower From: sklower@sequoia.Berkeley.EDU.berkeley.edu (Keith Sklower) Newsgroups: comp.protocols.tcp-ip,comp.protocols.misc,comp.protocols.iso,comp.protocols.ibm,comp.unix.questions,comp.dcom.lans,comp.os.vms Subject: Re: Pass an open socket to another process???? Keywords: sockets Message-ID: <22952@ucbvax.BERKELEY.EDU> Date: 11 Feb 88 22:37:10 GMT References: <291@tifsil.UUCP> <633@eden.quintus.UUCP> Sender: usenet@ucbvax.BERKELEY.EDU Reply-To: sklower@sequoia.Berkeley.EDU.UUCP (Keith Sklower) Organization: University of California, Berkeley Lines: 47 In article <633@eden.quintus.UUCP> jbeard@quintus.UUCP (Jeff Beard) writes: > > >Your problem is of interest to anyone concerned with nested servers. >I for one would appreciate a posting of the summary of your findings. > >Tnx. 4.2 and 4.3 BSD provide a means of passing an open file descriptor of any sort (including sockets) between two co-operating processes by means of the sendmsg system call. In fact, I am presently engaged in reducing the latency in providing XNS courier services under UNIX by use of this mechanism. The Courier RPC protocol imbeds requests for services as part of the data of a stream, so one would like to pass the stream between processes, and fork + exec is a relatively slow way to do it. For greatest speed, you want to establish an additional UNIX-domain socket connection between the two processes prior to when the "passing of the baton" will occur. You can do this with either a stream or datagram connection (but if you use a datagram connection you must be careful to check that the sendmsg system call doesn't fail due to lack of buffer space; if it does, don't close the socket you are handing off, but try the sendmsg() system call over again later). Here is a code fragment to send the file descriptor: (You can pass data in addition to the socket, like any excess data you may have drained from it by mistake). pass_fd_rights(s, fd, buf, buflen) int s, fd, buflen; char *buf; { static struct msghdr msg; static struct iovec iov[1]; iov->iov_base = buf; iov->iov_len = buflen; msg.msg_iov = iov; msg.msg_iovlen = 1; msg.msg_accrights = (caddr_t)&fd; msg.msg_accrightslen = sizeof (fd); sendmsg(s, &msg, 0); } recvmsg() is the system call you use to collect the passed file descriptor.