xref: /openbsd-src/regress/lib/libpthread/restart/accept/accept.c (revision 86ecbf1ee3c48d7a406e2f335749d917733f4718)
1*86ecbf1eSjca /*	$OpenBSD: accept.c,v 1.2 2016/01/27 01:20:10 jca Exp $	*/
2d13be5d4Sfgsch /*
3d13be5d4Sfgsch  * Federico G. Schwindt <fgsch@openbsd.org>, 2011. Public Domain.
4d13be5d4Sfgsch  */
5d13be5d4Sfgsch #include <sys/types.h>
6d13be5d4Sfgsch #include <sys/socket.h>
7d13be5d4Sfgsch #include <netinet/in.h>
8d13be5d4Sfgsch #include <pthread.h>
9d13be5d4Sfgsch #include <signal.h>
10d13be5d4Sfgsch #include <unistd.h>
11d13be5d4Sfgsch #include "test.h"
12d13be5d4Sfgsch 
13d13be5d4Sfgsch volatile sig_atomic_t hits = 0;
14d13be5d4Sfgsch 
15d13be5d4Sfgsch void
handler(int sig)16d13be5d4Sfgsch handler(int sig)
17d13be5d4Sfgsch {
18d13be5d4Sfgsch 	hits++;
19d13be5d4Sfgsch }
20d13be5d4Sfgsch 
21d13be5d4Sfgsch void *
thr_accept(void * arg)22d13be5d4Sfgsch thr_accept(void *arg)
23d13be5d4Sfgsch {
24d13be5d4Sfgsch 	struct sockaddr_in sa;
25d13be5d4Sfgsch 	socklen_t salen;
26d13be5d4Sfgsch 	int s;
27d13be5d4Sfgsch 
28d13be5d4Sfgsch 	CHECKe(s = socket(AF_INET, SOCK_STREAM, 0));
29d13be5d4Sfgsch 	bzero(&sa, sizeof(sa));
30*86ecbf1eSjca 	sa.sin_family = AF_INET;
31d13be5d4Sfgsch 	sa.sin_port = htons(6543);
32d13be5d4Sfgsch 	CHECKe(bind(s, (const void*)&sa, sizeof(sa)));
33d13be5d4Sfgsch 	CHECKe(listen(s, 10));
34d13be5d4Sfgsch 	salen = sizeof(sa);
35d13be5d4Sfgsch 	ASSERT(accept(s, (struct sockaddr *)&sa, &salen) == -1);
36d13be5d4Sfgsch 	return ((caddr_t)NULL + errno);
37d13be5d4Sfgsch }
38d13be5d4Sfgsch 
39d13be5d4Sfgsch int
main(int argc,char ** argv)40d13be5d4Sfgsch main(int argc, char **argv)
41d13be5d4Sfgsch {
42d13be5d4Sfgsch 	struct sigaction sa;
43d13be5d4Sfgsch 	pthread_t tid;
44d13be5d4Sfgsch 	void *retval;
45d13be5d4Sfgsch 
46d13be5d4Sfgsch 	bzero(&sa, sizeof(sa));
47d13be5d4Sfgsch 	sa.sa_handler = handler;
48d13be5d4Sfgsch 	sa.sa_flags = SA_RESTART;
49d13be5d4Sfgsch 	CHECKe(sigaction(SIGUSR1, &sa, NULL));
50d13be5d4Sfgsch 	sa.sa_flags = 0;
51d13be5d4Sfgsch 	CHECKe(sigaction(SIGUSR2, &sa, NULL));
52d13be5d4Sfgsch 
53d13be5d4Sfgsch 	CHECKr(pthread_create(&tid, NULL, thr_accept, NULL));
54d13be5d4Sfgsch 	sleep(2);
55d13be5d4Sfgsch 
56d13be5d4Sfgsch 	/* Should restart it. */
57d13be5d4Sfgsch 	CHECKr(pthread_kill(tid, SIGUSR1));
58d13be5d4Sfgsch 	sleep(1);
59d13be5d4Sfgsch 
60d13be5d4Sfgsch 	/* Should interrupt it. */
61d13be5d4Sfgsch 	CHECKr(pthread_kill(tid, SIGUSR2));
62d13be5d4Sfgsch 	sleep(1);
63d13be5d4Sfgsch 
64d13be5d4Sfgsch 	CHECKr(pthread_join(tid, &retval));
65d13be5d4Sfgsch 	ASSERT(retval == (void *)EINTR);
66d13be5d4Sfgsch 	ASSERT(hits == 2);
67d13be5d4Sfgsch 	SUCCEED;
68d13be5d4Sfgsch }
69