module System.Random.URandom (urandom) where import Foreign.C.Types (CUChar, CInt) import Foreign.Ptr (Ptr, castPtr) import System.IO.Error (ioError, userError) import qualified Data.ByteString as S import qualified Data.ByteString.Internal as SI -- XXX why should we specify unsafe if the function is perfectly safe? foreign import ccall unsafe "HsUrandom.h hsUrandom" c_urandom :: Ptr CUChar -> CInt -> IO CInt urandom :: Int -> IO S.ByteString urandom 0 = return S.empty urandom n = SI.create n pseudoBytes where pseudoBytes p = do ret <- c_urandom (castPtr p) (fromIntegral n) if ret == -1 -- TODO: we should use platform specific error routine, to -- supply more informations about the occurred error. then ioError $ userError "urandom failed" else return ()