rgm@lightning.Berkeley.EDU (Rob Menke) (06/28/90)
I have seen references in various IPC tutorials and manuals that it is
possible to transfer file descriptors between processes via UNIX domain
sockets using sendmsg(2) and recvmsg(2). Unfortunately, none of these
documents contain anything more than a tantalizing aside.
I'm hoping that someone out there might be able to provide a detailed
description of how this is done, or better yet, some clear code that could be
used as an example.
Please e-mail as I will be going on vacation shortly and our news server will
cheerfully overwrite any posted replies.
Thanks.
>GIVE COIN TO CHARON | Wabewalker
"So educated," giggles the voice in | rgm@OCF.berkeley.edu
your ear... | Robert.Menke@bmug.fidonet.org
nystrom@enea.se (Lars Nystr|m) (06/29/90)
In article <37317@ucbvax.BERKELEY.EDU> rgm@OCF.Berkeley.EDU (Rob Menke) writes: > >I have seen references in various IPC tutorials and manuals that it is >possible to transfer file descriptors between processes via UNIX domain >sockets using sendmsg(2) and recvmsg(2). Unfortunately, none of these >documents contain anything more than a tantalizing aside. There is a book that explains how to do this. UNIX Network Programming W. Richard Stevens Prentice-Hall 1990 ISBN 0-13-949876-1 An example will be E-mailed to you.
net@tub.UUCP (Oliver Laumann) (06/29/90)
In article <37317@ucbvax.BERKELEY.EDU> rgm@OCF.Berkeley.EDU (Rob Menke) writes: > > I have seen references in various IPC tutorials and manuals that it is > possible to transfer file descriptors between processes via UNIX domain > sockets using sendmsg(2) and recvmsg(2). > > I'm hoping that someone out there might be able to provide a detailed > description of how this is done, or better yet, some clear code that could be > used as an example. The following two trivial programs demonstrate this functionality. The first of them accepts a connection on a UNIX domain socket, opens /etc/passwd, sends the file descriptor to the peer process, and then exits. The other program establishes a connection, receives the file descriptor, reads a buffer full of data from it, and writes it to standard output. Yes, I know, the programs are written in a sloppy style (no exit codes, arguments not properly casted, no man-page and "imake" file :-) Regards, -- Oliver Laumann net@TUB.BITNET net@tub.cs.tu-berlin.de net@tub.UUCP -------------------------------------------------------------------------- #include <sys/types.h> #include <sys/socket.h> #include <sys/un.h> #include <sys/uio.h> main () { int s, fd; struct sockaddr_un a; static struct msghdr msg; static struct iovec iov; char *name = "foo"; unlink (name); if ((s = socket (AF_UNIX, SOCK_STREAM, 0)) == -1) { perror ("socket"); return; } a.sun_family = AF_UNIX; strcpy (a.sun_path, name); if (bind (s, (struct sockaddr *)&a, strlen (name)+2) == -1) { perror ("bind"); return; } listen (s, 1); s = accept (s, (struct sockaddr *)0, (int *)0); if ((fd = open ("/etc/passwd", 0)) == -1) { perror ("passwd"); return; } msg.msg_accrights = (caddr_t)&fd; msg.msg_accrightslen = sizeof (fd); msg.msg_iov = &iov; if (sendmsg (s, &msg, 0) == -1) perror ("sendmsg"); } -------------------------------------------------------------------------- #include <sys/types.h> #include <sys/socket.h> #include <sys/un.h> #include <sys/uio.h> main () { int s, n, fd; struct sockaddr_un a; static struct msghdr msg; static struct iovec iov; char *name = "foo"; char buf[512]; if ((s = socket (AF_UNIX, SOCK_STREAM, 0)) == -1) { perror ("socket"); return; } a.sun_family = AF_UNIX; strcpy (a.sun_path, name); if (connect (s, (struct sockaddr *)&a, strlen (name)+2) == -1) { perror ("connect"); return; } msg.msg_accrights = (caddr_t)&fd; msg.msg_accrightslen = sizeof(fd); msg.msg_iov = &iov; if ((n = recvmsg (s, &msg, 0)) == -1) { perror ("recvmsg"); return; } if ((n = read (fd, buf, 512)) == -1) { perror ("read"); return; } write (1, buf, n); } --------------------------------------------------------------------------
gt0178a@prism.gatech.EDU (BURNS,JIM) (07/01/90)
in article <1421@tub.UUCP>, net@tub.UUCP (Oliver Laumann) says: > In article <37317@ucbvax.BERKELEY.EDU> rgm@OCF.Berkeley.EDU (Rob Menke) writes: >> possible to transfer file descriptors between processes via UNIX domain >> sockets using sendmsg(2) and recvmsg(2). > The following two trivial programs demonstrate this functionality. > The first of them accepts a connection on a UNIX domain socket, opens > /etc/passwd, sends the file descriptor to the peer process, and then exits. I don't understand the concept here - if the program exits, its files are closed, and the file descriptor is no longer valid. I know that child procs can refer to parent fds even after the parent exits, but merely sending an fd in a message - so what? How does the system know that the message contains an fd that must remain valid after the program that opened it exits? -- BURNS,JIM Georgia Institute of Technology, Box 30178, Atlanta Georgia, 30332 uucp: ...!{decvax,hplabs,ncar,purdue,rutgers}!gatech!prism!gt0178a Internet: gt0178a@prism.gatech.edu
cpcahil@virtech.uucp (Conor P. Cahill) (07/01/90)
In article <10970@hydra.gatech.EDU> gt0178a@prism.gatech.EDU (BURNS,JIM) writes: >in article <1421@tub.UUCP>, net@tub.UUCP (Oliver Laumann) says: >> In article <37317@ucbvax.BERKELEY.EDU> rgm@OCF.Berkeley.EDU (Rob Menke) writes: >>> possible to transfer file descriptors between processes via UNIX domain >>> sockets using sendmsg(2) and recvmsg(2). >> The following two trivial programs demonstrate this functionality. >> The first of them accepts a connection on a UNIX domain socket, opens >> /etc/passwd, sends the file descriptor to the peer process, and then exits. > >I don't understand the concept here - if the program exits, its files are >closed, and the file descriptor is no longer valid. I know that child procs >can refer to parent fds even after the parent exits, but merely sending an >fd in a message - so what? How does the system know that the message >contains an fd that must remain valid after the program that opened it >exits? The system knows because the person, or persons, that added that capability to the sockets code ensured that the file descriptor that was passed became a valid file descriptor in the process that received it. This is not that hard to do since the kernel has control of both processes and thier file descriptor tables. The same capability exists in SVR3 streams although I'm not sure if it has equal functionality. -- Conor P. Cahill (703)430-9247 Virtual Technologies, Inc., uunet!virtech!cpcahil 46030 Manekin Plaza, Suite 160 Sterling, VA 22170
gt0178a@prism.gatech.EDU (BURNS,JIM) (07/02/90)
in article <1990Jul01.130157.3627@virtech.uucp>, cpcahil@virtech.uucp (Conor P. Cahill) says: >>in article <1421@tub.UUCP>, net@tub.UUCP (Oliver Laumann) says: [code deleted] > The system knows because the person, or persons, that added that capability > to the sockets code ensured that the file descriptor that was passed became > a valid file descriptor in the process that received it. I'm sure that it *can* be done - my question is what was it in Oliver Laumann's code that informed the kernel that what was in the message was a file descriptor? -- BURNS,JIM Georgia Institute of Technology, Box 30178, Atlanta Georgia, 30332 uucp: ...!{decvax,hplabs,ncar,purdue,rutgers}!gatech!prism!gt0178a Internet: gt0178a@prism.gatech.edu
cpcahil@virtech.uucp (Conor P. Cahill) (07/02/90)
In article <10981@hydra.gatech.EDU> gt0178a@prism.gatech.EDU (BURNS,JIM) writes: >in article <1990Jul01.130157.3627@virtech.uucp>, cpcahil@virtech.uucp (Conor P. Cahill) says: >>>in article <1421@tub.UUCP>, net@tub.UUCP (Oliver Laumann) says: > [code deleted] >> The system knows because the person, or persons, that added that capability >> to the sockets code ensured that the file descriptor that was passed became >> a valid file descriptor in the process that received it. > >I'm sure that it *can* be done - my question is what was it in Oliver >Laumann's code that informed the kernel that what was in the message was a >file descriptor? Essentially it is the portion of the that supports the passing of "access rights". The access rights to the file descriptor are passed using a send/recvmsg(). For more info, you could look at section 6.10 "Passing file descriptors" in UNIX Network Programming (by W. Richard Stevens). -- Conor P. Cahill (703)430-9247 Virtual Technologies, Inc., uunet!virtech!cpcahil 46030 Manekin Plaza, Suite 160 Sterling, VA 22170
guy@auspex.auspex.com (Guy Harris) (07/03/90)
>I'm sure that it *can* be done - my question is what was it in Oliver >Laumann's code that informed the kernel that what was in the message was a >file descriptor? It was msg.msg_accrights = (caddr_t)&fd; msg.msg_accrightslen = sizeof (fd); I.e., the "access rights" in a message sent down a UNIX-domain socket are, by definition, file descriptors....
stevens@hsi.UUCP (Richard Stevens) (07/03/90)
In article <1990Jul01.130157.3627@virtech.uucp> cpcahil@virtech.UUCP (Conor P. Cahill) writes: > >The same capability exists in SVR3 streams although I'm not sure if it has >equal functionality. It provides the same functionality plus the SVR3 routines provide the receiver with the effective UID and effective GID of the sender. Richard Stevens 3M Health Information Systems, Wallingford, CT stevens@hsi.com