1*86ecbf1eSjca /* $OpenBSD: recvmsg.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/uio.h>
7d13be5d4Sfgsch #include <sys/socket.h>
8d13be5d4Sfgsch #include <netinet/in.h>
9d13be5d4Sfgsch #include <pthread.h>
10d13be5d4Sfgsch #include <signal.h>
11d13be5d4Sfgsch #include <unistd.h>
12d13be5d4Sfgsch #include "test.h"
13d13be5d4Sfgsch
14d13be5d4Sfgsch volatile sig_atomic_t hits = 0;
15d13be5d4Sfgsch
16d13be5d4Sfgsch void
handler(int sig)17d13be5d4Sfgsch handler(int sig)
18d13be5d4Sfgsch {
19d13be5d4Sfgsch hits++;
20d13be5d4Sfgsch }
21d13be5d4Sfgsch
22d13be5d4Sfgsch void *
thr_recvmsg(void * arg)23d13be5d4Sfgsch thr_recvmsg(void *arg)
24d13be5d4Sfgsch {
25d13be5d4Sfgsch struct sockaddr_in sa;
26d13be5d4Sfgsch struct msghdr msg;
27d13be5d4Sfgsch struct iovec iov;
28d13be5d4Sfgsch char buf;
29d13be5d4Sfgsch int s;
30d13be5d4Sfgsch
31d13be5d4Sfgsch CHECKe(s = socket(AF_INET, SOCK_DGRAM, 0));
32d13be5d4Sfgsch bzero(&sa, sizeof(sa));
33*86ecbf1eSjca sa.sin_family = AF_INET;
34d13be5d4Sfgsch sa.sin_port = htons(6543);
35d13be5d4Sfgsch CHECKe(bind(s, (const void*)&sa, sizeof(sa)));
36d13be5d4Sfgsch bzero(&msg, sizeof(msg));
37d13be5d4Sfgsch iov.iov_base = &buf;
38d13be5d4Sfgsch iov.iov_len = 1;
39d13be5d4Sfgsch msg.msg_iov = &iov;
40d13be5d4Sfgsch msg.msg_iovlen = 1;
41d13be5d4Sfgsch ASSERT(recvmsg(s, &msg, 0) == -1);
42d13be5d4Sfgsch return ((caddr_t)NULL + errno);
43d13be5d4Sfgsch }
44d13be5d4Sfgsch
45d13be5d4Sfgsch int
main(int argc,char ** argv)46d13be5d4Sfgsch main(int argc, char **argv)
47d13be5d4Sfgsch {
48d13be5d4Sfgsch struct sigaction sa;
49d13be5d4Sfgsch pthread_t tid;
50d13be5d4Sfgsch void *retval;
51d13be5d4Sfgsch
52d13be5d4Sfgsch bzero(&sa, sizeof(sa));
53d13be5d4Sfgsch sa.sa_handler = handler;
54d13be5d4Sfgsch sa.sa_flags = SA_RESTART;
55d13be5d4Sfgsch CHECKe(sigaction(SIGUSR1, &sa, NULL));
56d13be5d4Sfgsch sa.sa_flags = 0;
57d13be5d4Sfgsch CHECKe(sigaction(SIGUSR2, &sa, NULL));
58d13be5d4Sfgsch
59d13be5d4Sfgsch CHECKr(pthread_create(&tid, NULL, thr_recvmsg, NULL));
60d13be5d4Sfgsch sleep(2);
61d13be5d4Sfgsch
62d13be5d4Sfgsch /* Should restart it. */
63d13be5d4Sfgsch CHECKr(pthread_kill(tid, SIGUSR1));
64d13be5d4Sfgsch sleep(1);
65d13be5d4Sfgsch
66d13be5d4Sfgsch /* Should interrupt it. */
67d13be5d4Sfgsch CHECKr(pthread_kill(tid, SIGUSR2));
68d13be5d4Sfgsch sleep(1);
69d13be5d4Sfgsch
70d13be5d4Sfgsch CHECKr(pthread_join(tid, &retval));
71d13be5d4Sfgsch ASSERT(retval == (void *)EINTR);
72d13be5d4Sfgsch ASSERT(hits == 2);
73d13be5d4Sfgsch SUCCEED;
74d13be5d4Sfgsch }
75