blob: 3c7db64cff152e59fa2ae32ab58e1861586c353c [file] [log] [blame]
sewardj4bdd5052006-10-17 01:28:48 +00001
2/* On AIX 5.2, _LINUX_SOURCE_COMPAT needs to be defined when reading
3 sys/socket.h in order to make CMSG_SPACE and CMSG_LEN visible. */
4
5#if defined(_AIX)
6#define _LINUX_SOURCE_COMPAT 1
7#endif
8
9#include <sys/socket.h>
10
11#if defined(_AIX)
12#undef _LINUX_SOURCE_COMPAT
13#endif
14
15
16/* Needed for 'memset' on AIX 5.2 */
17#if defined(_AIX)
18# include <memory.h>
19#endif
20
21
rjwalshf5f536f2003-11-17 17:45:00 +000022#include <sys/types.h>
23#include <sys/wait.h>
rjwalshf5f536f2003-11-17 17:45:00 +000024#include <sys/un.h>
25#include <stdio.h>
26#include <fcntl.h>
27#include <unistd.h>
28#include <stdlib.h>
sewardjb5f6f512005-03-10 23:59:00 +000029#include <errno.h>
bartfbce73d2008-05-27 12:33:29 +000030#include "fdleak.h"
sewardj4bdd5052006-10-17 01:28:48 +000031
rjwalshf5f536f2003-11-17 17:45:00 +000032char filea[24];
33char fileb[24];
34char sock[24];
35
36void
sewardj4bdd5052006-10-17 01:28:48 +000037server (void)
rjwalshf5f536f2003-11-17 17:45:00 +000038{
39 int s, fd1, fd2;
40 struct sockaddr_un addr;
41
42 fd1 = open(filea, O_RDWR | O_CREAT | O_TRUNC, 0750);
43 if(fd1 == -1) {
44 perror("open");
45 exit(1);
46 }
47
48 fd2 = open(fileb, O_RDWR | O_CREAT | O_TRUNC, 0750);
49 if(fd2 == -1) {
50 perror("open");
51 exit(1);
52 }
53
54 s = socket(PF_UNIX, SOCK_STREAM, 0);
55 if(s == -1) {
56 perror("socket");
57 exit(1);
58 }
59
60 memset(&addr, 0, sizeof(addr));
61 addr.sun_family = AF_UNIX;
62 sprintf(addr.sun_path, sock);
63
64 unlink(addr.sun_path);
65 if(bind(s, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
66 perror("bind");
67 exit(1);
68 }
69
70 if(listen(s, 5) == -1) {
71 perror("listen");
72 exit(1);
73 }
74
75 {
76 int x;
77 int baddrsize = 0;
78 struct sockaddr_un baddr;
79 struct msghdr msg = {NULL, 0, NULL, 0, 0, 0, 0};
80 struct cmsghdr *cmsg;
81 char buf[CMSG_SPACE(sizeof(int) * 2)];
82 struct iovec iov[1];
83
84 memset(&baddr, 0, sizeof(baddr));
85 x = accept(s, (struct sockaddr *)&baddr, &baddrsize);
86 if(x == -1) {
87 perror("accept");
88 exit(1);
89 }
90
91 msg.msg_control = buf;
92 msg.msg_controllen = sizeof(buf);
93 cmsg = CMSG_FIRSTHDR(&msg);
94 cmsg->cmsg_level = SOL_SOCKET;
95 cmsg->cmsg_type = SCM_RIGHTS;
96 cmsg->cmsg_len = CMSG_LEN(sizeof(int) * 2);
97 ((int *)CMSG_DATA(cmsg))[0] = fd1;
98 ((int *)CMSG_DATA(cmsg))[1] = fd2;
99
100 iov[0].iov_base = "hello";
101 iov[0].iov_len = 6;
102
103 msg.msg_iov = iov;
104 msg.msg_iovlen = 1;
105
106 if(sendmsg(x, &msg, 0) == -1) {
107 perror("sendmsg");
108 exit(1);
109 }
110 }
111}
112
113void
sewardj4bdd5052006-10-17 01:28:48 +0000114client (void)
rjwalshf5f536f2003-11-17 17:45:00 +0000115{
116 int s, fd1 = -1, fd2 = -1, size, count = 0, ret;
117 struct sockaddr_un addr;
118 struct iovec iov[1];
119 union {
120 struct cmsghdr cm;
121 char control[CMSG_SPACE(sizeof(int) * 2)];
122 } control_un;
123 struct msghdr msg = { NULL, 0, iov, 1, control_un.control,
124 sizeof(control_un), 0 };
125 struct cmsghdr *cmsg = &control_un.cm;
126 char buf[1024];
127
128 iov[0].iov_base = buf;
129 iov[0].iov_len = sizeof(buf);
130
131 s = socket(PF_UNIX, SOCK_STREAM, 0);
132 if(s == -1) {
133 perror("socket");
134 exit(1);
135 }
136
137 addr.sun_family = AF_UNIX;
138 sprintf(addr.sun_path, sock);
139
140 do {
141 count++;
142 ret = connect(s, (struct sockaddr *)&addr, sizeof(addr));
143 if(ret == -1) sleep(1);
144 } while (count < 10 && ret == -1);
145
146 if(ret == -1) {
147 perror("connect");
148 exit(1);
149 }
150
sewardjb5f6f512005-03-10 23:59:00 +0000151 again:
rjwalshf5f536f2003-11-17 17:45:00 +0000152 if((size = recvmsg(s, &msg, 0)) == -1) {
sewardjb5f6f512005-03-10 23:59:00 +0000153 if (errno == EINTR)
154 goto again; /* SIGCHLD from server exiting could interrupt */
rjwalshf5f536f2003-11-17 17:45:00 +0000155 perror("recvmsg");
156 exit(1);
157 }
158
159
160 cmsg = CMSG_FIRSTHDR(&msg);
161 while(cmsg) {
162 if(cmsg->cmsg_level == SOL_SOCKET &&
163 cmsg->cmsg_type == SCM_RIGHTS &&
164 cmsg->cmsg_len == CMSG_LEN(sizeof(int) * 2)) {
165 fd1 = ((int *)CMSG_DATA(cmsg))[0];
166 fd2 = ((int *)CMSG_DATA(cmsg))[1];
167 }
168
169 cmsg = CMSG_NXTHDR(&msg, cmsg);
170 }
171
172 if(fd1 != -1) write(fd1, "Yeah 1\n", 8);
173 if(fd2 != -1) write(fd2, "Yeah 2\n", 8);
174}
175
176
177int
178main (int argc, char **argv)
179{
180 int pid, status;
181
rjwalshf5f536f2003-11-17 17:45:00 +0000182
bartfbce73d2008-05-27 12:33:29 +0000183
184
185
186
187 CLOSE_INHERITED_FDS;
rjwalshf5f536f2003-11-17 17:45:00 +0000188
189 pid = getpid();
190 sprintf(filea, "/tmp/data1.%d", pid);
191 sprintf(fileb, "/tmp/data2.%d", pid);
192 sprintf(sock, "/tmp/sock.%d", pid);
193
194 if((pid = fork()) == 0) {
195 server();
196 return 0;
197 }
198
199 client();
200
201 wait(&status);
202
203 unlink(filea);
204 unlink(fileb);
205 unlink(sock);
206 return 0;
207}