How to transfer file descriptors with UNIX domain sockets?
Oliver Laumann
net at tub.UUCP
Sat Jun 30 00:21:30 AEST 1990
In article <37317 at ucbvax.BERKELEY.EDU> rgm at 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 at TUB.BITNET net at tub.cs.tu-berlin.de net at 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);
}
--------------------------------------------------------------------------
More information about the Comp.unix.questions
mailing list