diff options
author | kientzle <kientzle@FreeBSD.org> | 2009-04-17 00:44:47 +0000 |
---|---|---|
committer | kientzle <kientzle@FreeBSD.org> | 2009-04-17 00:44:47 +0000 |
commit | fecbf2a6965a8f465b8ec2172f67b38354c7191e (patch) | |
tree | 36451dfd13f16ecb0f9ba7b68031a405aa3ad4c7 /lib | |
parent | 1b0a8e451a6fc27ef612215c82d205ee6202ddb4 (diff) | |
download | FreeBSD-src-fecbf2a6965a8f465b8ec2172f67b38354c7191e.zip FreeBSD-src-fecbf2a6965a8f465b8ec2172f67b38354c7191e.tar.gz |
Use thread-safe getgrnam_r() and getpwnam_r(); dynamically size
the buffer used by this.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libarchive/archive_write_disk_set_standard_lookup.c | 56 |
1 files changed, 50 insertions, 6 deletions
diff --git a/lib/libarchive/archive_write_disk_set_standard_lookup.c b/lib/libarchive/archive_write_disk_set_standard_lookup.c index 5329425..59f6e17 100644 --- a/lib/libarchive/archive_write_disk_set_standard_lookup.c +++ b/lib/libarchive/archive_write_disk_set_standard_lookup.c @@ -118,12 +118,34 @@ lookup_gid(void *private_data, const char *gname, gid_t gid) 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 char *uname, uid_t uid) 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; |