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>