tmpfs - Fix mount_tmpfs -C
[dragonfly.git] / test / socket / accept4 / cloexec / accept4_cloexec.c
blob2c2490ed782ba82feca2745124289d641d54e422
1 #include <sys/types.h>
2 #include <sys/socket.h>
3 #include <sys/wait.h>
5 #include <arpa/inet.h>
6 #include <netinet/in.h>
8 #include <err.h>
9 #include <errno.h>
10 #include <signal.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <unistd.h>
16 #define CHECKFD_CMD "checkfd"
17 #define CHECKFD_PATH "/usr/local/bin/" CHECKFD_CMD
19 static void
20 usage(const char *cmd)
22 fprintf(stderr, "%s -p port\n", cmd);
23 exit(1);
26 static void
27 connect_client(int port)
29 struct sockaddr_in in;
30 int s;
32 memset(&in, 0, sizeof(in));
33 in.sin_family = AF_INET;
34 in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
35 in.sin_port = htons(port);
37 s = socket(AF_INET, SOCK_STREAM, 0);
38 if (s < 0)
39 err(1, "client socket failed");
40 if (connect(s, (const struct sockaddr *)&in, sizeof(in)) < 0)
41 err(1, "connect failed");
43 pause();
44 exit(0);
47 int
48 main(int argc, char *argv[])
50 pid_t pid;
51 struct sockaddr_in in;
52 int serv_s, s;
53 int opt, port, status, ecode, error;
55 port = 0;
56 while ((opt = getopt(argc, argv, "p:")) != -1) {
57 char *endptr;
59 switch (opt) {
60 case 'p':
61 port = strtol(optarg, &endptr, 0);
62 if (*endptr != '\0')
63 errx(1, "invalid -p %s", optarg);
64 break;
66 default:
67 usage(argv[0]);
70 if (port <= 0)
71 usage(argv[0]);
73 serv_s = socket(AF_INET, SOCK_STREAM, 0);
74 if (serv_s < 0)
75 err(1, "socket failed");
77 memset(&in, 0, sizeof(in));
78 in.sin_family = AF_INET;
79 in.sin_port = htons(port);
80 if (bind(serv_s, (const struct sockaddr *)&in, sizeof(in)) < 0)
81 err(1, "bind failed");
83 if (listen(serv_s, 0) < 0)
84 err(1, "listen failed");
86 pid = fork();
87 if (pid < 0) {
88 err(1, "fork failed");
89 } else if (pid == 0) {
90 connect_client(port);
91 abort();
92 /* NEVER REACHED */
95 s = accept4(serv_s, NULL, NULL, SOCK_CLOEXEC);
96 if (s < 0)
97 error = errno;
98 else
99 error = 0;
101 /* Kill connect_client */
102 kill(pid, SIGKILL);
103 waitpid(pid, &status, 0);
105 if (error)
106 errc(1, error, "accept4 failed");
108 pid = fork();
109 if (pid < 0) {
110 err(1, "fork failed");
111 } else if (pid == 0) {
112 char fd[8];
114 snprintf(fd, sizeof(fd), "%d", s);
115 execl(CHECKFD_PATH, CHECKFD_CMD, fd, NULL);
118 if (waitpid(pid, &status, 0) < 0)
119 err(1, "waitpid failed");
120 if (!WIFEXITED(status))
121 errx(1, "not exited");
122 ecode = WEXITSTATUS(status);
123 if (ecode != 0) {
124 warnx("exit code %d", ecode);
125 abort();
128 fprintf(stderr, "passed\n");
129 exit(0);