Index: cygwin.din
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/cygwin.din,v
retrieving revision 1.26
diff -u -p -r1.26 cygwin.din
--- cygwin.din	2001/04/13 15:28:20	1.26
+++ cygwin.din	2001/04/16 11:01:15
@@ -933,8 +933,10 @@ getpwduid
 _getpwduid = getpwduid
 getpwnam
 _getpwnam = getpwnam
+getpwnam_r
 getpwuid
 _getpwuid = getpwuid
+getpwuid_r
 getpgrp
 _getpgrp = getpgrp
 getgrent
Index: passwd.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/passwd.cc,v
retrieving revision 1.17
diff -u -p -r1.17 passwd.cc
--- passwd.cc	2001/01/28 05:51:14	1.17
+++ passwd.cc	2001/04/16 11:01:15
@@ -122,6 +122,20 @@ read_etc_passwd ()
 {
     extern int passwd_sem;
     char linebuf[1024];
+    /* A mutex is ok for speed here - pthreads will use critical sections not mutex's
+     * for non-shared mutexs in the future. Also, this function will at most be called
+     * once from each thread, after that the passwd_state test will succeed
+     */
+    static pthread_mutex_t etc_passwd_mutex = (pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER;
+    pthread_mutex_lock(&etc_passwd_mutex);
+
+    /* if we got blocked by the mutex, then etc_passwd may have been processed */
+    if (!(passwd_state == uninitialized))
+      {
+        pthread_mutex_unlock(&etc_passwd_mutex);
+        return;
+      }
+
     ++passwd_sem;
     FILE *f = fopen ("/etc/passwd", "rt");
     --passwd_sem;
@@ -145,9 +159,11 @@ read_etc_passwd ()
 	add_pwd_line (linebuf);
 	passwd_state = emulated;
       }
+    pthread_mutex_unlock(&etc_passwd_mutex);
 }
 
 /* Cygwin internal */
+/* If this ever becomes non-reentrant, update all the getpw*_r functions */
 static struct passwd *
 search_for (uid_t uid, const char *name)
 {
@@ -188,6 +204,40 @@ getpwuid (uid_t uid)
   return search_for (uid, 0);
 }
 
+extern "C" int 
+getpwuid_r (uid_t uid, struct passwd *pwd, char *buffer, size_t bufsize, struct passwd **result)
+{
+  *result = NULL;
+
+  if (!pwd || !buffer)
+    return ERANGE;
+
+  if (passwd_state == uninitialized)
+    read_etc_passwd ();
+
+  struct passwd *temppw = search_for (uid, 0);
+
+  if (!temppw)
+    return 0;
+
+  /* check needed buffer size. */
+  size_t needsize = strlen (temppw->pw_name) + strlen (temppw->pw_dir) + strlen (temppw->pw_shell);
+  if (needsize > bufsize)
+    return ERANGE;
+
+  /* make a copy of temppw */
+  *result = pwd;
+  pwd->pw_uid = temppw->pw_uid;
+  pwd->pw_gid = temppw->pw_gid;
+  pwd->pw_name = buffer;
+  pwd->pw_dir = buffer + strlen (temppw->pw_name);
+  pwd->pw_shell = buffer + strlen (temppw->pw_name) + strlen (temppw->pw_dir);
+  strcpy (pwd->pw_name, temppw->pw_name);
+  strcpy (pwd->pw_dir, temppw->pw_dir);
+  strcpy (pwd->pw_shell, temppw->pw_shell);
+  return 0;
+}
+
 extern "C" struct passwd *
 getpwnam (const char *name)
 {
@@ -195,6 +245,45 @@ getpwnam (const char *name)
     read_etc_passwd ();
 
   return search_for (0, name);
+}
+
+
+/* the max size buffer we can expect to 
+ * use is returned via sysconf with _SC_GETPW_R_SIZE_MAX.
+ * This may need updating! - Rob Collins April 2001.
+ */
+extern "C" int
+getpwnam_r (const char *nam, struct passwd *pwd, char *buffer, size_t bufsize, struct passwd **result)
+{
+  *result = NULL;
+
+  if (!pwd || !buffer || !nam)
+    return ERANGE;
+
+  if (passwd_state == uninitialized)
+    read_etc_passwd ();
+
+  struct passwd *temppw = search_for (0, nam);
+
+  if (!temppw)
+    return 0;
+
+  /* check needed buffer size. */
+  size_t needsize = strlen (temppw->pw_name) + strlen (temppw->pw_dir) + strlen (temppw->pw_shell);
+  if (needsize > bufsize)
+    return ERANGE;
+    
+  /* make a copy of temppw */
+  *result = pwd;
+  pwd->pw_uid = temppw->pw_uid;
+  pwd->pw_gid = temppw->pw_gid;
+  pwd->pw_name = buffer;
+  pwd->pw_dir = buffer + strlen (temppw->pw_name);
+  pwd->pw_shell = buffer + strlen (temppw->pw_name) + strlen (temppw->pw_dir);
+  strcpy (pwd->pw_name, temppw->pw_name);
+  strcpy (pwd->pw_dir, temppw->pw_dir);
+  strcpy (pwd->pw_shell, temppw->pw_shell);
+  return 0;
 }
 
 extern "C" struct passwd *
