xref: /openbsd/regress/sys/kern/accept/accept.c (revision 09467b48)
1 /*	$OpenBSD: accept.c,v 1.5 2015/01/19 00:22:30 guenther Exp $	*/
2 /*
3  *	Written by Artur Grabowski <art@openbsd.org>, 2002 Public Domain.
4  */
5 #include <sys/param.h>
6 #include <sys/socket.h>
7 #include <sys/time.h>
8 #include <sys/wait.h>
9 #include <sys/un.h>
10 
11 #include <stdlib.h>
12 #include <stdio.h>
13 #include <unistd.h>
14 #include <fcntl.h>
15 #include <err.h>
16 #include <signal.h>
17 #include <string.h>
18 
19 #define	SOCK_NAME	"test-sock"
20 
21 int	child(void);
22 
23 int
24 main(int argc, char *argv[])
25 {
26 	int listensock, sock;
27 	struct sockaddr_un sun, csun;
28 	int csunlen;
29 	int fd, lastfd;
30 	int status;
31 	int ischild = 0;
32 
33 	/*
34 	 * Create the listen socket.
35 	 */
36 	if ((listensock = socket(PF_LOCAL, SOCK_STREAM, 0)) == -1)
37 		err(1, "socket");
38 
39 	unlink(SOCK_NAME);
40 	memset(&sun, 0, sizeof(sun));
41 	sun.sun_family = AF_LOCAL;
42 	strlcpy(sun.sun_path, SOCK_NAME, sizeof sun.sun_path);
43 
44 
45 	if (bind(listensock, (struct sockaddr *)&sun, sizeof(sun)) == -1)
46 		err(1, "bind");
47 
48 	if (listen(listensock, 1) == -1)
49 		err(1, "listen");
50 
51 	switch (fork()) {
52 	case -1:
53 		err(1, "fork");
54 	case 0:
55 		return child();
56 	}
57 
58 	while ((fd = open("/dev/null", O_RDONLY)) >= 0)
59 		lastfd = fd;
60 
61 	switch (fork()) {
62 	case -1:
63 		err(1, "fork");
64 	case 0:
65 		ischild = 1;
66 		close(lastfd);	/* Close one fd so that accept can succeed */
67 		sleep(2); /* sleep a bit so that we're the second to accept */
68 	}
69 
70 	sock = accept(listensock, (struct sockaddr *)&csun, &csunlen);
71 
72 	if (!ischild && sock >= 0)
73 		errx(1, "accept succeeded in parent");
74 	if (ischild && sock < 0)
75 		err(1, "accept failed in child");
76 
77 	while (!ischild && wait4(-1, &status, 0, NULL) > 0)
78 		;
79 
80 	return (0);
81 }
82 
83 int
84 child()
85 {
86 	int i, fd, sock;
87 	struct sockaddr_un sun;
88 
89 	/*
90 	 * Create socket and connect to the receiver.
91 	 */
92 	if ((sock = socket(PF_LOCAL, SOCK_STREAM, 0)) == -1)
93 		errx(1, "child socket");
94 
95 	(void) memset(&sun, 0, sizeof(sun));
96 	sun.sun_family = AF_LOCAL;
97 	(void) strlcpy(sun.sun_path, SOCK_NAME, sizeof sun.sun_path);
98 
99 	if (connect(sock, (struct sockaddr *)&sun, sizeof(sun)) == -1)
100 		err(1, "child connect");
101 
102 	return (0);
103 }
104