Date: Fri, 28 Aug 1998 21:14:46 -0400 (EDT) From: Bill Paul <wpaul@skynet.ctr.columbia.edu> To: chanders@timing.com (Craig Anderson) Cc: freebsd-hackers@FreeBSD.ORG Subject: Re: Help with passing fd on FreeBSD Message-ID: <199808290114.VAA28236@skynet.ctr.columbia.edu> In-Reply-To: <199808281426.IAA10588@count.timing.com> from "Craig Anderson" at Aug 28, 98 08:26:25 am
next in thread | previous in thread | raw e-mail | index | archive | help
Of all the gin joints in all the towns in all the world, Craig Anderson
had to walk into mine and say:
>
> Can someone give me pointers on passing open file descriptors on FreeBSD?
> This is covered in W. Richard Stevens Advanced programming book, but
> the structs in FreeBSD are slightly different, and I've never done this.
>
> Thanks,
> Craig
Sure. Appended to this message are two small programs: r.c and s.c.
s.c sends a descriptor and r.c receives it. Last time I used this
was on FreeBSD 2.1.0 but it should still work. The descriptor being
sent is actually the AF_LOCAL socket that s.c creates to talk to
r.c, which is kind of pointless but you can use any other descriptor
index you want (as long as it refers to a valid open descriptor).
-Bill
--
=============================================================================
-Bill Paul (212) 854-6020 | System Manager, Master of Unix-Fu
Work: wpaul@ctr.columbia.edu | Center for Telecommunications Research
Home: wpaul@skynet.ctr.columbia.edu | Columbia University, New York City
=============================================================================
"It is not I who am crazy; it is I who am mad!" - Ren Hoek, "Space Madness"
=============================================================================
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <err.h>
#include <sys/types.h>
#include <sys/time.h>
#include <string.h>
#include <sys/uio.h>
#include <sys/fcntl.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/stat.h>
#ifndef lint
static const char rcsid[] = "$Id: r.c,v 1.4 1998/08/29 01:03:52 wpaul Exp $";
#endif
struct cmessage {
struct cmsghdr cmsg;
int fd;
};
int
main()
{
struct iovec iov[1];
struct msghdr msg;
struct cmessage cm;
struct sockaddr_un sun;
int s;
int sock;
int len;
fd_set readfds;
char recbuf[1024];
if (unlink("/tmp/testsock") == -1)
warn("couldn't remove old socket");
strcpy(sun.sun_path, "/tmp/testsock");
sun.sun_family = AF_UNIX;
len = sun.sun_len = sizeof(sun.sun_len) + sizeof(sun.sun_family) +
strlen(sun.sun_path) + 1;
if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
err(1, "socket creation failed");
iov[0].iov_base = (char *)&recbuf;
iov[0].iov_len = sizeof(recbuf);
bzero((char *)&cm, sizeof(cm));
bzero((char *)&msg, sizeof(msg));
msg.msg_iov = iov;
msg.msg_iovlen = 1;
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_control = (caddr_t)&cm;
msg.msg_controllen = sizeof(struct cmessage);
msg.msg_flags = 0;
if (bind(s, (struct sockaddr *)&sun, len) == -1)
err(1, "couldn't bind socket");
listen(s, 2);
if ((sock = accept(s, (struct sockaddr *)&sun, &len)) == -1)
err(1, "accept failed");
FD_ZERO(&readfds);
FD_SET(sock, &readfds);
select(FD_SETSIZE, &readfds, NULL, NULL, NULL);
if ((len = recvmsg(sock, &msg, 0)) == -1)
err(1, "recvmsg failed");
printf ("read %d bytes\n", len);
printf ("data: %s\n", iov[0].iov_base);
if (cm.cmsg.cmsg_type != SCM_RIGHTS)
warnx("message didn't contain SCM_RIGHTS");
printf ("FD: %d\n", cm.fd);
close(sock);
close(s);
exit(0);
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <err.h>
#include <sys/types.h>
#include <sys/time.h>
#include <string.h>
#include <sys/uio.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/fcntl.h>
#include <sys/stat.h>
#ifndef lint
static const char rcsid[] = "$Id: s.c,v 1.4 1998/08/29 01:05:28 wpaul Exp $";
#endif
struct cmessage {
struct cmsghdr cmsg;
int fd;
};
int
main()
{
struct iovec iov[1];
struct msghdr msg;
struct cmessage cm;
struct sockaddr_un sun;
int s;
int len;
char sendbuf[] = "This is a test buffer.";
strcpy(sun.sun_path, "/tmp/testsock");
sun.sun_family = AF_UNIX;
len = sun.sun_len = sizeof(sun.sun_len) + sizeof(sun.sun_family) +
strlen(sun.sun_path) + 1;
if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
err(1, "socket creation failed");
if (connect(s, (struct sockaddr *)&sun, len) == -1)
err(1, "couldn't connect socket");
iov[0].iov_base = (char *)&sendbuf;
iov[0].iov_len = sizeof(sendbuf);
cm.cmsg.cmsg_type = SCM_RIGHTS;
cm.cmsg.cmsg_level = SOL_SOCKET;
cm.cmsg.cmsg_len = sizeof(struct cmessage);
cm.fd = s; /* file descriptor to be transfered */
msg.msg_iov = iov;
msg.msg_iovlen = 1;
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_control = (caddr_t)&cm;
msg.msg_controllen = sizeof(struct cmessage);
msg.msg_flags = 0;
if ((len = sendmsg(s, &msg, 0)) == -1)
err(1, "sendmsg failed");
printf ("sent message (%d bytes), sending data...\n", len);
close(s);
exit(0);
}
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199808290114.VAA28236>
