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