{-# LINE 1 "libraries/unix/System/Posix/User.hsc" #-}
{-# LANGUAGE Trustworthy, CApiFFI, PatternSynonyms, ViewPatterns #-}
module System.Posix.User (
    
    
    getRealUserID,
    getRealGroupID,
    getEffectiveUserID,
    getEffectiveGroupID,
    getGroups,
    getLoginName,
    getEffectiveUserName,
    
    groupName,
    groupPassword,
    groupID,
    groupMembers,
    pattern GroupEntry,
    getGroupEntryForID,
    getGroupEntryForName,
    getAllGroupEntries,
    
    userName,
    userPassword,
    userID,
    userGroupID,
    userGecos,
    homeDirectory,
    userShell,
    pattern UserEntry,
    getUserEntryForID,
    getUserEntryForName,
    getAllUserEntries,
    
    setUserID,
    setGroupID,
    setEffectiveUserID,
    setEffectiveGroupID,
    setGroups
  ) where
import System.Posix.Types
import System.IO.Unsafe (unsafePerformIO)
import Foreign.C
import Foreign.Ptr
import Foreign.Marshal
import Foreign.Storable
import System.Posix.User.Common ( UserEntry, GroupEntry
{-# LINE 70 "libraries/unix/System/Posix/User.hsc" #-}
      , unpackUserEntry, unpackGroupEntry, LKUPTYPE(..), CPasswd, CGroup
{-# LINE 72 "libraries/unix/System/Posix/User.hsc" #-}
  )
import qualified System.Posix.User.Common as User
{-# LINE 76 "libraries/unix/System/Posix/User.hsc" #-}
{-# LINE 79 "libraries/unix/System/Posix/User.hsc" #-}
import Control.Concurrent.MVar ( MVar, newMVar, withMVar )
import Control.Exception
{-# LINE 82 "libraries/unix/System/Posix/User.hsc" #-}
import Control.Monad
import System.IO.Error
import qualified Data.ByteString.Char8 as C8
{-# LINE 90 "libraries/unix/System/Posix/User.hsc" #-}
{-# LINE 155 "libraries/unix/System/Posix/User.hsc" #-}
{-# LINE 221 "libraries/unix/System/Posix/User.hsc" #-}
pwlock :: MVar ()
pwlock :: MVar ()
pwlock = IO (MVar ()) -> MVar ()
forall a. IO a -> a
unsafePerformIO (IO (MVar ()) -> MVar ()) -> IO (MVar ()) -> MVar ()
forall a b. (a -> b) -> a -> b
$ () -> IO (MVar ())
forall a. a -> IO (MVar a)
newMVar ()
{-# NOINLINE pwlock #-}
lockpw :: LKUPTYPE -> IO a -> IO a
{-# LINE 234 "libraries/unix/System/Posix/User.hsc" #-}
lockpw :: forall a. LKUPTYPE -> IO a -> IO a
lockpw LKUPTYPE
GETONE = IO a -> IO a
forall a. a -> a
id
lockpw LKUPTYPE
GETALL = MVar () -> (() -> IO a) -> IO a
forall a b. MVar a -> (a -> IO b) -> IO b
withMVar MVar ()
pwlock ((() -> IO a) -> IO a) -> (IO a -> () -> IO a) -> IO a -> IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO a -> () -> IO a
forall a b. a -> b -> a
const
{-# LINE 237 "libraries/unix/System/Posix/User.hsc" #-}
{-# LINE 240 "libraries/unix/System/Posix/User.hsc" #-}
{-# LINE 242 "libraries/unix/System/Posix/User.hsc" #-}
grlock :: MVar ()
grlock :: MVar ()
grlock = IO (MVar ()) -> MVar ()
forall a. IO a -> a
unsafePerformIO (IO (MVar ()) -> MVar ()) -> IO (MVar ()) -> MVar ()
forall a b. (a -> b) -> a -> b
$ () -> IO (MVar ())
forall a. a -> IO (MVar a)
newMVar ()
{-# NOINLINE grlock #-}
lockgr :: LKUPTYPE -> IO a -> IO a
{-# LINE 255 "libraries/unix/System/Posix/User.hsc" #-}
lockgr :: forall a. LKUPTYPE -> IO a -> IO a
lockgr LKUPTYPE
GETONE = IO a -> IO a
forall a. a -> a
id
lockgr LKUPTYPE
GETALL = MVar () -> (() -> IO a) -> IO a
forall a b. MVar a -> (a -> IO b) -> IO b
withMVar MVar ()
grlock ((() -> IO a) -> IO a) -> (IO a -> () -> IO a) -> IO a -> IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO a -> () -> IO a
forall a b. a -> b -> a
const
{-# LINE 258 "libraries/unix/System/Posix/User.hsc" #-}
{-# LINE 261 "libraries/unix/System/Posix/User.hsc" #-}
getRealUserID :: IO UserID
getRealUserID :: IO UserID
getRealUserID = IO UserID
c_getuid
foreign import ccall unsafe "getuid"
  c_getuid :: IO CUid
getRealGroupID :: IO GroupID
getRealGroupID :: IO GroupID
getRealGroupID = IO GroupID
c_getgid
foreign import ccall unsafe "getgid"
  c_getgid :: IO CGid
getEffectiveUserID :: IO UserID
getEffectiveUserID :: IO UserID
getEffectiveUserID = IO UserID
c_geteuid
foreign import ccall unsafe "geteuid"
  c_geteuid :: IO CUid
getEffectiveGroupID :: IO GroupID
getEffectiveGroupID :: IO GroupID
getEffectiveGroupID = IO GroupID
c_getegid
foreign import ccall unsafe "getegid"
  c_getegid :: IO CGid
getGroups :: IO [GroupID]
getGroups :: IO [GroupID]
getGroups = do
    CInt
ngroups <- CInt -> Ptr GroupID -> IO CInt
c_getgroups CInt
0 Ptr GroupID
forall a. Ptr a
nullPtr
    Int -> (Ptr GroupID -> IO [GroupID]) -> IO [GroupID]
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray (CInt -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CInt
ngroups) ((Ptr GroupID -> IO [GroupID]) -> IO [GroupID])
-> (Ptr GroupID -> IO [GroupID]) -> IO [GroupID]
forall a b. (a -> b) -> a -> b
$ \Ptr GroupID
arr -> do
       String -> IO CInt -> IO ()
forall a. (Eq a, Num a) => String -> IO a -> IO ()
throwErrnoIfMinus1_ String
"getGroups" (CInt -> Ptr GroupID -> IO CInt
c_getgroups CInt
ngroups Ptr GroupID
arr)
       [GroupID]
groups <- Int -> Ptr GroupID -> IO [GroupID]
forall a. Storable a => Int -> Ptr a -> IO [a]
peekArray (CInt -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CInt
ngroups) Ptr GroupID
arr
       [GroupID] -> IO [GroupID]
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return [GroupID]
groups
foreign import ccall unsafe "getgroups"
  c_getgroups :: CInt -> Ptr CGid -> IO CInt
setGroups :: [GroupID] -> IO ()
setGroups :: [GroupID] -> IO ()
setGroups [GroupID]
groups = do
    [GroupID] -> (Int -> Ptr GroupID -> IO ()) -> IO ()
forall a b. Storable a => [a] -> (Int -> Ptr a -> IO b) -> IO b
withArrayLen [GroupID]
groups ((Int -> Ptr GroupID -> IO ()) -> IO ())
-> (Int -> Ptr GroupID -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \ Int
ngroups Ptr GroupID
arr ->
       String -> IO CInt -> IO ()
forall a. (Eq a, Num a) => String -> IO a -> IO ()
throwErrnoIfMinus1_ String
"setGroups" (CInt -> Ptr GroupID -> IO CInt
c_setgroups (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
ngroups) Ptr GroupID
arr)
foreign import ccall unsafe "setgroups"
  c_setgroups :: CInt -> Ptr CGid -> IO CInt
getLoginName :: IO String
getLoginName :: IO String
getLoginName =  do
    
    Ptr CChar
str <- String -> IO (Ptr CChar) -> IO (Ptr CChar)
forall a. String -> IO (Ptr a) -> IO (Ptr a)
throwErrnoIfNull String
"getLoginName" IO (Ptr CChar)
c_getlogin
    Ptr CChar -> IO String
peekCAString Ptr CChar
str
foreign import ccall unsafe "getlogin"
  c_getlogin :: IO CString
setUserID :: UserID -> IO ()
setUserID :: UserID -> IO ()
setUserID UserID
uid = String -> IO CInt -> IO ()
forall a. (Eq a, Num a) => String -> IO a -> IO ()
throwErrnoIfMinus1_ String
"setUserID" (UserID -> IO CInt
c_setuid UserID
uid)
foreign import ccall unsafe "setuid"
  c_setuid :: CUid -> IO CInt
setEffectiveUserID :: UserID -> IO ()
setEffectiveUserID :: UserID -> IO ()
setEffectiveUserID UserID
uid = String -> IO CInt -> IO ()
forall a. (Eq a, Num a) => String -> IO a -> IO ()
throwErrnoIfMinus1_ String
"setEffectiveUserID" (UserID -> IO CInt
c_seteuid UserID
uid)
foreign import ccall unsafe "seteuid"
  c_seteuid :: CUid -> IO CInt
setGroupID :: GroupID -> IO ()
setGroupID :: GroupID -> IO ()
setGroupID GroupID
gid = String -> IO CInt -> IO ()
forall a. (Eq a, Num a) => String -> IO a -> IO ()
throwErrnoIfMinus1_ String
"setGroupID" (GroupID -> IO CInt
c_setgid GroupID
gid)
foreign import ccall unsafe "setgid"
  c_setgid :: CGid -> IO CInt
setEffectiveGroupID :: GroupID -> IO ()
setEffectiveGroupID :: GroupID -> IO ()
setEffectiveGroupID GroupID
gid =
  String -> IO CInt -> IO ()
forall a. (Eq a, Num a) => String -> IO a -> IO ()
throwErrnoIfMinus1_ String
"setEffectiveGroupID" (GroupID -> IO CInt
c_setegid GroupID
gid)
foreign import ccall unsafe "setegid"
  c_setegid :: CGid -> IO CInt
getEffectiveUserName :: IO String
getEffectiveUserName :: IO String
getEffectiveUserName = do
    UserID
euid <- IO UserID
getEffectiveUserID
    UserEntry
pw <- UserID -> IO UserEntry
getUserEntryForID UserID
euid
    String -> IO String
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (UserEntry -> String
userName UserEntry
pw)
{-# LINE 381 "libraries/unix/System/Posix/User.hsc" #-}
groupName :: GroupEntry -> String
groupName :: GroupEntry -> String
groupName (GroupEntry String
gn String
_ GroupID
_ [String]
_) = String
gn
groupPassword :: GroupEntry -> String
groupPassword :: GroupEntry -> String
groupPassword (GroupEntry String
_ String
gp GroupID
_ [String]
_) = String
gp
groupID :: GroupEntry -> GroupID
groupID :: GroupEntry -> GroupID
groupID (GroupEntry String
_ String
_ GroupID
id' [String]
_) = GroupID
id'
groupMembers :: GroupEntry -> [String]
groupMembers :: GroupEntry -> [String]
groupMembers (GroupEntry String
_ String
_ GroupID
_ [String]
gm) = [String]
gm
pattern GroupEntry :: String          
                   -> String          
                   -> GroupID         
                   -> [String]        
                   -> GroupEntry
pattern $mGroupEntry :: forall {r}.
GroupEntry
-> (String -> String -> GroupID -> [String] -> r)
-> ((# #) -> r)
-> r
$bGroupEntry :: String -> String -> GroupID -> [String] -> GroupEntry
GroupEntry gn gp gi gm <- User.GroupEntry (C8.unpack -> gn) (C8.unpack -> gp) gi (fmap C8.unpack -> gm) where
  GroupEntry String
gn String
gp GroupID
gi [String]
gm = ByteString -> ByteString -> GroupID -> [ByteString] -> GroupEntry
User.GroupEntry (String -> ByteString
C8.pack String
gn) (String -> ByteString
C8.pack String
gp) GroupID
gi (String -> ByteString
C8.pack (String -> ByteString) -> [String] -> [ByteString]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [String]
gm)
{-# COMPLETE GroupEntry #-}
{-# LINE 426 "libraries/unix/System/Posix/User.hsc" #-}
getGroupEntryForID :: GroupID -> IO GroupEntry
{-# LINE 433 "libraries/unix/System/Posix/User.hsc" #-}
getGroupEntryForID gid = lockgr GETONE $
    allocaBytes (32) $ \pgr ->
{-# LINE 435 "libraries/unix/System/Posix/User.hsc" #-}
        doubleAllocWhileERANGE "getGroupEntryForID" "group"
            grBufSize unpackGroupEntry $ c_getgrgid_r gid pgr
foreign import capi safe "HsUnix.h getgrgid_r"
  c_getgrgid_r :: CGid -> Ptr CGroup -> CString
                 -> CSize -> Ptr (Ptr CGroup) -> IO CInt
{-# LINE 445 "libraries/unix/System/Posix/User.hsc" #-}
getGroupEntryForName :: String -> IO GroupEntry
{-# LINE 452 "libraries/unix/System/Posix/User.hsc" #-}
getGroupEntryForName name = lockgr GETONE $
    allocaBytes (32) $ \pgr ->
{-# LINE 454 "libraries/unix/System/Posix/User.hsc" #-}
        withCAString name $ \ pstr ->
            doubleAllocWhileERANGE "getGroupEntryForName" "group"
                grBufSize unpackGroupEntry $ c_getgrnam_r pstr pgr
foreign import capi safe "HsUnix.h getgrnam_r"
  c_getgrnam_r :: CString -> Ptr CGroup -> CString
                 -> CSize -> Ptr (Ptr CGroup) -> IO CInt
{-# LINE 465 "libraries/unix/System/Posix/User.hsc" #-}
getAllGroupEntries :: IO [GroupEntry]
{-# LINE 476 "libraries/unix/System/Posix/User.hsc" #-}
getAllGroupEntries = lockgr GETALL $ bracket_ c_setgrent c_endgrent $ worker []
  where
    worker accum = do
        resetErrno
        ppw <- throwErrnoIfNullAndError "getAllGroupEntries" $ c_getgrent
        if ppw == nullPtr
            then return (reverse accum)
            else do thisentry <- unpackGroupEntry ppw
                    worker (thisentry : accum)
foreign import ccall safe "getgrent" c_getgrent :: IO (Ptr CGroup)
foreign import ccall safe "setgrent" c_setgrent :: IO ()
foreign import ccall safe "endgrent" c_endgrent :: IO ()
{-# LINE 493 "libraries/unix/System/Posix/User.hsc" #-}
{-# LINE 495 "libraries/unix/System/Posix/User.hsc" #-}
grBufSize :: Int
{-# LINE 497 "libraries/unix/System/Posix/User.hsc" #-}
grBufSize = sysconfWithDefault 1024 (69)
{-# LINE 498 "libraries/unix/System/Posix/User.hsc" #-}
{-# LINE 501 "libraries/unix/System/Posix/User.hsc" #-}
{-# LINE 502 "libraries/unix/System/Posix/User.hsc" #-}
{-# LINE 504 "libraries/unix/System/Posix/User.hsc" #-}
userName :: UserEntry -> String
userName :: UserEntry -> String
userName (UserEntry String
n String
_ UserID
_ GroupID
_ String
_ String
_ String
_) = String
n
userPassword :: UserEntry -> String
userPassword :: UserEntry -> String
userPassword (UserEntry String
_ String
p UserID
_ GroupID
_ String
_ String
_ String
_) = String
p
userID :: UserEntry -> UserID
userID :: UserEntry -> UserID
userID (UserEntry String
_ String
_ UserID
id' GroupID
_ String
_ String
_ String
_) = UserID
id'
userGroupID :: UserEntry -> GroupID
userGroupID :: UserEntry -> GroupID
userGroupID (UserEntry String
_ String
_ UserID
_ GroupID
gid String
_ String
_ String
_) = GroupID
gid
userGecos :: UserEntry -> String
userGecos :: UserEntry -> String
userGecos (UserEntry String
_ String
_ UserID
_ GroupID
_ String
ge String
_ String
_) = String
ge
homeDirectory :: UserEntry -> String
homeDirectory :: UserEntry -> String
homeDirectory (UserEntry String
_ String
_ UserID
_ GroupID
_ String
_ String
hd String
_) = String
hd
userShell :: UserEntry -> String
userShell :: UserEntry -> String
userShell (UserEntry String
_ String
_ UserID
_ GroupID
_ String
_ String
_ String
us) = String
us
pattern UserEntry :: String         
                  -> String         
                  -> UserID         
                  -> GroupID        
                  -> String         
                  -> String         
                  -> String         
                  -> UserEntry
pattern $mUserEntry :: forall {r}.
UserEntry
-> (String
    -> String -> UserID -> GroupID -> String -> String -> String -> r)
-> ((# #) -> r)
-> r
$bUserEntry :: String
-> String
-> UserID
-> GroupID
-> String
-> String
-> String
-> UserEntry
UserEntry un up ui ugi ug hd us <- User.UserEntry (C8.unpack -> un)
                                                       (C8.unpack -> up)
                                                       ui
                                                       ugi
                                                       (C8.unpack -> ug)
                                                       (C8.unpack -> hd)
                                                       (C8.unpack -> us) where
  UserEntry String
un String
up UserID
ui GroupID
ugi String
ug String
hd String
us = ByteString
-> ByteString
-> UserID
-> GroupID
-> ByteString
-> ByteString
-> ByteString
-> UserEntry
User.UserEntry (String -> ByteString
C8.pack String
un)
                                                (String -> ByteString
C8.pack String
up)
                                                UserID
ui
                                                GroupID
ugi
                                                (String -> ByteString
C8.pack String
ug)
                                                (String -> ByteString
C8.pack String
hd)
                                                (String -> ByteString
C8.pack String
us)
{-# COMPLETE UserEntry #-}
getUserEntryForID :: UserID -> IO UserEntry
{-# LINE 561 "libraries/unix/System/Posix/User.hsc" #-}
getUserEntryForID uid = lockpw GETONE $
    allocaBytes (48) $ \ppw ->
{-# LINE 563 "libraries/unix/System/Posix/User.hsc" #-}
        doubleAllocWhileERANGE "getUserEntryForID" "user"
            pwBufSize unpackUserEntry $ c_getpwuid_r uid ppw
foreign import capi safe "HsUnix.h getpwuid_r"
  c_getpwuid_r :: CUid -> Ptr CPasswd ->
                        CString -> CSize -> Ptr (Ptr CPasswd) -> IO CInt
{-# LINE 573 "libraries/unix/System/Posix/User.hsc" #-}
getUserEntryForName :: String -> IO UserEntry
{-# LINE 580 "libraries/unix/System/Posix/User.hsc" #-}
getUserEntryForName name = lockpw GETONE $
    allocaBytes (48) $ \ppw ->
{-# LINE 582 "libraries/unix/System/Posix/User.hsc" #-}
        withCAString name $ \ pstr ->
            doubleAllocWhileERANGE "getUserEntryForName" "user"
                pwBufSize unpackUserEntry $ c_getpwnam_r pstr ppw
foreign import capi safe "HsUnix.h getpwnam_r"
  c_getpwnam_r :: CString -> Ptr CPasswd
               -> CString -> CSize -> Ptr (Ptr CPasswd) -> IO CInt
{-# LINE 593 "libraries/unix/System/Posix/User.hsc" #-}
getAllUserEntries :: IO [UserEntry]
{-# LINE 598 "libraries/unix/System/Posix/User.hsc" #-}
getAllUserEntries = lockpw GETALL $ bracket_ c_setpwent c_endpwent $ worker []
  where
    worker accum = do
        resetErrno
        ppw <- throwErrnoIfNullAndError "getAllUserEntries" $ c_getpwent
        if ppw == nullPtr
            then return (reverse accum)
            else do thisentry <- unpackUserEntry ppw
                    worker (thisentry : accum)
foreign import ccall safe "getpwent" c_getpwent :: IO (Ptr CPasswd)
foreign import ccall safe "setpwent" c_setpwent :: IO ()
foreign import ccall safe "endpwent" c_endpwent :: IO ()
{-# LINE 615 "libraries/unix/System/Posix/User.hsc" #-}
{-# LINE 617 "libraries/unix/System/Posix/User.hsc" #-}
pwBufSize :: Int
{-# LINE 619 "libraries/unix/System/Posix/User.hsc" #-}
pwBufSize = sysconfWithDefault 1024 (70)
{-# LINE 620 "libraries/unix/System/Posix/User.hsc" #-}
{-# LINE 623 "libraries/unix/System/Posix/User.hsc" #-}
{-# LINE 624 "libraries/unix/System/Posix/User.hsc" #-}
{-# LINE 626 "libraries/unix/System/Posix/User.hsc" #-}
foreign import ccall unsafe "sysconf"
  c_sysconf :: CInt -> IO CLong
sysconfWithDefault :: Int -> CInt -> Int
sysconfWithDefault :: Int -> CInt -> Int
sysconfWithDefault Int
def CInt
sc =
    IO Int -> Int
forall a. IO a -> a
unsafePerformIO (IO Int -> Int) -> IO Int -> Int
forall a b. (a -> b) -> a -> b
$ do Int
v <- (CLong -> Int) -> IO CLong -> IO Int
forall a b. (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap CLong -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (IO CLong -> IO Int) -> IO CLong -> IO Int
forall a b. (a -> b) -> a -> b
$ CInt -> IO CLong
c_sysconf CInt
sc
                         Int -> IO Int
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Int -> IO Int) -> Int -> IO Int
forall a b. (a -> b) -> a -> b
$ if Int
v Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== (-Int
1) then Int
def else Int
v
{-# LINE 638 "libraries/unix/System/Posix/User.hsc" #-}
{-# LINE 640 "libraries/unix/System/Posix/User.hsc" #-}
doubleAllocWhileERANGE
  :: String
  -> String 
  -> Int
  -> (Ptr r -> IO a)
  -> (Ptr b -> CSize -> Ptr (Ptr r) -> IO CInt)
  -> IO a
doubleAllocWhileERANGE :: forall r a b.
String
-> String
-> Int
-> (Ptr r -> IO a)
-> (Ptr b -> CSize -> Ptr (Ptr r) -> IO CInt)
-> IO a
doubleAllocWhileERANGE String
loc String
enttype Int
initlen Ptr r -> IO a
unpack Ptr b -> CSize -> Ptr (Ptr r) -> IO CInt
action =
  (Ptr (Ptr r) -> IO a) -> IO a
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr (Ptr r) -> IO a) -> IO a) -> (Ptr (Ptr r) -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ Int -> Ptr (Ptr r) -> IO a
go Int
initlen
 where
  go :: Int -> Ptr (Ptr r) -> IO a
go Int
len Ptr (Ptr r)
res = do
    Either CInt a
r <- Int -> (Ptr b -> IO (Either CInt a)) -> IO (Either CInt a)
forall a b. Int -> (Ptr a -> IO b) -> IO b
allocaBytes Int
len ((Ptr b -> IO (Either CInt a)) -> IO (Either CInt a))
-> (Ptr b -> IO (Either CInt a)) -> IO (Either CInt a)
forall a b. (a -> b) -> a -> b
$ \Ptr b
buf -> do
           CInt
rc <- Ptr b -> CSize -> Ptr (Ptr r) -> IO CInt
action Ptr b
buf (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len) Ptr (Ptr r)
res
           if CInt
rc CInt -> CInt -> Bool
forall a. Eq a => a -> a -> Bool
/= CInt
0
             then Either CInt a -> IO (Either CInt a)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (CInt -> Either CInt a
forall a b. a -> Either a b
Left CInt
rc)
             else do Ptr r
p <- Ptr (Ptr r) -> IO (Ptr r)
forall a. Storable a => Ptr a -> IO a
peek Ptr (Ptr r)
res
                     Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Ptr r
p Ptr r -> Ptr r -> Bool
forall a. Eq a => a -> a -> Bool
== Ptr r
forall a. Ptr a
nullPtr) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ IO ()
forall {a}. IO a
notFoundErr
                     (a -> Either CInt a) -> IO a -> IO (Either CInt a)
forall a b. (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> Either CInt a
forall a b. b -> Either a b
Right (Ptr r -> IO a
unpack Ptr r
p)
    case Either CInt a
r of
      Right a
x -> a -> IO a
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return a
x
      Left CInt
rc | CInt -> Errno
Errno CInt
rc Errno -> Errno -> Bool
forall a. Eq a => a -> a -> Bool
== Errno
eRANGE ->
        
        
        Int -> Ptr (Ptr r) -> IO a
go (Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
len) Ptr (Ptr r)
res
      Left CInt
rc ->
        IOError -> IO a
forall a. IOError -> IO a
ioError (String -> Errno -> Maybe Handle -> Maybe String -> IOError
errnoToIOError String
loc (CInt -> Errno
Errno CInt
rc) Maybe Handle
forall a. Maybe a
Nothing Maybe String
forall a. Maybe a
Nothing)
  notFoundErr :: IO a
notFoundErr =
    IOError -> IO a
forall a. IOError -> IO a
ioError (IOError -> IO a) -> IOError -> IO a
forall a b. (a -> b) -> a -> b
$ (IOError -> String -> IOError) -> String -> IOError -> IOError
forall a b c. (a -> b -> c) -> b -> a -> c
flip IOError -> String -> IOError
ioeSetErrorString (String
"no such " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
enttype)
            (IOError -> IOError) -> IOError -> IOError
forall a b. (a -> b) -> a -> b
$ IOErrorType -> String -> Maybe Handle -> Maybe String -> IOError
mkIOError IOErrorType
doesNotExistErrorType String
loc Maybe Handle
forall a. Maybe a
Nothing Maybe String
forall a. Maybe a
Nothing
throwErrnoIfNullAndError :: String -> IO (Ptr a) -> IO (Ptr a)
throwErrnoIfNullAndError :: forall a. String -> IO (Ptr a) -> IO (Ptr a)
throwErrnoIfNullAndError String
loc IO (Ptr a)
act = do
    Ptr a
rc <- IO (Ptr a)
act
    Errno
errno <- IO Errno
getErrno
    if Ptr a
rc Ptr a -> Ptr a -> Bool
forall a. Eq a => a -> a -> Bool
== Ptr a
forall a. Ptr a
nullPtr Bool -> Bool -> Bool
&& Errno
errno Errno -> Errno -> Bool
forall a. Eq a => a -> a -> Bool
/= Errno
eOK
       then String -> IO (Ptr a)
forall a. String -> IO a
throwErrno String
loc
       else Ptr a -> IO (Ptr a)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Ptr a
rc
{-# LINE 689 "libraries/unix/System/Posix/User.hsc" #-}