summaryrefslogtreecommitdiff
path: root/random
diff options
context:
space:
mode:
authorNIIBE Yutaka <gniibe@fsij.org>2021-10-05 15:28:28 +0900
committerNIIBE Yutaka <gniibe@fsij.org>2021-10-05 15:28:28 +0900
commit7da42a8e8cc587ced46dffefc8448c8a286b1ca0 (patch)
tree0ed62fe01dabbc63dca914dde414ca2b297ce4d7 /random
parent94c9234367152af35f376560d470927166692ff7 (diff)
downloadlibgcrypt-7da42a8e8cc587ced46dffefc8448c8a286b1ca0.tar.gz
random: Use poll instead of select.
* random/rndlinux.c (open_device): Use poll. (_gcry_rndlinux_gather_random): Use poll. -- Merging a patch for Fedora/RedHat for _gcry_rndlinux_gather_random. Also change open_device for completeness. Use of sleep(3) would be OK here, but it may use SIGALRM on some systems, which is not good as a library. GnuPG-bug-id: 5637 Co-authored-by: Tomáš Mráz <tm@t8m.info> Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
Diffstat (limited to 'random')
-rw-r--r--random/rndlinux.c66
1 files changed, 23 insertions, 43 deletions
diff --git a/random/rndlinux.c b/random/rndlinux.c
index c20c5d4c..0cafd859 100644
--- a/random/rndlinux.c
+++ b/random/rndlinux.c
@@ -23,15 +23,11 @@
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
-#include <sys/time.h>
#include <sys/types.h>
-#include <sys/stat.h>
-#ifdef HAVE_GETTIMEOFDAY
-# include <sys/times.h>
-#endif
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
+#include <poll.h>
#if defined(__APPLE__) && defined(__MACH__)
#include <Availability.h>
#ifdef __MAC_10_11
@@ -88,12 +84,8 @@ open_device (const char *name, int retry)
fd = open (name, O_RDONLY);
if (fd == -1 && retry)
{
- struct timeval tv;
-
- tv.tv_sec = 5;
- tv.tv_usec = 0;
- _gcry_random_progress ("wait_dev_random", 'X', 0, (int)tv.tv_sec);
- select (0, NULL, NULL, NULL, &tv);
+ _gcry_random_progress ("wait_dev_random", 'X', 0, 5);
+ poll (NULL, 0, 5000);
goto again;
}
if (fd == -1)
@@ -249,9 +241,8 @@ _gcry_rndlinux_gather_random (void (*add)(const void*, size_t,
return with something we will actually use 100ms. */
while (length)
{
- fd_set rfds;
- struct timeval tv;
int rc;
+ struct pollfd pfd;
/* If we have a modern operating system, we first try to use the new
* getentropy function. That call guarantees that the kernel's
@@ -299,7 +290,7 @@ _gcry_rndlinux_gather_random (void (*add)(const void*, size_t,
#endif
/* If we collected some bytes update the progress indicator. We
- do this always and not just if the select timed out because
+ do this always and not just if the poll timed out because
often just a few bytes are gathered within the timeout
period. */
if (any_need_entropy || last_so_far != (want - length) )
@@ -310,36 +301,25 @@ _gcry_rndlinux_gather_random (void (*add)(const void*, size_t,
any_need_entropy = 1;
}
- /* If the system has no limit on the number of file descriptors
- and we encounter an fd which is larger than the fd_set size,
- we don't use the select at all. The select code is only used
- to emit progress messages. A better solution would be to
- fall back to poll() if available. */
-#ifdef FD_SETSIZE
- if (fd < FD_SETSIZE)
-#endif
+ pfd.fd = fd;
+ pfd.events = POLLIN;
+
+ _gcry_pre_syscall ();
+ rc = poll (&pfd, 1, delay);
+ _gcry_post_syscall ();
+ if (!rc)
{
- FD_ZERO(&rfds);
- FD_SET(fd, &rfds);
- tv.tv_sec = delay;
- tv.tv_usec = delay? 0 : 100000;
- _gcry_pre_syscall ();
- rc = select (fd+1, &rfds, NULL, NULL, &tv);
- _gcry_post_syscall ();
- if (!rc)
- {
- any_need_entropy = 1;
- delay = 3; /* Use 3 seconds henceforth. */
- continue;
- }
- else if( rc == -1 )
- {
- log_error ("select() error: %s\n", strerror(errno));
- if (!delay)
- delay = 1; /* Use 1 second if we encounter an error before
- we have ever blocked. */
- continue;
- }
+ any_need_entropy = 1;
+ delay = 3000; /* Use 3 seconds henceforth. */
+ continue;
+ }
+ else if( rc == -1 )
+ {
+ log_error ("poll() error: %s\n", strerror (errno));
+ if (!delay)
+ delay = 1000; /* Use 1 second if we encounter an error before
+ we have ever blocked. */
+ continue;
}
do