diff options
author | Tim Kientzle <kientzle@gmail.com> | 2009-04-01 20:30:54 -0400 |
---|---|---|
committer | Tim Kientzle <kientzle@gmail.com> | 2009-04-01 20:30:54 -0400 |
commit | 4a55d43d91f7ce0617658afa1d764965abf743fc (patch) | |
tree | 2102ca1c40f3d83db127f5e8fe32273c8d79afef /libarchive/archive_write_disk_set_standard_lookup.c | |
parent | 88b368fb0c3bcbf770cd77b7811b2f5a849c51bb (diff) | |
download | libarchive-4a55d43d91f7ce0617658afa1d764965abf743fc.tar.gz |
Issue 19: Use getpwnam_r/getgrnam_r to look up uids and gids,
since they're thread-safe.
SVN-Revision: 905
Diffstat (limited to 'libarchive/archive_write_disk_set_standard_lookup.c')
-rw-r--r-- | libarchive/archive_write_disk_set_standard_lookup.c | 56 |
1 files changed, 50 insertions, 6 deletions
diff --git a/libarchive/archive_write_disk_set_standard_lookup.c b/libarchive/archive_write_disk_set_standard_lookup.c index 805c8c68..55373b8c 100644 --- a/libarchive/archive_write_disk_set_standard_lookup.c +++ b/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; |