1*49a6e16fSderaadt /* $OpenBSD: accept.c,v 1.6 2021/12/13 16:56:49 deraadt Exp $ */
2838d18abSart /*
3838d18abSart * Written by Artur Grabowski <art@openbsd.org>, 2002 Public Domain.
4838d18abSart */
5838d18abSart #include <sys/socket.h>
6838d18abSart #include <sys/time.h>
7838d18abSart #include <sys/wait.h>
8838d18abSart #include <sys/un.h>
9838d18abSart
10838d18abSart #include <stdlib.h>
11838d18abSart #include <stdio.h>
12838d18abSart #include <unistd.h>
13838d18abSart #include <fcntl.h>
14838d18abSart #include <err.h>
15838d18abSart #include <signal.h>
16838d18abSart #include <string.h>
17838d18abSart
18838d18abSart #define SOCK_NAME "test-sock"
19838d18abSart
20838d18abSart int child(void);
21838d18abSart
22838d18abSart int
main(int argc,char * argv[])23db3296cfSderaadt main(int argc, char *argv[])
24838d18abSart {
25838d18abSart int listensock, sock;
26838d18abSart struct sockaddr_un sun, csun;
27838d18abSart int csunlen;
28838d18abSart int fd, lastfd;
29838d18abSart int status;
308481fc67Sart int ischild = 0;
31838d18abSart
32838d18abSart /*
33838d18abSart * Create the listen socket.
34838d18abSart */
35838d18abSart if ((listensock = socket(PF_LOCAL, SOCK_STREAM, 0)) == -1)
36838d18abSart err(1, "socket");
37838d18abSart
38838d18abSart unlink(SOCK_NAME);
39838d18abSart memset(&sun, 0, sizeof(sun));
40838d18abSart sun.sun_family = AF_LOCAL;
414993325bSderaadt strlcpy(sun.sun_path, SOCK_NAME, sizeof sun.sun_path);
42838d18abSart
43838d18abSart
44838d18abSart if (bind(listensock, (struct sockaddr *)&sun, sizeof(sun)) == -1)
45838d18abSart err(1, "bind");
46838d18abSart
47838d18abSart if (listen(listensock, 1) == -1)
48838d18abSart err(1, "listen");
49838d18abSart
50838d18abSart switch (fork()) {
51838d18abSart case -1:
52838d18abSart err(1, "fork");
53838d18abSart case 0:
54838d18abSart return child();
55838d18abSart }
56838d18abSart
57838d18abSart while ((fd = open("/dev/null", O_RDONLY)) >= 0)
58838d18abSart lastfd = fd;
59838d18abSart
60838d18abSart switch (fork()) {
61838d18abSart case -1:
62838d18abSart err(1, "fork");
63838d18abSart case 0:
64838d18abSart ischild = 1;
65838d18abSart close(lastfd); /* Close one fd so that accept can succeed */
66838d18abSart sleep(2); /* sleep a bit so that we're the second to accept */
67838d18abSart }
68838d18abSart
69838d18abSart sock = accept(listensock, (struct sockaddr *)&csun, &csunlen);
70838d18abSart
71838d18abSart if (!ischild && sock >= 0)
72838d18abSart errx(1, "accept succeeded in parent");
73838d18abSart if (ischild && sock < 0)
74838d18abSart err(1, "accept failed in child");
75838d18abSart
76838d18abSart while (!ischild && wait4(-1, &status, 0, NULL) > 0)
77838d18abSart ;
78838d18abSart
79838d18abSart return (0);
80838d18abSart }
81838d18abSart
82838d18abSart int
child()83838d18abSart child()
84838d18abSart {
85838d18abSart int i, fd, sock;
86838d18abSart struct sockaddr_un sun;
87838d18abSart
88838d18abSart /*
89838d18abSart * Create socket and connect to the receiver.
90838d18abSart */
91838d18abSart if ((sock = socket(PF_LOCAL, SOCK_STREAM, 0)) == -1)
92838d18abSart errx(1, "child socket");
93838d18abSart
94838d18abSart (void) memset(&sun, 0, sizeof(sun));
95838d18abSart sun.sun_family = AF_LOCAL;
964993325bSderaadt (void) strlcpy(sun.sun_path, SOCK_NAME, sizeof sun.sun_path);
97838d18abSart
98838d18abSart if (connect(sock, (struct sockaddr *)&sun, sizeof(sun)) == -1)
99838d18abSart err(1, "child connect");
100838d18abSart
101838d18abSart return (0);
102838d18abSart }
103