xref: /openbsd-src/regress/lib/libpthread/socket/2/socket2.c (revision b6915e4e5b0edef64ed8c2ee411c0ce32b37dfd7)
1*b6915e4eStedu /*	$OpenBSD: socket2.c,v 1.7 2015/11/04 21:29:20 tedu Exp $	*/
2b2ea75c1Sfgsch /*
3b2ea75c1Sfgsch  * Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors,
4b2ea75c1Sfgsch  * proven@mit.edu All rights reserved.
5b2ea75c1Sfgsch  *
6b2ea75c1Sfgsch  * Redistribution and use in source and binary forms, with or without
7b2ea75c1Sfgsch  * modification, are permitted provided that the following conditions
8b2ea75c1Sfgsch  * are met:
9b2ea75c1Sfgsch  * 1. Redistributions of source code must retain the above copyright
10b2ea75c1Sfgsch  *    notice, this list of conditions and the following disclaimer.
11b2ea75c1Sfgsch  * 2. Redistributions in binary form must reproduce the above copyright
12b2ea75c1Sfgsch  *    notice, this list of conditions and the following disclaimer in the
13b2ea75c1Sfgsch  *    documentation and/or other materials provided with the distribution.
14b2ea75c1Sfgsch  * 3. All advertising materials mentioning features or use of this software
15b2ea75c1Sfgsch  *    must display the following acknowledgement:
16b2ea75c1Sfgsch  *	This product includes software developed by Chris Provenzano,
17b2ea75c1Sfgsch  *	the University of California, Berkeley, and contributors.
18b2ea75c1Sfgsch  * 4. Neither the name of Chris Provenzano, the University, nor the names of
19b2ea75c1Sfgsch  *   contributors may be used to endorse or promote products derived
20b2ea75c1Sfgsch  *   from this software without specific prior written permission.
21b2ea75c1Sfgsch  *
22b2ea75c1Sfgsch  * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO AND CONTRIBUTORS ``AS IS'' AND
23b2ea75c1Sfgsch  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24b2ea75c1Sfgsch  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25b2ea75c1Sfgsch  * ARE DISCLAIMED.  IN NO EVENT SHALL CHRIS PROVENZANO, THE REGENTS OR
26b2ea75c1Sfgsch  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27b2ea75c1Sfgsch  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28b2ea75c1Sfgsch  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
29b2ea75c1Sfgsch  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30b2ea75c1Sfgsch  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
31b2ea75c1Sfgsch  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
32b2ea75c1Sfgsch  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33b2ea75c1Sfgsch  */
34b2ea75c1Sfgsch 
35b2ea75c1Sfgsch /* ==== test_sock_1.c =========================================================
36b2ea75c1Sfgsch  * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
37b2ea75c1Sfgsch  *
38b2ea75c1Sfgsch  * Description : Test pthread_create() and pthread_exit() calls.
39b2ea75c1Sfgsch  *
40b2ea75c1Sfgsch  *  1.00 93/08/03 proven
41b2ea75c1Sfgsch  *      -Started coding this file.
42b2ea75c1Sfgsch  */
43b2ea75c1Sfgsch 
44b2ea75c1Sfgsch #include <pthread.h>
45b2ea75c1Sfgsch #include <pthread_np.h>
46b2ea75c1Sfgsch #include <errno.h>
47b2ea75c1Sfgsch #include <stdio.h>
48b2ea75c1Sfgsch #include <sys/types.h>
49b2ea75c1Sfgsch #include <sys/wait.h>
50b2ea75c1Sfgsch #include <sys/socket.h>
51b2ea75c1Sfgsch #include <netinet/in.h>
52b2ea75c1Sfgsch #include <unistd.h>
53b2ea75c1Sfgsch #include <string.h>
548445c537Stodd #include <stdlib.h>
55b2ea75c1Sfgsch #include "test.h"
56b2ea75c1Sfgsch 
57b2ea75c1Sfgsch struct sockaddr_in a_sout;
58b2ea75c1Sfgsch 
59b2ea75c1Sfgsch #define MESSAGE5 "This should be message #5"
60b2ea75c1Sfgsch #define MESSAGE6 "This should be message #6"
61b2ea75c1Sfgsch 
62db3296cfSderaadt static void *
sock_write(void * arg)63db3296cfSderaadt sock_write(void *arg)
64b2ea75c1Sfgsch {
65b2ea75c1Sfgsch 	int fd = *(int *)arg;
66b2ea75c1Sfgsch 
67b2ea75c1Sfgsch 	SET_NAME("writer");
68b2ea75c1Sfgsch 	CHECKe(write(fd, MESSAGE5, sizeof(MESSAGE5)));
69b2ea75c1Sfgsch 	return(NULL);
70b2ea75c1Sfgsch }
71b2ea75c1Sfgsch 
72b2ea75c1Sfgsch static pthread_mutex_t waiter_mutex = PTHREAD_MUTEX_INITIALIZER;
73b2ea75c1Sfgsch 
74db3296cfSderaadt static void *
waiter(void * arg)75d0774bb2Sfgsch waiter(void *arg)
76b2ea75c1Sfgsch {
77b2ea75c1Sfgsch 	int status;
78b2ea75c1Sfgsch 	pid_t pid;
79b2ea75c1Sfgsch 
80b2ea75c1Sfgsch 	SET_NAME("waiter");
81b2ea75c1Sfgsch 	CHECKr(pthread_mutex_lock(&waiter_mutex));
82b2ea75c1Sfgsch 	printf("waiting for child\n");
83b2ea75c1Sfgsch 	CHECKe(pid = wait(&status));
84b2ea75c1Sfgsch 	ASSERT(WIFEXITED(status));
85b2ea75c1Sfgsch 	ASSERT(WEXITSTATUS(status) == 0);
86b2ea75c1Sfgsch 	printf("child exited\n");
87b2ea75c1Sfgsch 	CHECKr(pthread_mutex_unlock(&waiter_mutex));
88b2ea75c1Sfgsch 	return (NULL);
89b2ea75c1Sfgsch }
90b2ea75c1Sfgsch 
91db3296cfSderaadt static void *
sock_accept(void * arg)92db3296cfSderaadt sock_accept(void *arg)
93b2ea75c1Sfgsch {
94b2ea75c1Sfgsch 	pthread_t thread, wthread;
95b2ea75c1Sfgsch 	struct sockaddr a_sin;
96b2ea75c1Sfgsch 	int a_sin_size, a_fd, fd;
97b2ea75c1Sfgsch 	u_int16_t port;
98b2ea75c1Sfgsch 	char buf[1024];
99b2ea75c1Sfgsch 	pid_t pid;
100b2ea75c1Sfgsch 
101b2ea75c1Sfgsch 	port = 3276;
102b2ea75c1Sfgsch 	a_sout.sin_family = AF_INET;
103b2ea75c1Sfgsch 	a_sout.sin_port = htons(port);
104b2ea75c1Sfgsch 	a_sout.sin_addr.s_addr = INADDR_ANY;
105b2ea75c1Sfgsch 
106b2ea75c1Sfgsch 	CHECKe(a_fd = socket(AF_INET, SOCK_STREAM, 0));
107b2ea75c1Sfgsch 
108b2ea75c1Sfgsch 	while(1) {
109b2ea75c1Sfgsch 		if (bind(a_fd, (struct sockaddr *)&a_sout, sizeof(a_sout))==0)
110b2ea75c1Sfgsch 			break;
111b2ea75c1Sfgsch 		if (errno == EADDRINUSE) {
112b2ea75c1Sfgsch 			a_sout.sin_port = htons((++port));
113b2ea75c1Sfgsch 			continue;
114b2ea75c1Sfgsch 		}
115b2ea75c1Sfgsch 		DIE(errno, "bind");
116b2ea75c1Sfgsch 	}
117b2ea75c1Sfgsch 
118b2ea75c1Sfgsch 	printf("listening on port %d\n", port);
119b2ea75c1Sfgsch 
120b2ea75c1Sfgsch 	CHECKe(listen(a_fd, 2));
121b2ea75c1Sfgsch 
122b2ea75c1Sfgsch 	printf("%d: This should be message #1\n", getpid());
123b2ea75c1Sfgsch 
124b2ea75c1Sfgsch 	CHECKr(pthread_mutex_init(&waiter_mutex, NULL));
125b2ea75c1Sfgsch 	CHECKr(pthread_mutex_lock(&waiter_mutex));
126b2ea75c1Sfgsch 	CHECKr(pthread_create(&wthread, NULL, waiter, NULL));
127b2ea75c1Sfgsch 
128112e1910Sderaadt 	snprintf(buf, sizeof buf, "%d", port);
1298719f1cfSfgsch 
130b2ea75c1Sfgsch 	CHECKe(pid = fork());
131b2ea75c1Sfgsch 	switch(pid) {
132b2ea75c1Sfgsch 	case 0:
1338719f1cfSfgsch 		execl("socket2a", "socket2a", "fork okay", buf, (char *)NULL);
134b2ea75c1Sfgsch 		DIE(errno, "execl");
135b2ea75c1Sfgsch 	default:
136b2ea75c1Sfgsch 		break;
137b2ea75c1Sfgsch 	}
138b2ea75c1Sfgsch 	CHECKr(pthread_mutex_unlock(&waiter_mutex));
139b2ea75c1Sfgsch 	pthread_yield();
140b2ea75c1Sfgsch 
141b2ea75c1Sfgsch 	a_sin_size = sizeof(a_sin);
142b2ea75c1Sfgsch 	CHECKe(fd = accept(a_fd, &a_sin, &a_sin_size));
143b2ea75c1Sfgsch 	CHECKe(close(fd));
144b2ea75c1Sfgsch 
145b2ea75c1Sfgsch 	sleep(1);
146b2ea75c1Sfgsch 
147b2ea75c1Sfgsch 	printf("%d: This should be message #4\n", getpid());
148b2ea75c1Sfgsch 
149b2ea75c1Sfgsch 	a_sin_size = sizeof(a_sin);
150b2ea75c1Sfgsch 	memset(&a_sin, 0, sizeof(a_sin));
151b2ea75c1Sfgsch 	CHECKe(fd = accept(a_fd, &a_sin, &a_sin_size));
152b2ea75c1Sfgsch 
153b2ea75c1Sfgsch 	/* Setup a write thread */
154b2ea75c1Sfgsch 
155b2ea75c1Sfgsch 	CHECKr(pthread_create(&thread, NULL, sock_write, &fd));
156b2ea75c1Sfgsch 	CHECKe(read(fd, buf, 1024));
157b2ea75c1Sfgsch 
158b2ea75c1Sfgsch 	printf("%d: %s\n", getpid(), buf); /* message 6 */
159b2ea75c1Sfgsch 
160b2ea75c1Sfgsch 	CHECKe(close(fd));
161b2ea75c1Sfgsch 
162b2ea75c1Sfgsch 	if (pthread_mutex_trylock(&waiter_mutex) == EBUSY) {
163b2ea75c1Sfgsch 		sleep(2);
164b2ea75c1Sfgsch 		if (pthread_mutex_trylock(&waiter_mutex) == EBUSY) {
165b2ea75c1Sfgsch 			/* forcibly kill child */
166b2ea75c1Sfgsch 			CHECKe(kill(pid, SIGKILL));
167b2ea75c1Sfgsch 			PANIC("child %d took too long to exit", pid);
168b2ea75c1Sfgsch 		}
169b2ea75c1Sfgsch 	}
170b2ea75c1Sfgsch 	CHECKr(pthread_join(wthread, NULL));
171b2ea75c1Sfgsch 
172b2ea75c1Sfgsch 	return(NULL);
173b2ea75c1Sfgsch }
174b2ea75c1Sfgsch 
175b2ea75c1Sfgsch int
main(int argc,char * argv[])176db3296cfSderaadt main(int argc, char *argv[])
177b2ea75c1Sfgsch {
178b2ea75c1Sfgsch 	pthread_t thread;
179b2ea75c1Sfgsch 
180*b6915e4eStedu 	setvbuf(stdout, NULL, _IONBF, 0);
181*b6915e4eStedu 	setvbuf(stderr, NULL, _IONBF, 0);
182b2ea75c1Sfgsch 
183b2ea75c1Sfgsch 	CHECKr(pthread_create(&thread, NULL, sock_accept,
184b2ea75c1Sfgsch 	    (void *)0xdeadbeaf));
185b2ea75c1Sfgsch 
186b2ea75c1Sfgsch 	CHECKr(pthread_join(thread, NULL));
187b2ea75c1Sfgsch 
188b2ea75c1Sfgsch 	SUCCEED;
189b2ea75c1Sfgsch }
190