blob: 6718fc265e3655d414c5a9d6bb71c54b703ca1f2 [file] [log] [blame]
sewardj4bdd5052006-10-17 01:28:48 +00001
sewardj4bdd5052006-10-17 01:28:48 +00002
sewardj6e9de462011-06-28 07:25:29 +00003
4
5
6
7
sewardj4bdd5052006-10-17 01:28:48 +00008
9#include <sys/socket.h>
10
sewardj4bdd5052006-10-17 01:28:48 +000011
12
sewardj6e9de462011-06-28 07:25:29 +000013
14
15
16
17
18
19
sewardj4bdd5052006-10-17 01:28:48 +000020
njnd2434862009-05-20 03:54:09 +000021#include <string.h>
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
njn81b975c2009-04-28 05:35:53 +000036void server (void)
rjwalshf5f536f2003-11-17 17:45:00 +000037{
38 int s, fd1, fd2;
39 struct sockaddr_un addr;
40
njn81b975c2009-04-28 05:35:53 +000041 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) );
rjwalshf5f536f2003-11-17 17:45:00 +000044
45 memset(&addr, 0, sizeof(addr));
46 addr.sun_family = AF_UNIX;
njnefc13c22009-02-23 06:44:51 +000047 sprintf(addr.sun_path, "%s", sock);
rjwalshf5f536f2003-11-17 17:45:00 +000048
njn81b975c2009-04-28 05:35:53 +000049 unlink(sock);
floriana3341d82013-10-02 15:37:03 +000050 (void) DO( bind(s, (struct sockaddr *)&addr, sizeof(addr)) );
51 (void) DO( listen(s, 5) );
rjwalshf5f536f2003-11-17 17:45:00 +000052
53 {
54 int x;
florian654b5422012-11-18 00:36:15 +000055 unsigned baddrsize = 0;
rjwalshf5f536f2003-11-17 17:45:00 +000056 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));
njn81b975c2009-04-28 05:35:53 +000063 x = DO( accept(s, (struct sockaddr *)&baddr, &baddrsize) );
rjwalshf5f536f2003-11-17 17:45:00 +000064
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
floriana3341d82013-10-02 15:37:03 +000080 (void) DO( sendmsg(x, &msg, 0) );
rjwalshf5f536f2003-11-17 17:45:00 +000081 }
82}
83
njn81b975c2009-04-28 05:35:53 +000084void client (void)
rjwalshf5f536f2003-11-17 17:45:00 +000085{
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);
njn81b975c2009-04-28 05:35:53 +0000102 if (s == -1) {
rjwalshf5f536f2003-11-17 17:45:00 +0000103 perror("socket");
104 exit(1);
105 }
106
107 addr.sun_family = AF_UNIX;
njnefc13c22009-02-23 06:44:51 +0000108 sprintf(addr.sun_path, "%s", sock);
rjwalshf5f536f2003-11-17 17:45:00 +0000109
110 do {
111 count++;
112 ret = connect(s, (struct sockaddr *)&addr, sizeof(addr));
njn81b975c2009-04-28 05:35:53 +0000113 if (ret == -1) sleep(1);
rjwalshf5f536f2003-11-17 17:45:00 +0000114 } while (count < 10 && ret == -1);
115
njn81b975c2009-04-28 05:35:53 +0000116 if (ret == -1) {
rjwalshf5f536f2003-11-17 17:45:00 +0000117 perror("connect");
118 exit(1);
119 }
120
sewardjb5f6f512005-03-10 23:59:00 +0000121 again:
njn81b975c2009-04-28 05:35:53 +0000122 if ((size = recvmsg(s, &msg, 0)) == -1) {
sewardjb5f6f512005-03-10 23:59:00 +0000123 if (errno == EINTR)
124 goto again; /* SIGCHLD from server exiting could interrupt */
rjwalshf5f536f2003-11-17 17:45:00 +0000125 perror("recvmsg");
126 exit(1);
127 }
128
129
130 cmsg = CMSG_FIRSTHDR(&msg);
njn81b975c2009-04-28 05:35:53 +0000131 while (cmsg) {
132 if (cmsg->cmsg_level == SOL_SOCKET &&
rjwalshf5f536f2003-11-17 17:45:00 +0000133 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
njn81b975c2009-04-28 05:35:53 +0000142 if (fd1 != -1) write(fd1, "Yeah 1\n", 8);
143 if (fd2 != -1) write(fd2, "Yeah 2\n", 8);
rjwalshf5f536f2003-11-17 17:45:00 +0000144}
145
146
njn81b975c2009-04-28 05:35:53 +0000147int main (int argc, char **argv)
rjwalshf5f536f2003-11-17 17:45:00 +0000148{
149 int pid, status;
150
bartfbce73d2008-05-27 12:33:29 +0000151 CLOSE_INHERITED_FDS;
rjwalshf5f536f2003-11-17 17:45:00 +0000152
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
njn81b975c2009-04-28 05:35:53 +0000158 if ((pid = fork()) == 0) {
rjwalshf5f536f2003-11-17 17:45:00 +0000159 server();
160 return 0;
161 }
162
163 client();
164
165 wait(&status);
166
floriana3341d82013-10-02 15:37:03 +0000167 (void) DO( unlink(filea) );
168 (void) DO( unlink(fileb) );
169 (void) DO( unlink(sock) );
rjwalshf5f536f2003-11-17 17:45:00 +0000170 return 0;
171}