#include /* ent.h undefs these constants and config.h is #pragma once. */ #if defined(ENT_GETRANDOM) #define _ENT_GETRANDOM #define _GNU_SOURCE #endif #if defined(ENT_URANDOM) #define _ENT_URANDOM #endif #include #if defined(_ENT_GETRANDOM) || defined(_ENT_URANDOM) #include #include #include #if defined(_ENT_GETRANDOM) #include #elif defined(_ENT_URANDOM) #include #include #include #endif int ent_getentropy(void* buf, size_t len) { char *cuf = buf; int ret; #if defined(_ENT_URANDOM) int fd; #endif assert(len <= 256); if (!len) return 0; #if defined(_ENT_URANDOM) if ((fd = open("/dev/urandom", O_RDONLY)) < 0) return -1; #endif while (len && #if defined(_ENT_GETRANDOM) (ret = syscall(SYS_getrandom, cuf, len, 0)) != 0 #elif defined(_ENT_URANDOM) (ret = read(fd, cuf, len)) != 0 #endif ) { if (ret < 0) { if (errno == EINTR) continue; break; } len -= ret; cuf += ret; } #if defined(_ENT_URANDOM) (void) close(fd); #endif if (!ret) { ret = -1; errno = EIO; } return ret < 0 ? ret : 0; } #endif /* _ENT_GETRANDOM || _ENT_URANDOM */