summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNils Maier <maierman@web.de>2015-03-04 19:42:49 +0100
committerNils Maier <maierman@web.de>2015-03-18 01:46:26 +0100
commitc248d456d194532098747055dd75a28118d77521 (patch)
treead535da020c056079fd99b819c6961b34bd65aaf
parentee63dff2258ff013e6905cb08d3d5e9ad53e3696 (diff)
Comment getrandom code a bit
-rw-r--r--src/SimpleRandomizer.cc1
-rw-r--r--src/getrandom_linux.c20
2 files changed, 20 insertions, 1 deletions
diff --git a/src/SimpleRandomizer.cc b/src/SimpleRandomizer.cc
index 72b647cf..6170bee6 100644
--- a/src/SimpleRandomizer.cc
+++ b/src/SimpleRandomizer.cc
@@ -109,6 +109,7 @@ void SimpleRandomizer::getRandomBytes(unsigned char* buf, size_t len)
if (rv < -1) {
A2_LOG_ERROR(fmt("Failed to produce randomness: %d", errno));
}
+ // getrandom is not supposed to fail, ever, so, we want to assert here.
assert(rv >= 0 && (size_t)rv == len);
return;
}
diff --git a/src/getrandom_linux.c b/src/getrandom_linux.c
index cbf4c32a..691c5d5f 100644
--- a/src/getrandom_linux.c
+++ b/src/getrandom_linux.c
@@ -48,17 +48,29 @@
int getrandom_linux(void *buf, size_t buflen) {
int rv = 0;
uint8_t* p = buf;
+
+ /* Loop while we did not fully retrieve what the user asked for.
+ * This may happen in particular when a call was EINTRupted.
+ */
while (buflen) {
int read;
#ifdef HAVE_GETRANDOM
+ /* libc already has support */
read = getrandom(p, buflen, 0);
#else // HAVE_GETRANDOM
+ /* libc has no support, make the syscall ourselves */
read = syscall(SYS_getrandom, p, buflen, 0);
- /* Some libc impl. might mess this up */
+ /* Some libc impl. might mess -ERESTART up */
if (read == -EINTR || read == -ERESTART) {
+ /* ERESTART, like EINTR, should restart the call, later, so handle both
+ * the same way.
+ */
errno = EINTR;
read = -1;
}
+ /* Some other non-interrupted error happened, put error code into errno and
+ * switch read to -1 (return value).
+ */
if (read < -1) {
errno = -read;
read = -1;
@@ -66,13 +78,19 @@ int getrandom_linux(void *buf, size_t buflen) {
#endif // HAVE_GETRANDOM
if (read < 0) {
if (errno == EINTR) {
+ /* Restart call */
continue;
}
+ /* Call failed, return -1, errno should be set up correctly at this
+ * point.
+ */
return -1;
}
+ /* We got some more randomness */
p += read;
rv += read;
buflen -= read;
}
+
return rv;
}