Unit tests included.
LTP tests pass. Here is an LTP emulation layer sufficient to run these tests on FreeBSD:
```
$ cat lapi/getrandom.h
#include <sys/random.h>
$ cat lapi/syscalls.h
#include <sys/syscall.h>
$ cat tst_test.h
#include <sys/param.h>
#include <err.h>
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
static long TEST_RETURN;
static int TEST_ERRNO;
static inline void
TEST(long a)
{
TEST_RETURN = a;
TEST_ERRNO = errno;
}
#define tst_syscall syscall
#define __NR_getrandom SYS_getrandom
#define TPASS 1
#define TFAIL 0
#define TPASSMASK 1
#define TTERRNO 2
static size_t tot_pass, tot_fail;
static inline void
tst_res(int flags, const char *fmt, ...)
{
va_list ap;
if ((flags & TPASSMASK) == TPASS) {
printf("PASS ");
tot_pass++;
} else {
printf("FAIL ");
tot_fail++;
}
va_start(ap, fmt);
vprintf(fmt, ap);
va_end(ap);
if (flags & TTERRNO)
printf(": %d (%s)", errno, strerror(errno));
puts("\n");
}
#define ARRAY_SIZE nitems
static inline void
SAFE_GETRLIMIT(int res, struct rlimit *out)
{
int ret;
ret = getrlimit(res, out);
if (ret != 0)
err(1, "getrlimit");
}
static inline void
SAFE_SETRLIMIT(int res, const struct rlimit *in)
{
int ret;
ret = setrlimit(res, in);
if (ret != 0)
err(1, "setrlimit");
}
struct tst_test {
size_t tcnt;
void (*test)(unsigned);
void (*test_all)(void);
};
static struct tst_test test;
int
main(int argc __unused, char **argv __unused)
{
size_t i;
for (i = 0; i < test.tcnt; i++)
test.test(i);
if (test.test_all != NULL)
test.test_all();
printf("Pass: %zu/%zu\n", tot_pass, tot_pass + tot_fail);
return (tot_fail != 0);
}
```
Under this emulation, all LTP `getrandom(2)` tests pass. (Compile with, e.g., `gcc6 -Wall -Wextra -O2 -g -I. getrandom04.c`.)
Truss:
```
$ LD_LIBRARY_PATH=$(cd lib/libsysdecode ; make -V .OBJDIR) $(cd usr.bin/truss ; make -V .OBJDIR)/truss.full $(cd tests/sys/kern ; make -V .OBJDIR)/sys_getrandom.full getrandom_randomness
...
getrandom("@\M^Pb\M-"\M^S\M-d\^Br\^A\^A1$"...,4096,0) = 4096 (0x1000)
mmap(0x0,266240,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANON,-1,0x0) = 34367328256 (0x80073d000)
getrandom("\aJql\M-Ej\M-S\M^]\M-+\f^\M-e\^Y"...,4096,1) = 4096 (0x1000)
getrandom("\M-_\M^\_\M-K\M-I\M^I.l\M-S\M^]"...,4096,2) = 4096 (0x1000)
getrandom("G\M-1Y\M^N\M^_3Y[4\M^I\M^Z\^S"...,4096,3) = 4096 (0x1000)
passed
writev(1,[{"passed",6},{"\n",1}],2) = 7 (0x7)
...
```