• Jeff Dike's avatar
    random: add async notification support to /dev/random · 9a6f70bb
    Jeff Dike authored
    Add async notification support to /dev/random.
    
    A little test case is below.  Without this patch, you get:
    
    $ ./async-random
    Drained the pool
    Found more randomness
    
    With it, you get:
    
    $ ./async-random
    Drained the pool
    SIGIO
    Found more randomness
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <signal.h>
    #include <errno.h>
    #include <fcntl.h>
    
    static void handler(int sig)
    {
            printf("SIGIO\n");
    }
    
    int main(int argc, char **argv)
    {
            int fd, n, err, flags;
    
            if(signal(SIGIO, handler) < 0){
                    perror("setting SIGIO handler");
                    exit(1);
            }
    
            fd = open("/dev/random", O_RDONLY);
            if(fd < 0){
                    perror("open");
                    exit(1);
            }
    
            flags = fcntl(fd, F_GETFL);
            if (flags < 0){
                    perror("getting flags");
                    exit(1);
            }
    
            flags |= O_NONBLOCK;
            if (fcntl(fd, F_SETFL, flags) < 0){
                    perror("setting flags");
                    exit(1);
            }
    
            while((err = read(fd, &n, sizeof(n))) > 0) ;
    
            if(err == 0){
                    printf("random returned 0\n");
                    exit(1);
            }
            else if(errno != EAGAIN){
                    perror("read");
                    exit(1);
            }
    
            flags |= O_ASYNC;
            if (fcntl(fd, F_SETFL, flags) < 0){
                    perror("setting flags");
                    exit(1);
            }
    
            if (fcntl(fd, F_SETOWN, getpid()) < 0) {
                    perror("Setting SIGIO");
                    exit(1);
            }
    
            printf("Drained the pool\n");
            read(fd, &n, sizeof(n));
            printf("Found more randomness\n");
    
            return(0);
    }
    Signed-off-by: default avatarJeff Dike <jdike@linux.intel.com>
    Signed-off-by: default avatarMatt Mackall <mpm@selenic.com>
    Cc: Theodore Ts'o <tytso@mit.edu>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    9a6f70bb
random.c 48.6 KB