add getentropy function
authorRich Felker <dalias@aerifal.cx>
Fri, 23 Feb 2018 07:54:01 +0000 (02:54 -0500)
committerRich Felker <dalias@aerifal.cx>
Fri, 23 Feb 2018 07:57:52 +0000 (02:57 -0500)
based loosely on patch by Hauke Mehrtens; converted to wrap the public
API of the underlying getrandom function rather than direct syscalls,
so that if/when a fallback implementation of getrandom is added it
will automatically get picked up by getentropy too.

include/unistd.h
src/misc/getentropy.c [new file with mode: 0644]

index 09190af4ed5abaaeb5a5009721a83edf91952afe..c17eace9f11aa5fccd63ee6906179300c17bf385 100644 (file)
@@ -176,6 +176,7 @@ int acct(const char *);
 long syscall(long, ...);
 int execvpe(const char *, char *const [], char *const []);
 int issetugid(void);
+int getentropy(void *, size_t);
 #endif
 
 #ifdef _GNU_SOURCE
diff --git a/src/misc/getentropy.c b/src/misc/getentropy.c
new file mode 100644 (file)
index 0000000..4c61ae2
--- /dev/null
@@ -0,0 +1,31 @@
+#include <sys/random.h>
+#include <pthread.h>
+#include <errno.h>
+
+int getentropy(void *buffer, size_t len)
+{
+       int cs, ret;
+       char *pos = buffer;
+
+       if (len > 256) {
+               errno = EIO;
+               return -1;
+       }
+
+       pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+
+       while (len) {
+               ret = getrandom(pos, len, 0);
+               if (ret < 0) {
+                       if (errno == EINTR) continue;
+                       else break;
+               }
+               pos += ret;
+               len -= ret;
+               ret = 0;
+       }
+
+       pthread_setcancelstate(cs, 0);
+
+       return ret;
+}