A few more ENGINE strings that need shortening.
[oweals/openssl.git] / crypto / rand / rand_unix.c
index d2fdb35b56fea84cd3a99e01d7d1ce7511cf6553..c4838b6b2e67918f5b3ad8819598479f3c388d6f 100644 (file)
 #include <sys/types.h>
 #include <sys/time.h>
 #include <sys/times.h>
+#include <sys/stat.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <time.h>
@@ -152,9 +153,10 @@ int RAND_poll(void)
        int n = 0;
 #endif
 #ifdef DEVRANDOM
-       static const char *randomfiles[] = { DEVRANDOM, NULL };
-       const char **randomfile = NULL;
+       static const char *randomfiles[] = { DEVRANDOM };
+       struct stat randomstats[sizeof(randomfiles)/sizeof(randomfiles[0])];
        int fd;
+       unsigned int i;
 #endif
 #ifdef DEVRANDOM_EGD
        static const char *egdsockets[] = { DEVRANDOM_EGD, NULL };
@@ -162,29 +164,57 @@ int RAND_poll(void)
 #endif
 
 #ifdef DEVRANDOM
+       memset(randomstats,0,sizeof(randomstats));
        /* Use a random entropy pool device. Linux, FreeBSD and OpenBSD
         * have this. Use /dev/urandom if you can as /dev/random may block
         * if it runs out of random entries.  */
 
-       for (randomfile = randomfiles; *randomfile && n < ENTROPY_NEEDED; randomfile++)
+       for (i = 0; (i < sizeof(randomfiles)/sizeof(randomfiles[0])) &&
+                       (n < ENTROPY_NEEDED); i++)
                {
-               if ((fd = open(*randomfile, O_RDONLY|O_NONBLOCK
+               if ((fd = open(randomfiles[i], O_RDONLY
+#ifdef O_NONBLOCK
+                       |O_NONBLOCK
+#endif
+#ifdef O_BINARY
+                       |O_BINARY
+#endif
 #ifdef O_NOCTTY /* If it happens to be a TTY (god forbid), do not make it
                   our controlling tty */
                        |O_NOCTTY
-#endif
-#ifdef O_NOFOLLOW /* Fail if the file is a symbolic link */
-                       |O_NOFOLLOW
 #endif
                        )) >= 0)
                        {
                        struct timeval t = { 0, 10*1000 }; /* Spend 10ms on
                                                              each file. */
                        int r;
+                       unsigned int j;
                        fd_set fset;
+                       struct stat *st=&randomstats[i];
+
+                       /* Avoid using same input... Used to be O_NOFOLLOW
+                        * above, but it's not universally appropriate... */
+                       if (fstat(fd,st) != 0)  { close(fd); continue; }
+                       for (j=0;j<i;j++)
+                               {
+                               if (randomstats[j].st_ino==st->st_ino &&
+                                   randomstats[j].st_dev==st->st_dev)
+                                       break;
+                               }
+                       if (j<i)                { close(fd); continue; }
 
                        do
                                {
+#if defined(OPENSSL_SYS_BEOS_R5)
+                               /* select() is broken in BeOS R5, so we simply 
+                                *  try to read something and snooze if we couldn't: */
+                               r=read(fd,(unsigned char *)tmpbuf+n,
+                                      ENTROPY_NEEDED-n);
+                               if (r > 0)
+                                       n += r;
+                               else if (r == 0)
+                                       snooze(t.tv_usec);
+#else
                                FD_ZERO(&fset);
                                FD_SET(fd, &fset);
                                r = -1;
@@ -198,7 +228,7 @@ int RAND_poll(void)
                                        if (r > 0)
                                                n += r;
                                        }
-
+#endif
                                /* Some Unixen will update t, some
                                   won't.  For those who won't, give
                                   up here, otherwise, we will do
@@ -247,6 +277,14 @@ int RAND_poll(void)
        l=time(NULL);
        RAND_add(&l,sizeof(l),0.0);
 
+#if defined(OPENSSL_SYS_BEOS)
+       {
+       system_info sysInfo;
+       get_system_info(&sysInfo);
+       RAND_add(&sysInfo,sizeof(sysInfo),0);
+       }
+#endif
+
 #if defined(DEVRANDOM) || defined(DEVRANDOM_EGD)
        return 1;
 #else