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