Skip to content

Instantly share code, notes, and snippets.

@hvr
Created August 10, 2016 17:07
Show Gist options
  • Save hvr/286f05b4b274cffbfd81558b0d33d12c to your computer and use it in GitHub Desktop.
Save hvr/286f05b4b274cffbfd81558b0d33d12c to your computer and use it in GitHub Desktop.
module Main where
import Foreign.C
import Foreign.Marshal.Alloc
import Foreign.Ptr
import Foreign.Storable
import System.Posix.Internals
-- import System.Environment (getExecutablePath)
main :: IO ()
main = print =<< getExecutablePath
foreign import ccall unsafe "getFullProgArgv"
c_getFullProgArgv :: Ptr CInt -> Ptr (Ptr CString) -> IO ()
getExecutablePath :: IO FilePath
getExecutablePath =
alloca $ \ p_argc ->
alloca $ \ p_argv -> do
c_getFullProgArgv p_argc p_argv
argc <- peek p_argc
if argc > 0
-- If argc > 0 then argv[0] is guaranteed by the standard
-- to be a pointer to a null-terminated string.
then peek p_argv >>= peek >>= peekFilePath
else errorWithoutStackTrace $ "getExecutablePath: " ++ msg
where msg = "no OS specific implementation and program name couldn't be " ++
"found in argv"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment