{-# LINE 1 "libraries/base/System/Environment/ExecutablePath.hsc" #-}
{-# LANGUAGE Safe #-}
{-# LANGUAGE CPP #-}
module System.Environment.ExecutablePath ( getExecutablePath ) where
{-# 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 60 "libraries/base/System/Environment/ExecutablePath.hsc" #-}
getExecutablePath :: IO FilePath
{-# LINE 80 "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
_NSGetExecutablePath :: IO FilePath
_NSGetExecutablePath :: IO FilePath
_NSGetExecutablePath =
forall a b. Int -> (Ptr a -> IO b) -> IO b
allocaBytes Int
1024 forall a b. (a -> b) -> a -> b
$ \ Ptr CChar
buf ->
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca forall a b. (a -> b) -> a -> b
$ \ Ptr UInt32
bufsize -> do
forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr UInt32
bufsize UInt32
1024
CInt
status <- Ptr CChar -> Ptr UInt32 -> IO CInt
c__NSGetExecutablePath Ptr CChar
buf Ptr UInt32
bufsize
if CInt
status forall a. Eq a => a -> a -> Bool
== CInt
0
then Ptr CChar -> IO FilePath
peekFilePath Ptr CChar
buf
else do Int
reqBufsize <- forall a b. (Integral a, Num b) => a -> b
fromIntegral forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` forall a. Storable a => Ptr a -> IO a
peek Ptr UInt32
bufsize
forall a b. Int -> (Ptr a -> IO b) -> IO b
allocaBytes Int
reqBufsize forall a b. (a -> b) -> a -> b
$ \ Ptr CChar
newBuf -> do
CInt
status2 <- Ptr CChar -> Ptr UInt32 -> IO CInt
c__NSGetExecutablePath Ptr CChar
newBuf Ptr UInt32
bufsize
if CInt
status2 forall a. Eq a => a -> a -> Bool
== CInt
0
then Ptr CChar -> IO FilePath
peekFilePath Ptr CChar
newBuf
else forall a. FilePath -> a
errorWithoutStackTrace FilePath
"_NSGetExecutablePath: buffer too small"
foreign import ccall unsafe "stdlib.h realpath"
c_realpath :: CString -> CString -> IO CString
realpath :: FilePath -> IO FilePath
realpath :: FilePath -> IO FilePath
realpath FilePath
path =
forall a. FilePath -> (Ptr CChar -> IO a) -> IO a
withFilePath FilePath
path forall a b. (a -> b) -> a -> b
$ \ Ptr CChar
fileName ->
forall a b. Int -> (Ptr a -> IO b) -> IO b
allocaBytes Int
1024 forall a b. (a -> b) -> a -> b
$ \ Ptr CChar
resolvedName -> do
Ptr CChar
_ <- forall a. FilePath -> IO (Ptr a) -> IO (Ptr a)
throwErrnoIfNull FilePath
"realpath" forall a b. (a -> b) -> a -> b
$ Ptr CChar -> Ptr CChar -> IO (Ptr CChar)
c_realpath Ptr CChar
fileName Ptr CChar
resolvedName
Ptr CChar -> IO FilePath
peekFilePath Ptr CChar
resolvedName
getExecutablePath :: IO FilePath
getExecutablePath = IO FilePath
_NSGetExecutablePath forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= FilePath -> IO FilePath
realpath
{-# LINE 300 "libraries/base/System/Environment/ExecutablePath.hsc" #-}