xref: /openbsd-src/regress/sys/kern/kqueue/kqueue-random.c (revision f2da64fbbbf1b03f09f390ab01267c93dfd77c4c)
1 /*	$OpenBSD: kqueue-random.c,v 1.9 2015/08/13 10:12:04 uebayasi Exp $	*/
2 /*	Written by Michael Shalayeff, 2002, Public Domain	*/
3 
4 #include <stdlib.h>
5 #include <stdio.h>
6 #include <err.h>
7 #include <unistd.h>
8 #include <string.h>
9 
10 #include <sys/param.h>
11 #include <sys/event.h>
12 #include <sys/wait.h>
13 #include <sys/fcntl.h>
14 
15 #include <dev/rndvar.h>
16 
17 int do_random(void);
18 
19 int
20 do_random(void)
21 {
22 	int n, fd, kq;
23 	struct timespec ts;
24 	struct kevent ev;
25 	u_int32_t buf[BUFSIZ];
26 
27 	if ((fd = open("/dev/random", O_RDONLY)) < 0) {
28 		warn("open: /dev/random");
29 		return (1);
30 	}
31 	if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) {
32 		warn("fcntl");
33 		close(fd);
34 		return (1);
35 	}
36 
37 	if ((kq = kqueue()) < 0) {
38 		warn("kqueue");
39 		close(fd);
40 		return (1);
41 	}
42 
43 	memset(&ev, 0, sizeof(ev));
44 	ev.ident = fd;
45 	ev.filter = EVFILT_READ;
46 	ev.flags = EV_ADD | EV_ENABLE;
47 	n = kevent(kq, &ev, 1, NULL, 0, NULL);
48 	if (n == -1) {
49 		warn("kevent");
50 		close(kq);
51 		close(fd);
52 		return (1);
53 	}
54 
55 	ts.tv_sec = 0;
56 	ts.tv_nsec = 0;
57 	if (kevent(kq, NULL, 0, &ev, 1, &ts) < 0) {
58 		warn("kevent2");
59 		return (1);
60 	}
61 
62 	n = MIN((ev.data + 7) / 8, sizeof(buf));
63 	if (read(fd, buf, n) < 1) {
64 		warnx("read %d", n);
65 		return (1);
66 	}
67 
68 	close(kq);
69 	close(fd);
70 
71 	return (0);
72 }
73