Path: utzoo!attcan!uunet!mcsun!unido!tub!net From: net@tub.UUCP (Oliver Laumann) Newsgroups: comp.unix.questions Subject: Re: How to transfer file descriptors with UNIX domain sockets? Message-ID: <1421@tub.UUCP> Date: 29 Jun 90 14:21:30 GMT References: <37317@ucbvax.BERKELEY.EDU> Reply-To: net@tub.UUCP (Oliver Laumann) Organization: Technical University of Berlin, Germany Lines: 93 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 #include #include #include 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 #include #include #include 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); } --------------------------------------------------------------------------