00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef _PASSENGER_RANDOM_GENERATOR_H_
00026 #define _PASSENGER_RANDOM_GENERATOR_H_
00027
00028 #include <string>
00029
00030 #include <boost/noncopyable.hpp>
00031 #include <boost/shared_ptr.hpp>
00032 #include <oxt/system_calls.hpp>
00033
00034 #include "StaticString.h"
00035 #include "Utils.h"
00036 #include "Exceptions.h"
00037
00038
00039
00040
00041
00042 namespace Passenger {
00043
00044 using namespace std;
00045 using namespace boost;
00046 using namespace oxt;
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 class RandomGenerator: public boost::noncopyable {
00061 private:
00062 FILE *handle;
00063
00064 public:
00065 RandomGenerator(bool open = true) {
00066 handle = NULL;
00067 if (open) {
00068 reopen();
00069 }
00070 }
00071
00072 ~RandomGenerator() {
00073 this_thread::disable_syscall_interruption dsi;
00074 close();
00075 }
00076
00077 void reopen() {
00078 close();
00079 handle = syscalls::fopen("/dev/urandom", "r");
00080 if (handle == NULL) {
00081 throw FileSystemException("Cannot open /dev/urandom",
00082 errno, "/dev/urandom");
00083 }
00084 }
00085
00086 void close() {
00087 if (handle != NULL) {
00088 syscalls::fclose(handle);
00089 handle = NULL;
00090 }
00091 }
00092
00093 StaticString generateBytes(void *buf, unsigned int size) {
00094 size_t ret = syscalls::fread(buf, 1, size, handle);
00095 if (ret != size) {
00096 throw IOException("Cannot read sufficient data from /dev/urandom");
00097 }
00098 return StaticString((const char *) buf, size);
00099 }
00100
00101 string generateByteString(unsigned int size) {
00102 char buf[size];
00103 generateBytes(buf, size);
00104 return string(buf, size);
00105 }
00106
00107 string generateHexString(unsigned int size) {
00108 char buf[size];
00109 generateBytes(buf, size);
00110 return toHex(StaticString(buf, size));
00111 }
00112
00113 int generateInt() {
00114 int ret;
00115 generateBytes(&ret, sizeof(ret));
00116 return ret;
00117 }
00118
00119 unsigned int generateUint() {
00120 return (unsigned int) generateInt();
00121 }
00122 };
00123
00124 typedef shared_ptr<RandomGenerator> RandomGeneratorPtr;
00125
00126 }
00127
00128 #endif