sewardj | 4bdd505 | 2006-10-17 01:28:48 +0000 | [diff] [blame] | 1 | |
sewardj | 4bdd505 | 2006-10-17 01:28:48 +0000 | [diff] [blame] | 2 | |
sewardj | 6e9de46 | 2011-06-28 07:25:29 +0000 | [diff] [blame^] | 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
sewardj | 4bdd505 | 2006-10-17 01:28:48 +0000 | [diff] [blame] | 8 | |
| 9 | #include <sys/socket.h> |
| 10 | |
sewardj | 4bdd505 | 2006-10-17 01:28:48 +0000 | [diff] [blame] | 11 | |
| 12 | |
sewardj | 6e9de46 | 2011-06-28 07:25:29 +0000 | [diff] [blame^] | 13 | |
| 14 | |
| 15 | |
| 16 | |
| 17 | |
| 18 | |
| 19 | |
sewardj | 4bdd505 | 2006-10-17 01:28:48 +0000 | [diff] [blame] | 20 | |
njn | d243486 | 2009-05-20 03:54:09 +0000 | [diff] [blame] | 21 | #include <string.h> |
rjwalsh | f5f536f | 2003-11-17 17:45:00 +0000 | [diff] [blame] | 22 | #include <sys/types.h> |
| 23 | #include <sys/wait.h> |
rjwalsh | f5f536f | 2003-11-17 17:45:00 +0000 | [diff] [blame] | 24 | #include <sys/un.h> |
| 25 | #include <stdio.h> |
| 26 | #include <fcntl.h> |
| 27 | #include <unistd.h> |
| 28 | #include <stdlib.h> |
sewardj | b5f6f51 | 2005-03-10 23:59:00 +0000 | [diff] [blame] | 29 | #include <errno.h> |
bart | fbce73d | 2008-05-27 12:33:29 +0000 | [diff] [blame] | 30 | #include "fdleak.h" |
sewardj | 4bdd505 | 2006-10-17 01:28:48 +0000 | [diff] [blame] | 31 | |
rjwalsh | f5f536f | 2003-11-17 17:45:00 +0000 | [diff] [blame] | 32 | char filea[24]; |
| 33 | char fileb[24]; |
| 34 | char sock[24]; |
| 35 | |
njn | 81b975c | 2009-04-28 05:35:53 +0000 | [diff] [blame] | 36 | void server (void) |
rjwalsh | f5f536f | 2003-11-17 17:45:00 +0000 | [diff] [blame] | 37 | { |
| 38 | int s, fd1, fd2; |
| 39 | struct sockaddr_un addr; |
| 40 | |
njn | 81b975c | 2009-04-28 05:35:53 +0000 | [diff] [blame] | 41 | fd1 = DO( open(filea, O_RDWR | O_CREAT | O_TRUNC, 0750) ); |
| 42 | fd2 = DO( open(fileb, O_RDWR | O_CREAT | O_TRUNC, 0750) ); |
| 43 | s = DO( socket(PF_UNIX, SOCK_STREAM, 0) ); |
rjwalsh | f5f536f | 2003-11-17 17:45:00 +0000 | [diff] [blame] | 44 | |
| 45 | memset(&addr, 0, sizeof(addr)); |
| 46 | addr.sun_family = AF_UNIX; |
njn | efc13c2 | 2009-02-23 06:44:51 +0000 | [diff] [blame] | 47 | sprintf(addr.sun_path, "%s", sock); |
rjwalsh | f5f536f | 2003-11-17 17:45:00 +0000 | [diff] [blame] | 48 | |
njn | 81b975c | 2009-04-28 05:35:53 +0000 | [diff] [blame] | 49 | unlink(sock); |
| 50 | DO( bind(s, (struct sockaddr *)&addr, sizeof(addr)) ); |
| 51 | DO( listen(s, 5) ); |
rjwalsh | f5f536f | 2003-11-17 17:45:00 +0000 | [diff] [blame] | 52 | |
| 53 | { |
| 54 | int x; |
| 55 | int baddrsize = 0; |
| 56 | struct sockaddr_un baddr; |
| 57 | struct msghdr msg = {NULL, 0, NULL, 0, 0, 0, 0}; |
| 58 | struct cmsghdr *cmsg; |
| 59 | char buf[CMSG_SPACE(sizeof(int) * 2)]; |
| 60 | struct iovec iov[1]; |
| 61 | |
| 62 | memset(&baddr, 0, sizeof(baddr)); |
njn | 81b975c | 2009-04-28 05:35:53 +0000 | [diff] [blame] | 63 | x = DO( accept(s, (struct sockaddr *)&baddr, &baddrsize) ); |
rjwalsh | f5f536f | 2003-11-17 17:45:00 +0000 | [diff] [blame] | 64 | |
| 65 | msg.msg_control = buf; |
| 66 | msg.msg_controllen = sizeof(buf); |
| 67 | cmsg = CMSG_FIRSTHDR(&msg); |
| 68 | cmsg->cmsg_level = SOL_SOCKET; |
| 69 | cmsg->cmsg_type = SCM_RIGHTS; |
| 70 | cmsg->cmsg_len = CMSG_LEN(sizeof(int) * 2); |
| 71 | ((int *)CMSG_DATA(cmsg))[0] = fd1; |
| 72 | ((int *)CMSG_DATA(cmsg))[1] = fd2; |
| 73 | |
| 74 | iov[0].iov_base = "hello"; |
| 75 | iov[0].iov_len = 6; |
| 76 | |
| 77 | msg.msg_iov = iov; |
| 78 | msg.msg_iovlen = 1; |
| 79 | |
njn | 81b975c | 2009-04-28 05:35:53 +0000 | [diff] [blame] | 80 | DO( sendmsg(x, &msg, 0) ); |
rjwalsh | f5f536f | 2003-11-17 17:45:00 +0000 | [diff] [blame] | 81 | } |
| 82 | } |
| 83 | |
njn | 81b975c | 2009-04-28 05:35:53 +0000 | [diff] [blame] | 84 | void client (void) |
rjwalsh | f5f536f | 2003-11-17 17:45:00 +0000 | [diff] [blame] | 85 | { |
| 86 | int s, fd1 = -1, fd2 = -1, size, count = 0, ret; |
| 87 | struct sockaddr_un addr; |
| 88 | struct iovec iov[1]; |
| 89 | union { |
| 90 | struct cmsghdr cm; |
| 91 | char control[CMSG_SPACE(sizeof(int) * 2)]; |
| 92 | } control_un; |
| 93 | struct msghdr msg = { NULL, 0, iov, 1, control_un.control, |
| 94 | sizeof(control_un), 0 }; |
| 95 | struct cmsghdr *cmsg = &control_un.cm; |
| 96 | char buf[1024]; |
| 97 | |
| 98 | iov[0].iov_base = buf; |
| 99 | iov[0].iov_len = sizeof(buf); |
| 100 | |
| 101 | s = socket(PF_UNIX, SOCK_STREAM, 0); |
njn | 81b975c | 2009-04-28 05:35:53 +0000 | [diff] [blame] | 102 | if (s == -1) { |
rjwalsh | f5f536f | 2003-11-17 17:45:00 +0000 | [diff] [blame] | 103 | perror("socket"); |
| 104 | exit(1); |
| 105 | } |
| 106 | |
| 107 | addr.sun_family = AF_UNIX; |
njn | efc13c2 | 2009-02-23 06:44:51 +0000 | [diff] [blame] | 108 | sprintf(addr.sun_path, "%s", sock); |
rjwalsh | f5f536f | 2003-11-17 17:45:00 +0000 | [diff] [blame] | 109 | |
| 110 | do { |
| 111 | count++; |
| 112 | ret = connect(s, (struct sockaddr *)&addr, sizeof(addr)); |
njn | 81b975c | 2009-04-28 05:35:53 +0000 | [diff] [blame] | 113 | if (ret == -1) sleep(1); |
rjwalsh | f5f536f | 2003-11-17 17:45:00 +0000 | [diff] [blame] | 114 | } while (count < 10 && ret == -1); |
| 115 | |
njn | 81b975c | 2009-04-28 05:35:53 +0000 | [diff] [blame] | 116 | if (ret == -1) { |
rjwalsh | f5f536f | 2003-11-17 17:45:00 +0000 | [diff] [blame] | 117 | perror("connect"); |
| 118 | exit(1); |
| 119 | } |
| 120 | |
sewardj | b5f6f51 | 2005-03-10 23:59:00 +0000 | [diff] [blame] | 121 | again: |
njn | 81b975c | 2009-04-28 05:35:53 +0000 | [diff] [blame] | 122 | if ((size = recvmsg(s, &msg, 0)) == -1) { |
sewardj | b5f6f51 | 2005-03-10 23:59:00 +0000 | [diff] [blame] | 123 | if (errno == EINTR) |
| 124 | goto again; /* SIGCHLD from server exiting could interrupt */ |
rjwalsh | f5f536f | 2003-11-17 17:45:00 +0000 | [diff] [blame] | 125 | perror("recvmsg"); |
| 126 | exit(1); |
| 127 | } |
| 128 | |
| 129 | |
| 130 | cmsg = CMSG_FIRSTHDR(&msg); |
njn | 81b975c | 2009-04-28 05:35:53 +0000 | [diff] [blame] | 131 | while (cmsg) { |
| 132 | if (cmsg->cmsg_level == SOL_SOCKET && |
rjwalsh | f5f536f | 2003-11-17 17:45:00 +0000 | [diff] [blame] | 133 | cmsg->cmsg_type == SCM_RIGHTS && |
| 134 | cmsg->cmsg_len == CMSG_LEN(sizeof(int) * 2)) { |
| 135 | fd1 = ((int *)CMSG_DATA(cmsg))[0]; |
| 136 | fd2 = ((int *)CMSG_DATA(cmsg))[1]; |
| 137 | } |
| 138 | |
| 139 | cmsg = CMSG_NXTHDR(&msg, cmsg); |
| 140 | } |
| 141 | |
njn | 81b975c | 2009-04-28 05:35:53 +0000 | [diff] [blame] | 142 | if (fd1 != -1) write(fd1, "Yeah 1\n", 8); |
| 143 | if (fd2 != -1) write(fd2, "Yeah 2\n", 8); |
rjwalsh | f5f536f | 2003-11-17 17:45:00 +0000 | [diff] [blame] | 144 | } |
| 145 | |
| 146 | |
njn | 81b975c | 2009-04-28 05:35:53 +0000 | [diff] [blame] | 147 | int main (int argc, char **argv) |
rjwalsh | f5f536f | 2003-11-17 17:45:00 +0000 | [diff] [blame] | 148 | { |
| 149 | int pid, status; |
| 150 | |
bart | fbce73d | 2008-05-27 12:33:29 +0000 | [diff] [blame] | 151 | CLOSE_INHERITED_FDS; |
rjwalsh | f5f536f | 2003-11-17 17:45:00 +0000 | [diff] [blame] | 152 | |
| 153 | pid = getpid(); |
| 154 | sprintf(filea, "/tmp/data1.%d", pid); |
| 155 | sprintf(fileb, "/tmp/data2.%d", pid); |
| 156 | sprintf(sock, "/tmp/sock.%d", pid); |
| 157 | |
njn | 81b975c | 2009-04-28 05:35:53 +0000 | [diff] [blame] | 158 | if ((pid = fork()) == 0) { |
rjwalsh | f5f536f | 2003-11-17 17:45:00 +0000 | [diff] [blame] | 159 | server(); |
| 160 | return 0; |
| 161 | } |
| 162 | |
| 163 | client(); |
| 164 | |
| 165 | wait(&status); |
| 166 | |
njn | 81b975c | 2009-04-28 05:35:53 +0000 | [diff] [blame] | 167 | DO( unlink(filea) ); |
| 168 | DO( unlink(fileb) ); |
| 169 | DO( unlink(sock) ); |
rjwalsh | f5f536f | 2003-11-17 17:45:00 +0000 | [diff] [blame] | 170 | return 0; |
| 171 | } |