fdpass: new module.
[ccan] / ccan / fdpass / test / run.c
1 #include <ccan/fdpass/fdpass.h>
2 /* Include the C files directly. */
3 #include <ccan/fdpass/fdpass.c>
4 #include <ccan/tap/tap.h>
5
6 #include <sys/types.h>
7 #include <sys/wait.h>
8 #include <sys/un.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <unistd.h>
12 #include <assert.h>
13
14 static void child(int sockfd)
15 {
16         char c;
17         int newfd = fdpass_recv(sockfd);
18         assert(newfd >= 0);
19         assert(read(newfd, &c, 1) == 1);
20         assert(c == 0x77);
21         exit(0);
22 }
23
24 static void child_nofd(int sockfd)
25 {
26         assert(fdpass_recv(sockfd) == -1);
27         exit(0);
28 }
29
30 static void parent(int sockfd)
31 {
32         int pfds[2];
33
34         ok1(pipe(pfds) == 0);
35         ok1(fdpass_send(sockfd, pfds[0]));
36         ok1(close(pfds[0]) == 0);
37         ok1(write(pfds[1], "\x77", 1) == 1);
38         ok1(close(pfds[1]) == 0);
39 }
40
41 int main(void)
42 {
43         int sv[2];
44         int pid, wstatus;
45
46         plan_tests(17);
47         ok1(socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == 0);
48
49         pid = fork();
50         if (pid == 0) {
51                 close(sv[1]);
52                 child(sv[0]);
53         }
54
55         parent(sv[1]);
56         ok1(waitpid(pid, &wstatus, 0) == pid);
57         ok1(WIFEXITED(wstatus));
58         ok1(WEXITSTATUS(wstatus) == 0);
59
60         pid = fork();
61         if (pid == 0) {
62                 close(sv[1]);
63                 child_nofd(sv[0]);
64         }
65         /* Don't write an fd. */
66         ok1(write(sv[1], "1", 1) == 1);
67         ok1(waitpid(pid, &wstatus, 0) == pid);
68         ok1(WIFEXITED(wstatus));
69         ok1(WEXITSTATUS(wstatus) == 0);
70         
71         pid = fork();
72         if (pid == 0) {
73                 close(sv[1]);
74                 child_nofd(sv[0]);
75         }
76         /* Don't write anything. */
77         close(sv[1]);
78         ok1(waitpid(pid, &wstatus, 0) == pid);
79         ok1(WIFEXITED(wstatus));
80         ok1(WEXITSTATUS(wstatus) == 0);
81         
82         close(sv[0]);
83         /* Test fdpass_recv from invalid fd. */
84         ok1(fdpass_recv(sv[0]) == -1 && errno == EBADF);
85
86         /* This exits depending on whether all tests passed */
87         return exit_status();
88 }