• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 
3 
4 
5 
6 
7 
8 
9 #include <sys/socket.h>
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 #include <string.h>
22 #include <sys/types.h>
23 #include <sys/wait.h>
24 #include <sys/un.h>
25 #include <stdio.h>
26 #include <fcntl.h>
27 #include <unistd.h>
28 #include <stdlib.h>
29 #include <errno.h>
30 #include "fdleak.h"
31 
32 char filea[24];
33 char fileb[24];
34 char sock[24];
35 
server(void)36 void server (void)
37 {
38    int s, fd1, fd2;
39    struct sockaddr_un addr;
40 
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) );
44 
45    memset(&addr, 0, sizeof(addr));
46    addr.sun_family = AF_UNIX;
47    sprintf(addr.sun_path, "%s", sock);
48 
49    unlink(sock);
50    DO( bind(s, (struct sockaddr *)&addr, sizeof(addr)) );
51    DO( listen(s, 5) );
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));
63       x = DO( accept(s, (struct sockaddr *)&baddr, &baddrsize) );
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 
80       DO( sendmsg(x, &msg, 0) );
81    }
82 }
83 
client(void)84 void client (void)
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);
102    if (s == -1) {
103       perror("socket");
104       exit(1);
105    }
106 
107    addr.sun_family = AF_UNIX;
108    sprintf(addr.sun_path, "%s", sock);
109 
110    do {
111      count++;
112      ret = connect(s, (struct sockaddr *)&addr, sizeof(addr));
113      if (ret == -1) sleep(1);
114    } while (count < 10 && ret == -1);
115 
116    if (ret == -1) {
117       perror("connect");
118       exit(1);
119    }
120 
121   again:
122    if ((size = recvmsg(s, &msg, 0)) == -1) {
123       if (errno == EINTR)
124 	 goto again;		/* SIGCHLD from server exiting could interrupt */
125       perror("recvmsg");
126       exit(1);
127    }
128 
129 
130    cmsg = CMSG_FIRSTHDR(&msg);
131    while (cmsg) {
132       if (cmsg->cmsg_level == SOL_SOCKET &&
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 
142    if (fd1 != -1) write(fd1, "Yeah 1\n", 8);
143    if (fd2 != -1) write(fd2, "Yeah 2\n", 8);
144 }
145 
146 
main(int argc,char ** argv)147 int main (int argc, char **argv)
148 {
149    int pid, status;
150 
151    CLOSE_INHERITED_FDS;
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 
158    if ((pid = fork()) == 0) {
159       server();
160       return 0;
161    }
162 
163    client();
164 
165    wait(&status);
166 
167    DO( unlink(filea) );
168    DO( unlink(fileb) );
169    DO( unlink(sock) );
170    return 0;
171 }
172