aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar bjorn@bringert.net <unknown>2007-04-16 21:48:37 +0000
committerGravatar bjorn@bringert.net <unknown>2007-04-16 21:48:37 +0000
commitd4feb8c50b82015cb83c896e9f430ee109480346 (patch)
tree38fbc2b6c30f6dd6421b9dc0bf0944e30cf7a1cd
parent5f7a21e6d5c8a983e92a576e249db2baab3f9c5a (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.hsc15
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