{-# LINE 1 "libraries/base/System/Environment/ExecutablePath.hsc" #-} {-# LANGUAGE Safe #-} {-# LINE 2 "libraries/base/System/Environment/ExecutablePath.hsc" #-} {-# LANGUAGE CPP #-} ----------------------------------------------------------------------------- -- | -- Module : System.Environment.ExecutablePath -- Copyright : (c) The University of Glasgow 2001 -- License : BSD-style (see the file libraries/base/LICENSE) -- -- Maintainer : libraries@haskell.org -- Stability : provisional -- Portability : portable -- -- Function to retrieve the absolute filepath of the current executable. -- -- @since 4.6.0.0 ----------------------------------------------------------------------------- module System.Environment.ExecutablePath ( getExecutablePath ) where -- The imports are purposely kept completely disjoint to prevent edits -- to one OS implementation from breaking another. {-# LINE 25 "libraries/base/System/Environment/ExecutablePath.hsc" #-} import Data.Word import Foreign.C import Foreign.Marshal.Alloc import Foreign.Ptr import Foreign.Storable import System.Posix.Internals {-# LINE 48 "libraries/base/System/Environment/ExecutablePath.hsc" #-} -- The exported function is defined outside any if-guard to make sure -- every OS implements it with the same type. -- | Returns the absolute pathname of the current executable. -- -- Note that for scripts and interactive sessions, this is the path to -- the interpreter (e.g. ghci.) -- -- @since 4.6.0.0 getExecutablePath :: IO FilePath -------------------------------------------------------------------------------- -- Mac OS X {-# LINE 64 "libraries/base/System/Environment/ExecutablePath.hsc" #-} type UInt32 = Word32 foreign import ccall unsafe "mach-o/dyld.h _NSGetExecutablePath" c__NSGetExecutablePath :: CString -> Ptr UInt32 -> IO CInt -- | Returns the path of the main executable. The path may be a -- symbolic link and not the real file. -- -- See dyld(3) _NSGetExecutablePath :: IO FilePath _NSGetExecutablePath = allocaBytes 1024 $ \ buf -> -- PATH_MAX is 1024 on OS X alloca $ \ bufsize -> do poke bufsize 1024 status <- c__NSGetExecutablePath buf bufsize if status == 0 then peekFilePath buf else do reqBufsize <- fromIntegral `fmap` peek bufsize allocaBytes reqBufsize $ \ newBuf -> do status2 <- c__NSGetExecutablePath newBuf bufsize if status2 == 0 then peekFilePath newBuf else error "_NSGetExecutablePath: buffer too small" foreign import ccall unsafe "stdlib.h realpath" c_realpath :: CString -> CString -> IO CString -- | Resolves all symbolic links, extra \/ characters, and references -- to \/.\/ and \/..\/. Returns an absolute pathname. -- -- See realpath(3) realpath :: FilePath -> IO FilePath realpath path = withFilePath path $ \ fileName -> allocaBytes 1024 $ \ resolvedName -> do _ <- throwErrnoIfNull "realpath" $ c_realpath fileName resolvedName peekFilePath resolvedName getExecutablePath = _NSGetExecutablePath >>= realpath -------------------------------------------------------------------------------- -- Linux {-# LINE 176 "libraries/base/System/Environment/ExecutablePath.hsc" #-}