{-# LINE 1 "System/Posix/DynamicLinker/Module.hsc" #-}{-# LANGUAGE Safe #-}------------------------------------------------------------------------------- |-- Module : System.Posix.DynamicLinker.Module-- Copyright : (c) Volker Stolz <vs@foldr.org> 2003-- License : BSD-style (see the file libraries/base/LICENSE)---- Maintainer : vs@foldr.org-- Stability : provisional-- Portability : non-portable (requires POSIX)---- DLOpen support, old API-- Derived from GModule.chs by M.Weber & M.Chakravarty which is part of c2hs-- I left the API more or less the same, mostly the flags are different.-------------------------------------------------------------------------------moduleSystem.Posix.DynamicLinker.Module(-- Usage:-- ******---- Let's assume you want to open a local shared library 'foo' (./libfoo.so)-- offering a function-- char * mogrify (char*,int)-- and invoke str = mogrify("test",1):---- type Fun = CString -> Int -> IO CString-- foreign import dynamic unsafe fun__ :: FunPtr Fun -> Fun---- withModule (Just ".") ("libfoo.so") [RTLD_NOW] $ \ mod -> do-- funptr <- moduleSymbol mod "mogrify"-- let fun = fun__ funptr-- withCString "test" $ \ str -> do-- strptr <- fun str 1-- strstr <- peekCString strptr-- ...Module,moduleOpen-- :: String -> ModuleFlags -> IO Module,moduleSymbol-- :: Source -> String -> IO (FunPtr a),moduleClose-- :: Module -> IO Bool,moduleError-- :: IO String,withModule-- :: Maybe String-- -> String-- -> [ModuleFlags ]-- -> (Module -> IO a)-- -> IO a,withModule_-- :: Maybe String-- -> String-- -> [ModuleFlags]-- -> (Module -> IO a)-- -> IO ())whereimportPreludehiding(head,tail)importSystem.Posix.DynamicLinkerimportSystem.Posix.DynamicLinker.CommonimportForeign.Ptr(Ptr,nullPtr,FunPtr)importSystem.Posix.Internals(withFilePath)unModule::Module->(Ptr())unModule(Moduleadr)=adr-- Opens a module (EXPORTED)--moduleOpen::String->[RTLDFlags]->IOModulemoduleOpenfileflags=domodPtr<-withFilePathfile$\modAddr->c_dlopenmodAddr(packRTLDFlagsflags)if(modPtr==nullPtr)thenmoduleError>>=\err->ioError(userError("dlopen: "++err))elsereturn$ModulemodPtr-- Gets a symbol pointer from a module (EXPORTED)--moduleSymbol::Module->String->IO(FunPtra)moduleSymbolfilesym=dlsym(DLHandle(unModulefile))sym-- Closes a module (EXPORTED)--moduleClose::Module->IO()moduleClosefile=dlclose(DLHandle(unModulefile))-- Gets a string describing the last module error (EXPORTED)--moduleError::IOStringmoduleError=dlerror-- Convenience function, cares for module open- & closing-- additionally returns status of `moduleClose' (EXPORTED)--withModule::MaybeString->String->[RTLDFlags]->(Module->IOa)->IOawithModulemdirfileflagsp=doletmodPath=casemdirofNothing->fileJustdir->dir++caseunsnocdirofJust(_,'/')->fileJust{}->'/':fileNothing->error"System.Posix.DynamicLinker.Module.withModule: directory should not be Just \"\", pass Nothing instead"modu<-moduleOpenmodPathflagsresult<-pmodumoduleClosemodureturnresultwithModule_::MaybeString->String->[RTLDFlags]->(Module->IOa)->IO()withModule_dirfileflagsp=withModuledirfileflagsp>>=\_->return()-- Dual to 'Data.List.uncons'.unsnoc::[a]->Maybe([a],a)unsnoc=foldrgoNothingwheregoxNothing=Just([],x)gox(Just(xs,lst))=Just(x:xs,lst)