Merge branch 'vendor/GCC44'
[dragonfly.git] / test / debug / fdpassing.c
1
2 /*
3  * cc -Wall fdpassing.c -o /tmp/fdp
4  */
5 #include <sys/types.h>
6 #include <sys/socket.h>
7 #include <sys/wait.h>
8 #include <sys/uio.h>
9 #include <sys/stat.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <unistd.h>
13 #include <string.h>
14 #include <fcntl.h>
15 #include <errno.h>
16
17 void sendfd(int s, int fd);
18 int recvfd(int s);
19
20 int
21 main(int ac, char **av)
22 {
23     struct stat st;
24     int fds[2];
25     int fd;
26     int i;
27     int dummy;
28
29     if (socketpair(PF_LOCAL, SOCK_STREAM, 0, fds) < 0) {
30         perror("socktepair");
31         exit(1);
32     }
33     fcntl(fds[0], F_SETFL, 0);
34     fcntl(fds[1], F_SETFL, 0);
35     if (fork() == 0) {
36         close(fds[1]);
37         while ((fd = recvfd(fds[0])) >= 0) {
38                 fflush(stdout);
39                 usleep(1000000 / 10);
40                 if (fstat(fd, &st) < 0)
41                     printf("B");
42                 else if (read(fd, &dummy, sizeof(dummy)) != sizeof(dummy))
43                     printf("b");
44                 else
45                     printf("r");
46                 close(fd);
47                 usleep(1000000 / 10);
48         }
49         printf("X\n");
50         _exit(0);
51     }
52     close(fds[0]);
53
54     for (;;) {
55         for (i = 1; i < ac; ++i) {
56             if ((fd = open(av[i], O_RDONLY, 0666)) < 0) {
57                 fprintf(stderr, "unable to open %s\n", av[i]);
58             } else {
59                 sendfd(fds[1], fd);
60                 printf("w");
61                 fflush(stdout);
62                 close(fd);
63             }
64         }
65         usleep(1000000 / 5 - 10000);
66     }
67     printf("DONE\n");
68     close(fds[1]);
69     while (wait(NULL) < 0)
70         ;
71     return(0);
72 }
73
74 void
75 sendfd(int s, int fd)
76 {
77     struct msghdr msg;
78     struct {
79         struct cmsghdr cmsg;
80         int fd;
81     } cmsg;
82     struct iovec iov;
83
84     bzero(&msg, sizeof(msg));
85     bzero(&cmsg, sizeof(cmsg));
86
87     iov.iov_base = NULL;
88     iov.iov_len = 0;
89
90     msg.msg_iov = &iov;
91     msg.msg_iovlen = 1;
92     msg.msg_control = (caddr_t)&cmsg;
93     msg.msg_controllen = sizeof(cmsg);
94
95     cmsg.cmsg.cmsg_level = SOL_SOCKET;
96     cmsg.cmsg.cmsg_type = SCM_RIGHTS;
97     cmsg.cmsg.cmsg_len = sizeof(cmsg);
98     cmsg.fd = fd;
99
100     if (sendmsg(s, &msg, 0) < 0) {
101         printf("sendfd: failed %s\n", strerror(errno));
102         exit(1);
103     }
104 }
105
106 int
107 recvfd(int s)
108 {
109     struct msghdr msg;
110     struct {
111         struct cmsghdr cmsg;
112         int fd;
113     } cmsg;
114     struct iovec iov;
115     int r;
116     int dummy;
117
118     bzero(&msg, sizeof(msg));
119     bzero(&cmsg, sizeof(cmsg));
120
121     iov.iov_base = &dummy;
122     iov.iov_len = sizeof(dummy);
123
124     msg.msg_iov = &iov;
125     msg.msg_iovlen = 1;
126     msg.msg_control = (caddr_t)&cmsg;
127     msg.msg_controllen = sizeof(cmsg);
128
129 #if 0
130     cmsg.cmsg.cmsg_level = SOL_SOCKET;
131     cmsg.cmsg.cmsg_type = SCM_RIGHTS;
132 #endif
133     cmsg.cmsg.cmsg_len = sizeof(cmsg);
134     cmsg.fd = -1;
135
136     if ((r = recvmsg(s, &msg, MSG_EOR)) < 0) {
137         printf("recvmsg: failed %s\n", strerror(errno));
138         return(-1);
139     }
140     return(cmsg.fd);
141 }