1 /*	$OpenBSD: kqueue-random.c,v 1.13 2021/12/14 06:26:15 anton Exp $	*/
2 /*	Written by Michael Shalayeff, 2002, Public Domain	*/
3 
4 #include <sys/types.h>
5 #include <sys/event.h>
6 #include <sys/time.h>
7 
8 #include <err.h>
9 #include <fcntl.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <unistd.h>
14 
15 #include "main.h"
16 
17 #define MINIMUM(a, b)    (((a) < (b)) ? (a) : (b))
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 	ASS((fd = open("/dev/random", O_RDONLY)) >= 0,
28 	    warn("open: /dev/random"));
29 	ASS(fcntl(fd, F_SETFL, O_NONBLOCK) == 0,
30 	    warn("fcntl"));
31 
32 	ASS((kq = kqueue()) >= 0,
33 	    warn("kqueue"));
34 
35 	memset(&ev, 0, sizeof(ev));
36 	ev.ident = fd;
37 	ev.filter = EVFILT_READ;
38 	ev.flags = EV_ADD | EV_ENABLE;
39 	n = kevent(kq, &ev, 1, NULL, 0, NULL);
40 	ASSX(n != -1);
41 
42 	ts.tv_sec = 0;
43 	ts.tv_nsec = 0;
44 	n = kevent(kq, NULL, 0, &ev, 1, &ts);
45 	ASSX(n >= 0);
46 
47 	n = MINIMUM((ev.data + 7) / 8, sizeof(buf));
48 	ASSX(read(fd, buf, n) > 0);
49 
50 	close(kq);
51 	close(fd);
52 
53 	return (0);
54 }
55