Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 17 Apr 2009 00:44:47 +0000 (UTC)
From:      Tim Kientzle <kientzle@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r191168 - head/lib/libarchive
Message-ID:  <200904170044.n3H0ilHU098682@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kientzle
Date: Fri Apr 17 00:44:47 2009
New Revision: 191168
URL: http://svn.freebsd.org/changeset/base/191168

Log:
  Use thread-safe getgrnam_r() and getpwnam_r(); dynamically size
  the buffer used by this.

Modified:
  head/lib/libarchive/archive_write_disk_set_standard_lookup.c

Modified: head/lib/libarchive/archive_write_disk_set_standard_lookup.c
==============================================================================
--- head/lib/libarchive/archive_write_disk_set_standard_lookup.c	Fri Apr 17 00:44:03 2009	(r191167)
+++ head/lib/libarchive/archive_write_disk_set_standard_lookup.c	Fri Apr 17 00:44:47 2009	(r191168)
@@ -118,12 +118,34 @@ lookup_gid(void *private_data, const cha
 	b->hash = h;
 #if HAVE_GRP_H
 	{
-		struct group	*grent = getgrnam(gname);
-		if (grent != NULL)
-			gid = grent->gr_gid;
+		char _buffer[128];
+		size_t bufsize = 128;
+		char *buffer = _buffer;
+		struct group	grent, *result;
+		int r;
+
+		for (;;) {
+			r = getgrnam_r(gname, &grent, buffer, bufsize, &result);
+			if (r == 0)
+				break;
+			if (r != ERANGE)
+				break;
+			bufsize *= 2;
+			if (buffer != _buffer)
+				free(buffer);
+			buffer = malloc(bufsize);
+			if (buffer == NULL)
+				break;
+		}
+		if (result != NULL)
+			gid = result->gr_gid;
+		if (buffer != _buffer)
+			free(buffer);
 	}
 #elif defined(_WIN32) && !defined(__CYGWIN__)
 	/* TODO: do a gname->gid lookup for Windows. */
+#else
+	#error No way to perform gid lookups on this platform
 #endif
 	b->id = gid;
 
@@ -155,12 +177,34 @@ lookup_uid(void *private_data, const cha
 	b->hash = h;
 #if HAVE_PWD_H
 	{
-		struct passwd	*pwent = getpwnam(uname);
-		if (pwent != NULL)
-			uid = pwent->pw_uid;
+		char _buffer[128];
+		size_t bufsize = 128;
+		char *buffer = _buffer;
+		struct passwd	pwent, *result;
+		int r;
+
+		for (;;) {
+			r = getpwnam_r(uname, &pwent, buffer, bufsize, &result);
+			if (r == 0)
+				break;
+			if (r != ERANGE)
+				break;
+			bufsize *= 2;
+			if (buffer != _buffer)
+				free(buffer);
+			buffer = malloc(bufsize);
+			if (buffer == NULL)
+				break;
+		}
+		if (result != NULL)
+			uid = result->pw_uid;
+		if (buffer != _buffer)
+			free(buffer);
 	}
 #elif defined(_WIN32) && !defined(__CYGWIN__)
 	/* TODO: do a uname->uid lookup for Windows. */
+#else
+	#error No way to look up uids on this platform
 #endif
 	b->id = uid;
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200904170044.n3H0ilHU098682>