<commit_before>/*
* /dev/random EntropySource
* (C) 1999-2009 <NAME>
*
* Distributed under the terms of the Botan license
*/

#include <botan/es_dev.h>

#include <sys/types.h>
#include <sys/select.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>

namespace Botan {

/**
Close the device, if open
*/
void Device_EntropySource::Device_Reader::close()
   {
   if(fd > 0) { ::close(fd); fd = -1; }
   }

/**
Read bytes from a device file
*/
u32bit Device_EntropySource::Device_Reader::get(byte out[], u32bit length,
                                                u32bit ms_wait_time)
   {
   if(fd < 0)
      return 0;

   if(fd >= FD_SETSIZE)
      return 0;

   fd_set read_set;
   FD_ZERO(&read_set);
   FD_SET(fd, &read_set);

   struct ::timeval timeout;
   timeout.tv_sec = 0;
   timeout.tv_usec = ms_wait_time * 1000;

   if(::select(fd + 1, &read_set, 0, 0, &timeout) < 0)
      return 0;

   if(!(FD_ISSET(fd, &read_set)))
      return 0;

   const ssize_t got = ::read(fd, out, length);
   if(got <= 0)
      return 0;

   return static_cast<u32bit>(got);
   }

/**
Attempt to open a device
*/
Device_EntropySource::Device_Reader::fd_type
Device_EntropySource::Device_Reader::open(const std::string& pathname)
   {
#ifndef O_NONBLOCK<commit_msg>Fix a subtle bug in the /dev/*random reader. The maximum ms wait time was set to 1000 ms (scaling based on amount of data requested). At 1000 ms exactly, we would form a timeval of 0 seconds and 1000000 usecs (ie, 1 second). Linux was fine with this, but FreeBSD 7.0's select was returning EINVAL.<commit_after>/*
* /dev/random EntropySource
* (C) 1999-2009 <NAME>
*
* Distributed under the terms of the Botan license
*/

#include <botan/es_dev.h>

#include <sys/types.h>
#include <sys/select.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>

namespace Botan {

/**
Close the device, if open
*/
void Device_EntropySource::Device_Reader::close()
   {
   if(fd > 0) { ::close(fd); fd = -1; }
   }

/**
Read bytes from a device file
*/
u32bit Device_EntropySource::Device_Reader::get(byte out[], u32bit length,
                                                u32bit ms_wait_time)
   {
   if(fd < 0)
      return 0;

   if(fd >= FD_SETSIZE)
      return 0;

   fd_set read_set;
   FD_ZERO(&read_set);
   FD_SET(fd, &read_set);

   struct ::timeval timeout;

   timeout.tv_sec = (ms_wait_time / 1000);
   timeout.tv_usec = (ms_wait_time % 1000) * 1000;

   if(::select(fd + 1, &read_set, 0, 0, &timeout) < 0)
      return 0;

   if(!(FD_ISSET(fd, &read_set)))
      return 0;

   const ssize_t got = ::read(fd, out, length);
   if(got <= 0)
      return 0;

   return static_cast<u32bit>(got);
   }

/**
Attempt to open a device
*/
Device_EntropySource::Device_Reader::fd_type
Device_EntropySource::Device_Reader::open(const std::string& pathname)
   {
#ifndef O_NONBLOCK
{'fraction_non_alphanumeric': 0.13623595505617977, 'fraction_numerical': 0.03300561797752809, 'mean_word_length': 3.128985507246377, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2627399', 'n_tokens_mistral': 1129, 'n_tokens_neox': 1024, 'n_words': 275}