fdleak_cmsg.c revision b32f58018498ea2225959b0ba11c18f0c433deef
1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 4b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 5b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 6b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 7b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <sys/socket.h> 10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 13b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 14b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 15b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 16b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 17b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 18b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 19b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <string.h> 22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <sys/types.h> 23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <sys/wait.h> 24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <sys/un.h> 25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <stdio.h> 26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <fcntl.h> 27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <unistd.h> 28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <stdlib.h> 29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <errno.h> 30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "fdleak.h" 31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownchar filea[24]; 33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownchar fileb[24]; 34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownchar sock[24]; 35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid server (void) 37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int s, fd1, fd2; 39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct sockaddr_un addr; 40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fd1 = DO( open(filea, O_RDWR | O_CREAT | O_TRUNC, 0750) ); 42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fd2 = DO( open(fileb, O_RDWR | O_CREAT | O_TRUNC, 0750) ); 43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown s = DO( socket(PF_UNIX, SOCK_STREAM, 0) ); 44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown memset(&addr, 0, sizeof(addr)); 46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addr.sun_family = AF_UNIX; 47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sprintf(addr.sun_path, "%s", sock); 48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unlink(sock); 50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DO( bind(s, (struct sockaddr *)&addr, sizeof(addr)) ); 51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DO( listen(s, 5) ); 52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int x; 55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int baddrsize = 0; 56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct sockaddr_un baddr; 57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct msghdr msg = {NULL, 0, NULL, 0, 0, 0, 0}; 58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct cmsghdr *cmsg; 59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown char buf[CMSG_SPACE(sizeof(int) * 2)]; 60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct iovec iov[1]; 61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown memset(&baddr, 0, sizeof(baddr)); 63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown x = DO( accept(s, (struct sockaddr *)&baddr, &baddrsize) ); 64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown msg.msg_control = buf; 66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown msg.msg_controllen = sizeof(buf); 67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cmsg = CMSG_FIRSTHDR(&msg); 68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cmsg->cmsg_level = SOL_SOCKET; 69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cmsg->cmsg_type = SCM_RIGHTS; 70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cmsg->cmsg_len = CMSG_LEN(sizeof(int) * 2); 71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ((int *)CMSG_DATA(cmsg))[0] = fd1; 72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ((int *)CMSG_DATA(cmsg))[1] = fd2; 73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown iov[0].iov_base = "hello"; 75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown iov[0].iov_len = 6; 76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown msg.msg_iov = iov; 78ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown msg.msg_iovlen = 1; 79ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 80ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DO( sendmsg(x, &msg, 0) ); 81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 82ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 83ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 84ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid client (void) 85ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 86ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int s, fd1 = -1, fd2 = -1, size, count = 0, ret; 87ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct sockaddr_un addr; 88ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct iovec iov[1]; 89ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown union { 90ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct cmsghdr cm; 91ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown char control[CMSG_SPACE(sizeof(int) * 2)]; 92ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } control_un; 93ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct msghdr msg = { NULL, 0, iov, 1, control_un.control, 94ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sizeof(control_un), 0 }; 95ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct cmsghdr *cmsg = &control_un.cm; 96ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown char buf[1024]; 97ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 98ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown iov[0].iov_base = buf; 99ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown iov[0].iov_len = sizeof(buf); 100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown s = socket(PF_UNIX, SOCK_STREAM, 0); 102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (s == -1) { 103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown perror("socket"); 104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown exit(1); 105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addr.sun_family = AF_UNIX; 108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sprintf(addr.sun_path, "%s", sock); 109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { 111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown count++; 112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ret = connect(s, (struct sockaddr *)&addr, sizeof(addr)); 113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (ret == -1) sleep(1); 114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (count < 10 && ret == -1); 115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (ret == -1) { 117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown perror("connect"); 118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown exit(1); 119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown again: 122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ((size = recvmsg(s, &msg, 0)) == -1) { 123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (errno == EINTR) 124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown goto again; /* SIGCHLD from server exiting could interrupt */ 125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown perror("recvmsg"); 126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown exit(1); 127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cmsg = CMSG_FIRSTHDR(&msg); 131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (cmsg) { 132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (cmsg->cmsg_level == SOL_SOCKET && 133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cmsg->cmsg_type == SCM_RIGHTS && 134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cmsg->cmsg_len == CMSG_LEN(sizeof(int) * 2)) { 135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fd1 = ((int *)CMSG_DATA(cmsg))[0]; 136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fd2 = ((int *)CMSG_DATA(cmsg))[1]; 137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cmsg = CMSG_NXTHDR(&msg, cmsg); 140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (fd1 != -1) write(fd1, "Yeah 1\n", 8); 143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (fd2 != -1) write(fd2, "Yeah 2\n", 8); 144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint main (int argc, char **argv) 148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int pid, status; 150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLOSE_INHERITED_FDS; 152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pid = getpid(); 154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sprintf(filea, "/tmp/data1.%d", pid); 155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sprintf(fileb, "/tmp/data2.%d", pid); 156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sprintf(sock, "/tmp/sock.%d", pid); 157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ((pid = fork()) == 0) { 159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown server(); 160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 0; 161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown client(); 164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown wait(&status); 166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DO( unlink(filea) ); 168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DO( unlink(fileb) ); 169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DO( unlink(sock) ); 170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 0; 171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 172