xref: /openbsd-src/regress/sys/kern/accept/accept.c (revision a28daedfc357b214be5c701aa8ba8adb29a7f1c2)
1 /*	$OpenBSD: accept.c,v 1.4 2004/02/28 03:29:15 deraadt 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 	sun.sun_len = SUN_LEN(&sun);
44 
45 
46 	if (bind(listensock, (struct sockaddr *)&sun, sizeof(sun)) == -1)
47 		err(1, "bind");
48 
49 	if (listen(listensock, 1) == -1)
50 		err(1, "listen");
51 
52 	switch (fork()) {
53 	case -1:
54 		err(1, "fork");
55 	case 0:
56 		return child();
57 	}
58 
59 	while ((fd = open("/dev/null", O_RDONLY)) >= 0)
60 		lastfd = fd;
61 
62 	switch (fork()) {
63 	case -1:
64 		err(1, "fork");
65 	case 0:
66 		ischild = 1;
67 		close(lastfd);	/* Close one fd so that accept can succeed */
68 		sleep(2); /* sleep a bit so that we're the second to accept */
69 	}
70 
71 	sock = accept(listensock, (struct sockaddr *)&csun, &csunlen);
72 
73 	if (!ischild && sock >= 0)
74 		errx(1, "accept succeeded in parent");
75 	if (ischild && sock < 0)
76 		err(1, "accept failed in child");
77 
78 	while (!ischild && wait4(-1, &status, 0, NULL) > 0)
79 		;
80 
81 	return (0);
82 }
83 
84 int
85 child()
86 {
87 	int i, fd, sock;
88 	struct sockaddr_un sun;
89 
90 	/*
91 	 * Create socket and connect to the receiver.
92 	 */
93 	if ((sock = socket(PF_LOCAL, SOCK_STREAM, 0)) == -1)
94 		errx(1, "child socket");
95 
96 	(void) memset(&sun, 0, sizeof(sun));
97 	sun.sun_family = AF_LOCAL;
98 	(void) strlcpy(sun.sun_path, SOCK_NAME, sizeof sun.sun_path);
99 	sun.sun_len = SUN_LEN(&sun);
100 
101 	if (connect(sock, (struct sockaddr *)&sun, sizeof(sun)) == -1)
102 		err(1, "child connect");
103 
104 	return (0);
105 }
106