Home | History | Annotate | Download | only in tests
      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 
     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    (void) DO( bind(s, (struct sockaddr *)&addr, sizeof(addr)) );
     51    (void) DO( listen(s, 5) );
     52 
     53    {
     54       int x;
     55       unsigned 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       (void) DO( sendmsg(x, &msg, 0) );
     81    }
     82 }
     83 
     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 
    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    (void) DO( unlink(filea) );
    168    (void) DO( unlink(fileb) );
    169    (void) DO( unlink(sock) );
    170    return 0;
    171 }
    172