Hey,
This patch provides System.Posix.User getUserEntryFor{ID,Name} on
platforms without the _r versions of getpwuid and getpwnam. This
appears to be all the BSDs, including the Mac.
I'd like some comment on whether I should bother with the MVar locking
code -- and is this the way to go about it? The issue with the non-_r
functions is threadsafe access to a static buffer.
Also, while I'm here, solve the getGroupEntryFor* "Result too large" bug
on OpenBSD:
http://www.haskell.org/pipermail/glasgow-haskell-bugs/2003-September/003601.html
grBufSize was too small, apparently.
-- Don
Index: configure.ac
===================================================================
RCS file: /cvs/fptools/configure.ac,v
retrieving revision 1.83
diff -u -u -r1.83 configure.ac
--- configure.ac 22 Sep 2004 08:37:00 -0000 1.83
+++ configure.ac 29 Sep 2004 01:40:55 -0000
@@ -1132,7 +1132,7 @@
fi
dnl ** check for more functions
-AC_CHECK_FUNCS([ftime getclock getgrgid_r getgrnam_r getpagesize getpwnam_r
getpwuid_r getrusage gettimeofday gmtime_r localtime_r lstat readdir_r readlink setenv
setitimer siginterrupt symlink sysconf times unsetenv])
+AC_CHECK_FUNCS([ftime getclock getgrgid_r getgrnam_r getpagesize getpwnam_r
getpwuid_r getpwnam getpwuid getrusage gettimeofday gmtime_r localtime_r lstat
readdir_r readlink setenv setitimer siginterrupt symlink sysconf times unsetenv])
dnl ** Solaris2 needs additionl flag for getpw*_r()
case "$TargetPlatform" in
Index: libraries/unix/System/Posix/User.hsc
===================================================================
RCS file: /cvs/fptools/libraries/unix/System/Posix/User.hsc,v
retrieving revision 1.8
diff -u -u -r1.8 User.hsc
--- libraries/unix/System/Posix/User.hsc 19 Feb 2004 16:29:28 -0000 1.8
+++ libraries/unix/System/Posix/User.hsc 29 Sep 2004 01:41:27 -0000
@@ -47,6 +47,10 @@
import Foreign.C
import System.Posix.Internals ( CGroup, CPasswd )
+#if !defined(HAVE_GETPWNAM_R) || !defined(HAVE_GETPWUID_R)
+import Control.Concurrent.MVar ( newMVar, withMVar )
+#endif
+
-- -----------------------------------------------------------------------------
-- user environemnt
@@ -168,7 +172,7 @@
grBufSize = fromIntegral $ unsafePerformIO $
c_sysconf (#const _SC_GETGR_R_SIZE_MAX)
#else
-grBufSize = 1024 -- just assume some value
+grBufSize = 2048 -- just assume some value (1024 is too small on OpenBSD)
#endif
#endif
@@ -192,6 +196,16 @@
userShell :: String
}
+--
+-- getpwuid and getpwnam leave results in a static object. Subsequent
+-- calls modify the same object, which isn't threadsafe. We attempt to
+-- mitigate this issue, on platforms that don't provide the safe _r versions
+--
+#if !defined(HAVE_GETPWNAM_R) || !defined(HAVE_GETPWUID_R)
+lock = unsafePerformIO $ newMVar ()
+{-# NOINLINE lock #-}
+#endif
+
getUserEntryForID :: UserID -> IO UserEntry
#ifdef HAVE_GETPWUID_R
getUserEntryForID uid = do
@@ -205,6 +219,14 @@
foreign import ccall unsafe "getpwuid_r"
c_getpwuid_r :: CUid -> Ptr CPasswd ->
CString -> CSize -> Ptr (Ptr CPasswd) -> IO CInt
+#elif HAVE_GETPWUID
+getUserEntryForID uid = do
+ withMVar lock $ \_ -> do
+ ppw <- throwErrnoIfNull "getUserEntryForID" $ c_getpwuid uid
+ unpackUserEntry ppw
+
+foreign import ccall unsafe "getpwuid"
+ c_getpwuid :: CUid -> IO (Ptr CPasswd)
#else
getUserEntryForID = error "System.Posix.User.getUserEntryForID: not supported"
#endif
@@ -223,6 +245,15 @@
foreign import ccall unsafe "getpwnam_r"
c_getpwnam_r :: CString -> Ptr CPasswd ->
CString -> CSize -> Ptr (Ptr CPasswd) -> IO CInt
+#elif HAVE_GETPWNAM
+getUserEntryForName name = do
+ withCString name $ \ pstr -> do
+ withMVar lock $ \_ -> do
+ ppw <- throwErrnoIfNull "getUserEntryForName" $ c_getpwnam pstr
+ unpackUserEntry ppw
+
+foreign import ccall unsafe "getpwnam"
+ c_getpwnam :: CString -> IO (Ptr CPasswd)
#else
getUserEntryForName = error "System.Posix.User.getUserEntryForName: not supported"
#endif
_______________________________________________
Cvs-ghc mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/cvs-ghc