Comment getrandom code a bit

This commit is contained in:
Nils Maier 2015-03-04 19:42:49 +01:00
parent ee63dff225
commit c248d456d1
2 changed files with 20 additions and 1 deletions

View File

@ -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;
}

View File

@ -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;
}