|
k-dot-p 0.1
|
00001 /* 00002 *randomness.h++ platform-specific random number generator stuff. Should mostly be used for seeding 00003 the GSL random number generator. 00004 00005 Copyright (C) 2010 Joseph Pingenot 00006 00007 This program is free software: you can redistribute it and/or modify 00008 it under the terms of the GNU Affero General Public License as published by 00009 the Free Software Foundation, either version 3 of the License, or 00010 (at your option) any later version. 00011 00012 This program is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU Affero General Public License for more details. 00016 00017 You should have received a copy of the GNU Affero General Public License 00018 along with this program. If not, see <http://www.gnu.org/licenses/>. 00019 00020 */ 00021 00022 #include <stdio.h> 00023 #include <glib.h> 00024 #include <sys/types.h> 00025 #include <sys/stat.h> 00026 #include <fcntl.h> 00027 #include <errno.h> 00028 #include <string.h> 00029 #include <unistd.h> 00030 #include <libmodelxx/randomness.h++> 00031 #include <config.h> 00032 00033 #define RANDOMNESS_GERROR_DOMAIN 15 00034 00035 namespace kdotp { 00036 namespace libmodelxx { 00037 namespace randomness { 00038 00039 00040 unsigned long int get_random_unsigned_long_int(GError **err) { 00041 #if HOST_OS != LINUX 00042 #error This currently only supports Linux. 00043 #else 00044 long unsigned rnum; 00045 int fd = open("/dev/random", O_RDONLY); 00046 if(fd == -1) { 00047 *err = g_error_new(RANDOMNESS_GERROR_DOMAIN, 1, "libmodelxx::randomness::randomness.c++::get_random_unsinged_long_int: Error while opening /proc/random: %d (%s)\n", errno, strerror(errno)); 00048 return 0; 00049 } 00050 ssize_t len = read(fd, &rnum, sizeof(unsigned long int)); 00051 if(len != sizeof(unsigned long int)) { 00052 *err = g_error_new(RANDOMNESS_GERROR_DOMAIN, 1, "libmodelxx::randomness::randomness.c++::get_random_unsinged_long_int: Failed to read an entire unsigned long int: %d (%s)\n", errno, strerror(errno)); 00053 close(fd); 00054 return 0; 00055 } 00056 close(fd); 00057 fprintf(stderr, "get_urandom_unsinged_long_int: returning %lu\n", rnum); 00058 return rnum; 00059 #endif 00060 } 00061 00062 /**Will get from /dev/urandom if present. Otherwise, is identical to random.*/ 00063 unsigned long int get_urandom_unsigned_long_int(GError **err) { 00064 #if HOST_OS != LINUX 00065 return get_random_unsigned_long_int(err); 00066 #else 00067 long unsigned rnum; 00068 int fd = open("/dev/urandom", O_RDONLY); 00069 if(fd == -1) { 00070 *err = g_error_new(RANDOMNESS_GERROR_DOMAIN, 1, "libmodelxx::randomness::randomness.c++::get_urandom_unsinged_long_int: Error while opening /proc/urandom: %d (%s)\n", errno, strerror(errno)); 00071 return 0; 00072 } 00073 ssize_t len = read(fd, &rnum, sizeof(unsigned long int)); 00074 if(len != sizeof(unsigned long int)) { 00075 *err = g_error_new(RANDOMNESS_GERROR_DOMAIN, 1, "libmodelxx::randomness::randomness.c++::get_urandom_unsinged_long_int: Failed to read an entire unsigned long int: %d (%s)\n", errno, strerror(errno)); 00076 close(fd); 00077 return 0; 00078 } 00079 close(fd); 00080 fprintf(stderr, "get_urandom_unsinged_long_int: returning %lu\n", rnum); 00081 return rnum; 00082 #endif 00083 } 00084 00085 00086 } 00087 } 00088 }