fdleak_cmsg.c revision b32f58018498ea2225959b0ba11c18f0c433deef
14e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 24e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 34e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 44e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 54e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 64e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 74e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 84e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 94e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <sys/socket.h> 104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <string.h> 224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <sys/types.h> 234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <sys/wait.h> 244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <sys/un.h> 254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <stdio.h> 264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <fcntl.h> 274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <unistd.h> 284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <stdlib.h> 294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <errno.h> 30#include "fdleak.h" 31 32char filea[24]; 33char fileb[24]; 34char sock[24]; 35 36void 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 84void 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 147int 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