diff options
author | bjorn@bringert.net <unknown> | 2007-04-16 21:48:37 +0000 |
---|---|---|
committer | bjorn@bringert.net <unknown> | 2007-04-16 21:48:37 +0000 |
commit | d4feb8c50b82015cb83c896e9f430ee109480346 (patch) | |
tree | 38fbc2b6c30f6dd6421b9dc0bf0944e30cf7a1cd | |
parent | 5f7a21e6d5c8a983e92a576e249db2baab3f9c5a (diff) |
Handle sysconf(3) return value -1 when checking _SC_GETGR_R_SIZE_MAX and _SC_GETPW_R_SIZE_MAX.
sysconf(3) returns -1 on failure, but this was not handled when checking _SC_GETGR_R_SIZE_MAX and _SC_GETPW_R_SIZE_MAX in System.Posix.User. This made getUserEntryForID, getUserEntryForName, getGroupEntryForID and getGroupEntryForName fail on OS X 10.4.9 on i386. Just checking that unistd.h defines _SC_GETGR_R_SIZE_MAX and _SC_GETPW_R_SIZE_MAX as was done before does not guarantee that sysconf(3) will succeed.
sysconf(3) failure is now handled by using the same default values as were already used when sysconf(3) is not available, or the parameter names are not defined.
-rw-r--r-- | System/Posix/User.hsc | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/System/Posix/User.hsc b/System/Posix/User.hsc index 2ca6f4f..49c834a 100644 --- a/System/Posix/User.hsc +++ b/System/Posix/User.hsc @@ -223,8 +223,7 @@ getAllGroupEntries = error "System.Posix.User.getAllGroupEntries: not supported" #if defined(HAVE_GETGRGID_R) || defined(HAVE_GETGRNAM_R) grBufSize :: Int #if defined(HAVE_SYSCONF) && defined(HAVE_SC_GETGR_R_SIZE_MAX) -grBufSize = fromIntegral $ unsafePerformIO $ - c_sysconf (#const _SC_GETGR_R_SIZE_MAX) +grBufSize = sysconfWithDefault 2048 (#const _SC_GETGR_R_SIZE_MAX) #else grBufSize = 2048 -- just assume some value (1024 is too small on OpenBSD) #endif @@ -351,8 +350,7 @@ getAllUserEntries = error "System.Posix.User.getAllUserEntries: not supported" #if defined(HAVE_GETPWUID_R) || defined(HAVE_GETPWNAM_R) pwBufSize :: Int #if defined(HAVE_SYSCONF) && defined(HAVE_SC_GETPW_R_SIZE_MAX) -pwBufSize = fromIntegral $ unsafePerformIO $ - c_sysconf (#const _SC_GETPW_R_SIZE_MAX) +pwBufSize = sysconfWithDefault 1024 (#const _SC_GETPW_R_SIZE_MAX) #else pwBufSize = 1024 #endif @@ -361,6 +359,15 @@ pwBufSize = 1024 #ifdef HAVE_SYSCONF foreign import ccall unsafe "sysconf" c_sysconf :: CInt -> IO CLong + +-- We need a default value since sysconf can fail and return -1 +-- even when the parameter name is defined in unistd.h. +-- One example of this is _SC_GETPW_R_SIZE_MAX under +-- Mac OS X 10.4.9 on i386. +sysconfWithDefault :: Int -> CInt -> Int +sysconfWithDefault def sc = + unsafePerformIO $ do v <- fmap fromIntegral $ c_sysconf sc + return $ if v == (-1) then def else v #endif unpackUserEntry :: Ptr CPasswd -> IO UserEntry |