1 /*	$OpenBSD: kqueue-random.c,v 1.8 2014/11/22 18:58:33 deraadt 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 
9 #include <sys/param.h>
10 #include <sys/event.h>
11 #include <sys/wait.h>
12 #include <sys/fcntl.h>
13 
14 #include <dev/rndvar.h>
15 
16 int do_random(void);
17 
18 int
19 do_random(void)
20 {
21 	int n, fd, kq;
22 	struct timespec ts;
23 	struct kevent ev;
24 	u_int32_t buf[BUFSIZ];
25 
26 	if ((fd = open("/dev/random", O_RDONLY)) < 0) {
27 		warn("open: /dev/random");
28 		return (1);
29 	}
30 	if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) {
31 		warn("fcntl");
32 		close(fd);
33 		return (1);
34 	}
35 
36 	if ((kq = kqueue()) < 0) {
37 		warn("kqueue");
38 		close(fd);
39 		return (1);
40 	}
41 
42 	ev.ident = fd;
43 	ev.filter = EVFILT_READ;
44 	ev.flags = EV_ADD | EV_ENABLE;
45 	n = kevent(kq, &ev, 1, NULL, 0, NULL);
46 	if (n == -1) {
47 		warn("kevent");
48 		close(kq);
49 		close(fd);
50 		return (1);
51 	}
52 
53 	ts.tv_sec = 0;
54 	ts.tv_nsec = 0;
55 	if (kevent(kq, NULL, 0, &ev, 1, &ts) < 0) {
56 		warn("kevent2");
57 		return (1);
58 	}
59 
60 	n = MIN((ev.data + 7) / 8, sizeof(buf));
61 	if (read(fd, buf, n) < 1) {
62 		warnx("read %d", n);
63 		return (1);
64 	}
65 
66 	close(kq);
67 	close(fd);
68 
69 	return (0);
70 }
71