1*d13be5d4Sfgsch /*	$OpenBSD: readv.c,v 1.1 2011/09/13 23:50:17 fgsch Exp $	*/
2*d13be5d4Sfgsch /*
3*d13be5d4Sfgsch  * Federico G. Schwindt <fgsch@openbsd.org>, 2011. Public Domain.
4*d13be5d4Sfgsch  */
5*d13be5d4Sfgsch #include <sys/types.h>
6*d13be5d4Sfgsch #include <sys/uio.h>
7*d13be5d4Sfgsch #include <pthread.h>
8*d13be5d4Sfgsch #include <signal.h>
9*d13be5d4Sfgsch #include <unistd.h>
10*d13be5d4Sfgsch #include "test.h"
11*d13be5d4Sfgsch 
12*d13be5d4Sfgsch volatile sig_atomic_t hits = 0;
13*d13be5d4Sfgsch 
14*d13be5d4Sfgsch void
handler(int sig)15*d13be5d4Sfgsch handler(int sig)
16*d13be5d4Sfgsch {
17*d13be5d4Sfgsch 	hits++;
18*d13be5d4Sfgsch }
19*d13be5d4Sfgsch 
20*d13be5d4Sfgsch void *
thr_readv(void * arg)21*d13be5d4Sfgsch thr_readv(void *arg)
22*d13be5d4Sfgsch {
23*d13be5d4Sfgsch 	struct iovec iov;
24*d13be5d4Sfgsch 	int fds[2];
25*d13be5d4Sfgsch 	char buf;
26*d13be5d4Sfgsch 
27*d13be5d4Sfgsch 	CHECKe(pipe(fds));
28*d13be5d4Sfgsch 	iov.iov_base = &buf;
29*d13be5d4Sfgsch 	iov.iov_len = 1;
30*d13be5d4Sfgsch 	ASSERT(readv(fds[0], &iov, 1) == -1);
31*d13be5d4Sfgsch 	return ((caddr_t)NULL + errno);
32*d13be5d4Sfgsch }
33*d13be5d4Sfgsch 
34*d13be5d4Sfgsch int
main(int argc,char ** argv)35*d13be5d4Sfgsch main(int argc, char **argv)
36*d13be5d4Sfgsch {
37*d13be5d4Sfgsch 	struct sigaction sa;
38*d13be5d4Sfgsch 	pthread_t tid;
39*d13be5d4Sfgsch 	void *retval;
40*d13be5d4Sfgsch 
41*d13be5d4Sfgsch 	bzero(&sa, sizeof(sa));
42*d13be5d4Sfgsch 	sa.sa_handler = handler;
43*d13be5d4Sfgsch 	sa.sa_flags = SA_RESTART;
44*d13be5d4Sfgsch 	CHECKe(sigaction(SIGUSR1, &sa, NULL));
45*d13be5d4Sfgsch 	sa.sa_flags = 0;
46*d13be5d4Sfgsch 	CHECKe(sigaction(SIGUSR2, &sa, NULL));
47*d13be5d4Sfgsch 
48*d13be5d4Sfgsch 	CHECKr(pthread_create(&tid, NULL, thr_readv, NULL));
49*d13be5d4Sfgsch 	sleep(2);
50*d13be5d4Sfgsch 
51*d13be5d4Sfgsch 	/* Should restart it. */
52*d13be5d4Sfgsch 	CHECKr(pthread_kill(tid, SIGUSR1));
53*d13be5d4Sfgsch 	sleep(1);
54*d13be5d4Sfgsch 
55*d13be5d4Sfgsch 	/* Should interrupt it. */
56*d13be5d4Sfgsch 	CHECKr(pthread_kill(tid, SIGUSR2));
57*d13be5d4Sfgsch 	sleep(1);
58*d13be5d4Sfgsch 
59*d13be5d4Sfgsch 	CHECKr(pthread_join(tid, &retval));
60*d13be5d4Sfgsch 	ASSERT(retval == (void *)EINTR);
61*d13be5d4Sfgsch 	ASSERT(hits == 2);
62*d13be5d4Sfgsch 	SUCCEED;
63*d13be5d4Sfgsch }
64