rsc | b3994ec | 2003-12-11 17:50:28 +0000 | [diff] [blame] | 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 | |
rsc | 2ec48bb | 2005-07-13 03:55:52 +0000 | [diff] [blame] | 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 | |
rsc | b3994ec | 2003-12-11 17:50:28 +0000 | [diff] [blame] | 25 | int |
| 26 | sendfd(int s, int fd) |
| 27 | { |
| 28 | char buf[1]; |
| 29 | struct iovec iov; |
| 30 | struct msghdr msg; |
rsc | 52e6164 | 2005-05-01 18:40:01 +0000 | [diff] [blame] | 31 | struct cmsghdr *cmsg; |
rsc | b3994ec | 2003-12-11 17:50:28 +0000 | [diff] [blame] | 32 | int n; |
rsc | 52e6164 | 2005-05-01 18:40:01 +0000 | [diff] [blame] | 33 | char cms[CMSG_SPACE(sizeof(int))]; |
| 34 | |
rsc | b3994ec | 2003-12-11 17:50:28 +0000 | [diff] [blame] | 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; |
rsc | 52e6164 | 2005-05-01 18:40:01 +0000 | [diff] [blame] | 42 | msg.msg_control = (caddr_t)cms; |
| 43 | msg.msg_controllen = CMSG_LEN(sizeof(int)); |
rsc | b3994ec | 2003-12-11 17:50:28 +0000 | [diff] [blame] | 44 | |
rsc | 52e6164 | 2005-05-01 18:40:01 +0000 | [diff] [blame] | 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 | *(int*)CMSG_DATA(cmsg) = fd; |
rsc | b3994ec | 2003-12-11 17:50:28 +0000 | [diff] [blame] | 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; |
rsc | 52e6164 | 2005-05-01 18:40:01 +0000 | [diff] [blame] | 60 | int fd; |
rsc | b3994ec | 2003-12-11 17:50:28 +0000 | [diff] [blame] | 61 | char buf[1]; |
| 62 | struct iovec iov; |
| 63 | struct msghdr msg; |
rsc | 52e6164 | 2005-05-01 18:40:01 +0000 | [diff] [blame] | 64 | struct cmsghdr *cmsg; |
| 65 | char cms[CMSG_SPACE(sizeof(int))]; |
rsc | b3994ec | 2003-12-11 17:50:28 +0000 | [diff] [blame] | 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 | |
rsc | 52e6164 | 2005-05-01 18:40:01 +0000 | [diff] [blame] | 76 | msg.msg_control = (caddr_t)cms; |
| 77 | msg.msg_controllen = sizeof cms; |
rsc | b3994ec | 2003-12-11 17:50:28 +0000 | [diff] [blame] | 78 | |
| 79 | if((n=recvmsg(s, &msg, 0)) < 0) |
| 80 | return -1; |
rsc | c8a93fb | 2006-07-23 02:57:11 +0000 | [diff] [blame] | 81 | if(n == 0){ |
| 82 | werrstr("unexpected EOF"); |
| 83 | return -1; |
| 84 | } |
rsc | 52e6164 | 2005-05-01 18:40:01 +0000 | [diff] [blame] | 85 | cmsg = CMSG_FIRSTHDR(&msg); |
| 86 | fd = *(int*)CMSG_DATA(cmsg); |
| 87 | return fd; |
rsc | b3994ec | 2003-12-11 17:50:28 +0000 | [diff] [blame] | 88 | } |