Bug 497723 - forgot to restore callgrind output cleanup
[valgrind.git] / none / tests / fdleak_cmsg.c
blobd4300bcf2da1a2e9c11c17322d7c2d064554a998
9 #include <sys/socket.h>
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 #include <sys/uio.h>
33 char filea[24];
34 char fileb[24];
35 char sock[24];
37 void server (void)
39 int s, fd1, fd2;
40 struct sockaddr_un addr;
42 fd1 = DO( open(filea, O_RDWR | O_CREAT | O_TRUNC, 0750) );
43 fd2 = DO( open(fileb, O_RDWR | O_CREAT | O_TRUNC, 0750) );
44 s = DO( socket(PF_UNIX, SOCK_STREAM, 0) );
46 memset(&addr, 0, sizeof(addr));
47 addr.sun_family = AF_UNIX;
48 sprintf(addr.sun_path, "%s", sock);
50 unlink(sock);
51 (void) DO( bind(s, (struct sockaddr *)&addr, sizeof(addr)) );
52 (void) DO( listen(s, 5) );
55 int x;
56 unsigned baddrsize = 0;
57 struct sockaddr_un baddr;
58 struct msghdr msg = {NULL, 0, NULL, 0, 0, 0, 0};
59 struct cmsghdr *cmsg;
60 char buf[CMSG_SPACE(sizeof(int) * 2)];
61 struct iovec iov[1];
63 memset(&baddr, 0, sizeof(baddr));
64 x = DO( accept(s, (struct sockaddr *)&baddr, &baddrsize) );
66 msg.msg_control = buf;
67 msg.msg_controllen = sizeof(buf);
68 cmsg = CMSG_FIRSTHDR(&msg);
69 cmsg->cmsg_level = SOL_SOCKET;
70 cmsg->cmsg_type = SCM_RIGHTS;
71 cmsg->cmsg_len = CMSG_LEN(sizeof(int) * 2);
72 ((int *)CMSG_DATA(cmsg))[0] = fd1;
73 ((int *)CMSG_DATA(cmsg))[1] = fd2;
75 iov[0].iov_base = "hello";
76 iov[0].iov_len = 6;
78 msg.msg_iov = iov;
79 msg.msg_iovlen = 1;
81 (void) DO( sendmsg(x, &msg, 0) );
85 void client (void)
87 int s, fd1 = -1, fd2 = -1, size, count = 0, ret;
88 struct sockaddr_un addr;
89 struct iovec iov[1];
90 union {
91 struct cmsghdr cm;
92 char control[CMSG_SPACE(sizeof(int) * 2)];
93 } control_un;
94 struct msghdr msg;
95 /* this was using brace initialization
96 * but that doesn't work on MSL because of padding fields
97 * C99 designated initializers would be nicer
98 * but I'll just do it the simple way */
99 msg.msg_name = NULL;
100 msg.msg_namelen = 0;
101 msg.msg_iov = iov;
102 msg.msg_iovlen = 1;
103 msg.msg_control = control_un.control;
104 msg.msg_controllen = sizeof(control_un);
105 msg.msg_flags = 0;
106 struct cmsghdr *cmsg = &control_un.cm;
107 char buf[1024];
109 iov[0].iov_base = buf;
110 iov[0].iov_len = sizeof(buf);
112 s = socket(PF_UNIX, SOCK_STREAM, 0);
113 if (s == -1) {
114 perror("socket");
115 exit(1);
118 addr.sun_family = AF_UNIX;
119 sprintf(addr.sun_path, "%s", sock);
121 do {
122 count++;
123 ret = connect(s, (struct sockaddr *)&addr, sizeof(addr));
124 if (ret == -1) sleep(1);
125 } while (count < 10 && ret == -1);
127 if (ret == -1) {
128 perror("connect");
129 exit(1);
132 again:
133 if ((size = recvmsg(s, &msg, 0)) == -1) {
134 if (errno == EINTR)
135 goto again; /* SIGCHLD from server exiting could interrupt */
136 perror("recvmsg");
137 exit(1);
141 cmsg = CMSG_FIRSTHDR(&msg);
142 while (cmsg) {
143 if (cmsg->cmsg_level == SOL_SOCKET &&
144 cmsg->cmsg_type == SCM_RIGHTS &&
145 cmsg->cmsg_len == CMSG_LEN(sizeof(int) * 2)) {
146 fd1 = ((int *)CMSG_DATA(cmsg))[0];
147 fd2 = ((int *)CMSG_DATA(cmsg))[1];
150 cmsg = CMSG_NXTHDR(&msg, cmsg);
153 if (fd1 != -1) write(fd1, "Yeah 1\n", 8);
154 if (fd2 != -1) write(fd2, "Yeah 2\n", 8);
158 int main (int argc, char **argv)
160 int pid, status;
162 CLOSE_INHERITED_FDS;
164 pid = getpid();
165 sprintf(filea, "/tmp/data1.%d", pid);
166 sprintf(fileb, "/tmp/data2.%d", pid);
167 sprintf(sock, "/tmp/sock.%d", pid);
169 if ((pid = fork()) == 0) {
170 server();
171 return 0;
174 client();
176 wait(&status);
178 (void) DO( unlink(filea) );
179 (void) DO( unlink(fileb) );
180 (void) DO( unlink(sock) );
181 return 0;