From d4feb8c50b82015cb83c896e9f430ee109480346 Mon Sep 17 00:00:00 2001 From: "bjorn@bringert.net" Date: Mon, 16 Apr 2007 21:48:37 +0000 Subject: 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. --- System/Posix/User.hsc | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'System/Posix/User.hsc') 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 -- cgit v1.2.3