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

Reply via email to