{-# LINE 1 "libraries/unix/System/Posix/ByteString/FilePath.hsc" #-}

{-# LINE 2 "libraries/unix/System/Posix/ByteString/FilePath.hsc" #-}
{-# LANGUAGE Safe #-}

{-# LINE 6 "libraries/unix/System/Posix/ByteString/FilePath.hsc" #-}

-----------------------------------------------------------------------------
-- |
-- Module      :  System.Posix.ByteString.FilePath
-- Copyright   :  (c) The University of Glasgow 2002
-- License     :  BSD-style (see the file libraries/base/LICENSE)
--
-- Maintainer  :  libraries@haskell.org
-- Stability   :  provisional
-- Portability :  non-portable (requires POSIX)
--
-- Internal stuff: support for ByteString FilePaths
--
-----------------------------------------------------------------------------

module System.Posix.ByteString.FilePath (
     RawFilePath, withFilePath, peekFilePath, peekFilePathLen,
     throwErrnoPathIfMinus1Retry,
     throwErrnoPathIfMinus1Retry_,
     throwErrnoPathIfNullRetry,
     throwErrnoPathIfRetry,
     throwErrnoPath,
     throwErrnoPathIf,
     throwErrnoPathIf_,
     throwErrnoPathIfNull,
     throwErrnoPathIfMinus1,
     throwErrnoPathIfMinus1_
  ) where

import Foreign hiding ( void )
import Foreign.C hiding (
     throwErrnoPath,
     throwErrnoPathIf,
     throwErrnoPathIf_,
     throwErrnoPathIfNull,
     throwErrnoPathIfMinus1,
     throwErrnoPathIfMinus1_ )

import Control.Monad
import Data.ByteString
import Data.ByteString.Char8 as BC
import Prelude hiding (FilePath)

-- | A literal POSIX file path
type RawFilePath = ByteString

withFilePath :: RawFilePath -> (CString -> IO a) -> IO a
withFilePath :: RawFilePath -> (CString -> IO a) -> IO a
withFilePath = RawFilePath -> (CString -> IO a) -> IO a
forall a. RawFilePath -> (CString -> IO a) -> IO a
useAsCString

peekFilePath :: CString -> IO RawFilePath
peekFilePath :: CString -> IO RawFilePath
peekFilePath = CString -> IO RawFilePath
packCString

peekFilePathLen :: CStringLen -> IO RawFilePath
peekFilePathLen :: CStringLen -> IO RawFilePath
peekFilePathLen = CStringLen -> IO RawFilePath
packCStringLen


throwErrnoPathIfMinus1Retry :: (Eq a, Num a)
                            => String -> RawFilePath -> IO a -> IO a
throwErrnoPathIfMinus1Retry :: String -> RawFilePath -> IO a -> IO a
throwErrnoPathIfMinus1Retry String
loc RawFilePath
path IO a
f = do
  (a -> Bool) -> String -> RawFilePath -> IO a -> IO a
forall a. (a -> Bool) -> String -> RawFilePath -> IO a -> IO a
throwErrnoPathIfRetry (a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== -a
1) String
loc RawFilePath
path IO a
f

throwErrnoPathIfMinus1Retry_ :: (Eq a, Num a)
                             => String -> RawFilePath -> IO a -> IO ()
throwErrnoPathIfMinus1Retry_ :: String -> RawFilePath -> IO a -> IO ()
throwErrnoPathIfMinus1Retry_ String
loc RawFilePath
path IO a
f =
  IO a -> IO ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (IO a -> IO ()) -> IO a -> IO ()
forall a b. (a -> b) -> a -> b
$ (a -> Bool) -> String -> RawFilePath -> IO a -> IO a
forall a. (a -> Bool) -> String -> RawFilePath -> IO a -> IO a
throwErrnoPathIfRetry (a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== -a
1) String
loc RawFilePath
path IO a
f

throwErrnoPathIfNullRetry :: String -> RawFilePath -> IO (Ptr a) -> IO (Ptr a)
throwErrnoPathIfNullRetry :: String -> RawFilePath -> IO (Ptr a) -> IO (Ptr a)
throwErrnoPathIfNullRetry String
loc RawFilePath
path IO (Ptr a)
f =
  (Ptr a -> Bool)
-> String -> RawFilePath -> IO (Ptr a) -> IO (Ptr a)
forall a. (a -> Bool) -> String -> RawFilePath -> IO a -> IO a
throwErrnoPathIfRetry (Ptr a -> Ptr a -> Bool
forall a. Eq a => a -> a -> Bool
== Ptr a
forall a. Ptr a
nullPtr) String
loc RawFilePath
path IO (Ptr a)
f

throwErrnoPathIfRetry :: (a -> Bool) -> String -> RawFilePath -> IO a -> IO a
throwErrnoPathIfRetry :: (a -> Bool) -> String -> RawFilePath -> IO a -> IO a
throwErrnoPathIfRetry a -> Bool
pr String
loc RawFilePath
rpath IO a
f =
  do
    a
res <- IO a
f
    if a -> Bool
pr a
res
      then do
        Errno
err <- IO Errno
getErrno
        if Errno
err Errno -> Errno -> Bool
forall a. Eq a => a -> a -> Bool
== Errno
eINTR
          then (a -> Bool) -> String -> RawFilePath -> IO a -> IO a
forall a. (a -> Bool) -> String -> RawFilePath -> IO a -> IO a
throwErrnoPathIfRetry a -> Bool
pr String
loc RawFilePath
rpath IO a
f
          else String -> RawFilePath -> IO a
forall a. String -> RawFilePath -> IO a
throwErrnoPath String
loc RawFilePath
rpath
      else a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return a
res

-- | as 'throwErrno', but exceptions include the given path when appropriate.
--
throwErrnoPath :: String -> RawFilePath -> IO a
throwErrnoPath :: String -> RawFilePath -> IO a
throwErrnoPath String
loc RawFilePath
path =
  do
    Errno
errno <- IO Errno
getErrno
    IOError -> IO a
forall a. IOError -> IO a
ioError (String -> Errno -> Maybe Handle -> Maybe String -> IOError
errnoToIOError String
loc Errno
errno Maybe Handle
forall a. Maybe a
Nothing (String -> Maybe String
forall a. a -> Maybe a
Just (RawFilePath -> String
BC.unpack RawFilePath
path)))

-- | as 'throwErrnoIf', but exceptions include the given path when
--   appropriate.
--
throwErrnoPathIf :: (a -> Bool) -> String -> RawFilePath -> IO a -> IO a
throwErrnoPathIf :: (a -> Bool) -> String -> RawFilePath -> IO a -> IO a
throwErrnoPathIf a -> Bool
cond String
loc RawFilePath
path IO a
f =
  do
    a
res <- IO a
f
    if a -> Bool
cond a
res then String -> RawFilePath -> IO a
forall a. String -> RawFilePath -> IO a
throwErrnoPath String
loc RawFilePath
path else a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return a
res

-- | as 'throwErrnoIf_', but exceptions include the given path when
--   appropriate.
--
throwErrnoPathIf_ :: (a -> Bool) -> String -> RawFilePath -> IO a -> IO ()
throwErrnoPathIf_ :: (a -> Bool) -> String -> RawFilePath -> IO a -> IO ()
throwErrnoPathIf_ a -> Bool
cond String
loc RawFilePath
path IO a
f  = IO a -> IO ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (IO a -> IO ()) -> IO a -> IO ()
forall a b. (a -> b) -> a -> b
$ (a -> Bool) -> String -> RawFilePath -> IO a -> IO a
forall a. (a -> Bool) -> String -> RawFilePath -> IO a -> IO a
throwErrnoPathIf a -> Bool
cond String
loc RawFilePath
path IO a
f

-- | as 'throwErrnoIfNull', but exceptions include the given path when
--   appropriate.
--
throwErrnoPathIfNull :: String -> RawFilePath -> IO (Ptr a) -> IO (Ptr a)
throwErrnoPathIfNull :: String -> RawFilePath -> IO (Ptr a) -> IO (Ptr a)
throwErrnoPathIfNull  = (Ptr a -> Bool)
-> String -> RawFilePath -> IO (Ptr a) -> IO (Ptr a)
forall a. (a -> Bool) -> String -> RawFilePath -> IO a -> IO a
throwErrnoPathIf (Ptr a -> Ptr a -> Bool
forall a. Eq a => a -> a -> Bool
== Ptr a
forall a. Ptr a
nullPtr)

-- | as 'throwErrnoIfMinus1', but exceptions include the given path when
--   appropriate.
--
throwErrnoPathIfMinus1 :: (Eq a, Num a) => String -> RawFilePath -> IO a -> IO a
throwErrnoPathIfMinus1 :: String -> RawFilePath -> IO a -> IO a
throwErrnoPathIfMinus1 = (a -> Bool) -> String -> RawFilePath -> IO a -> IO a
forall a. (a -> Bool) -> String -> RawFilePath -> IO a -> IO a
throwErrnoPathIf (a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== -a
1)

-- | as 'throwErrnoIfMinus1_', but exceptions include the given path when
--   appropriate.
--
throwErrnoPathIfMinus1_ :: (Eq a, Num a) => String -> RawFilePath -> IO a -> IO ()
throwErrnoPathIfMinus1_ :: String -> RawFilePath -> IO a -> IO ()
throwErrnoPathIfMinus1_  = (a -> Bool) -> String -> RawFilePath -> IO a -> IO ()
forall a. (a -> Bool) -> String -> RawFilePath -> IO a -> IO ()
throwErrnoPathIf_ (a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== -a
1)