[Haskell-cafe] Re: DevRandom
Yitzchak Gale
gale at sefer.org
Tue Jan 30 13:10:21 EST 2007
It's short, so I'll post it here.
Any comments?
Thanks,
-Yitz
module DevRandom where
import System.IO
import System.IO.Error
import Foreign.Marshal.Alloc
import Foreign.Storable
import Foreign.Ptr
data BlockingMode = Blocking | NonBlocking
deriving (Eq, Show)
-- Read data from the system random device.
-- Return Nothing if there is currently not
-- enough entropy in the system random device.
devRandom :: Storable a => IO (Maybe a)
devRandom = readDev "/dev/random" NonBlocking
-- Read data from the system random device.
-- If necessary, wait until there is
-- enough entropy in the system random device.
devRandomWait :: Storable a => IO a
devRandomWait = readDev dev Blocking >>= maybe (devRandomError dev) return
where
dev = "/dev/random"
-- Read data from the system random device.
-- If there is currently not enough entropy
-- in the system random device, use a lower
-- quality source of randomness instead.
devURandom :: Storable a => IO a
devURandom = readDev dev NonBlocking >>= maybe (devRandomError dev) return
where
dev = "/dev/urandom"
readDev :: Storable a => FilePath -> BlockingMode -> IO (Maybe a)
readDev dev mode = do
h <- openFile dev ReadMode
hSetBuffering h NoBuffering
alloca $ getMaybe h undefined
where
getMaybe :: Storable a => Handle -> a -> Ptr a -> IO (Maybe a)
getMaybe h undef ptr = do
let size = sizeOf undef
n <- case mode of
Blocking -> hGetBuf h ptr size
NonBlocking -> hGetBufNonBlocking h ptr size
if n < size
then return Nothing
else peek ptr >>= return . Just
devRandomError :: FilePath -> IO a
devRandomError p = ioError $ mkIOError illegalOperationErrorType
"Unable to read from the system random device" Nothing (Just p)
More information about the Haskell-Cafe
mailing list