Line data Source code
1 : /** \file randomSeed.hpp
2 : * \author Jared R. Males
3 : * \brief Defines a random number seed generator
4 : * \ingroup gen_math_files
5 : *
6 : */
7 :
8 : //***********************************************************************//
9 : // Copyright 2015, 2016, 2017, 2020 Jared R. Males (jaredmales@gmail.com)
10 : //
11 : // This file is part of mxlib.
12 : //
13 : // mxlib is free software: you can redistribute it and/or modify
14 : // it under the terms of the GNU General Public License as published by
15 : // the Free Software Foundation, either version 3 of the License, or
16 : // (at your option) any later version.
17 : //
18 : // mxlib is distributed in the hope that it will be useful,
19 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 : // GNU General Public License for more details.
22 : //
23 : // You should have received a copy of the GNU General Public License
24 : // along with mxlib. If not, see <http://www.gnu.org/licenses/>.
25 : //***********************************************************************//
26 :
27 : #ifndef mx_math_randomSeed_hpp
28 : #define mx_math_randomSeed_hpp
29 :
30 : #include <unistd.h>
31 : #include <fcntl.h>
32 :
33 : #include "../mxlib.hpp"
34 :
35 : namespace mx
36 : {
37 : namespace math
38 : {
39 :
40 : /// Get a value to use as a random seed
41 : /** On Linux systems, uses /dev/urandom to populate the value with sizeof(intT) bytes.
42 : * Otherwise, uses time(0) to get time since the epoch.
43 : *
44 : * \returns 0 on success.
45 : * \returns -1 on error.
46 : *
47 : * \tparam intT is the integer type of seeval.
48 : *
49 : * \ingroup random
50 : *
51 : */
52 : template <typename intT>
53 9 : int randomSeed( intT &seedval /**< [out] will be populated with the seed.*/ )
54 : {
55 : #ifdef __linux__
56 :
57 : int fd;
58 :
59 9 : errno = 0;
60 9 : fd = open( "/dev/urandom", O_RDONLY );
61 :
62 9 : if( fd < 0 )
63 : {
64 0 : internal::mxlib_error_report(errno2error_t(errno), "error opening /dev/urandom" );
65 :
66 0 : return -1;
67 : }
68 :
69 9 : seedval = 0;
70 :
71 9 : errno = 0;
72 9 : int rv = ::read( fd, &seedval, sizeof( intT ) );
73 :
74 9 : if( rv < 0 )
75 : {
76 0 : internal::mxlib_error_report(errno2error_t(errno), "Error on read from /dev/urandom." );
77 0 : close( fd );
78 0 : return -1;
79 : }
80 :
81 9 : close( fd );
82 :
83 9 : int sz = sizeof( intT );
84 :
85 9 : if( rv < sz )
86 : {
87 0 : internal::mxlib_error_report(error_t::filererr, "Read from /dev/urandom did not return enough bytes" );
88 :
89 0 : return -1;
90 : }
91 :
92 9 : return 0;
93 :
94 : #endif //__linux__
95 :
96 : seedval = time( 0 );
97 :
98 : return 0;
99 : }
100 :
101 : } // namespace math
102 : } // namespace mx
103 :
104 : #endif // mx_math_randomSeed_hpp
|