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