sendfd.c (1672B)
1 #include <u.h> 2 #define NOPLAN9DEFINES 3 #include <libc.h> 4 #include <sys/socket.h> 5 #include <sys/uio.h> 6 #include <unistd.h> 7 #include <errno.h> 8 9 #ifndef CMSG_ALIGN 10 # ifdef __sun__ 11 # define CMSG_ALIGN _CMSG_DATA_ALIGN 12 # else 13 # define CMSG_ALIGN(len) (((len)+sizeof(long)-1) & ~(sizeof(long)-1)) 14 # endif 15 #endif 16 17 #ifndef CMSG_SPACE 18 # define CMSG_SPACE(len) (CMSG_ALIGN(sizeof(struct cmsghdr))+CMSG_ALIGN(len)) 19 #endif 20 21 #ifndef CMSG_LEN 22 # define CMSG_LEN(len) (CMSG_ALIGN(sizeof(struct cmsghdr))+(len)) 23 #endif 24 25 int 26 sendfd(int s, int fd) 27 { 28 char buf[1]; 29 struct iovec iov; 30 struct msghdr msg; 31 struct cmsghdr *cmsg; 32 int n; 33 char cms[CMSG_SPACE(sizeof(int))]; 34 35 buf[0] = 0; 36 iov.iov_base = buf; 37 iov.iov_len = 1; 38 39 memset(&msg, 0, sizeof msg); 40 msg.msg_iov = &iov; 41 msg.msg_iovlen = 1; 42 msg.msg_control = (caddr_t)cms; 43 msg.msg_controllen = CMSG_LEN(sizeof(int)); 44 45 cmsg = CMSG_FIRSTHDR(&msg); 46 cmsg->cmsg_len = CMSG_LEN(sizeof(int)); 47 cmsg->cmsg_level = SOL_SOCKET; 48 cmsg->cmsg_type = SCM_RIGHTS; 49 memmove(CMSG_DATA(cmsg), &fd, sizeof(int)); 50 51 if((n=sendmsg(s, &msg, 0)) != iov.iov_len) 52 return -1; 53 return 0; 54 } 55 56 int 57 recvfd(int s) 58 { 59 int n; 60 int fd; 61 char buf[1]; 62 struct iovec iov; 63 struct msghdr msg; 64 struct cmsghdr *cmsg; 65 char cms[CMSG_SPACE(sizeof(int))]; 66 67 iov.iov_base = buf; 68 iov.iov_len = 1; 69 70 memset(&msg, 0, sizeof msg); 71 msg.msg_name = 0; 72 msg.msg_namelen = 0; 73 msg.msg_iov = &iov; 74 msg.msg_iovlen = 1; 75 76 msg.msg_control = (caddr_t)cms; 77 msg.msg_controllen = sizeof cms; 78 79 if((n=recvmsg(s, &msg, 0)) < 0) 80 return -1; 81 if(n == 0){ 82 werrstr("unexpected EOF"); 83 return -1; 84 } 85 cmsg = CMSG_FIRSTHDR(&msg); 86 memmove(&fd, CMSG_DATA(cmsg), sizeof(int)); 87 return fd; 88 }