// version 20230919
// public domain
// djb

// 20230919: fixing main getentropy() call; tnx jan mojzis

#include <unistd.h>

// automatic-alternatives 2
#ifdef getentropy_wrapper_2

#include "getentropy_wrapper.h"

int getentropy_wrapper_ready(void)
{
  return 0;
}

void getentropy_wrapper(void *x,long long xbytes)
{
  for (;;) pause();
}

#else

#include <errno.h>
#include <signal.h>

#include "getentropy_wrapper.h"

static int getentropy_wrapper_ready_core(void)
{
  char ch;
  int r;

  for (;;) {
    errno = 0;
    r = getentropy(&ch,1);
    if (r == 0) return 1;
    if (r == -1 && errno == ENOSYS) return 0;
    if (r == -1 && errno == EPERM) return 0;
    if (r == -1 && errno == EIO) return 0;
  }
}

int getentropy_wrapper_ready(void)
{
  struct sigaction old_sigsys;
  int result;

  sigaction(SIGSYS,0,&old_sigsys);
  signal(SIGSYS,SIG_IGN);
  result = getentropy_wrapper_ready_core();
  sigaction(SIGSYS,&old_sigsys,0);
  return result;
}

void getentropy_wrapper(void *x,long long xbytes)
{
  while (xbytes > 0) {
    // getentropy fails for >256 bytes

    int todo = 256;
    if (xbytes < 256) todo = xbytes;

    if (getentropy(x,todo) != 0) {
      sleep(1);
      continue;
    }

    x += todo;
    xbytes -= todo;
  }
}

#endif
