From 1fff03ef9b8c5badbf2e66d1293c17d372d60cff Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Fri, 16 Dec 2011 00:55:19 +0000 Subject: [PATCH] Add virGetGroupName to convert from GID to group name --- src/libvirt_private.syms | 1 + src/util/util.c | 55 ++++++++++++++++++++++++++++++++++++++++ src/util/util.h | 1 + 3 files changed, 57 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 0dfd4c1f1c..8301c78800 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1112,6 +1112,7 @@ virFindFileInPath; virFormatMacAddr; virGenerateMacAddr; virGetGroupID; +virGetGroupName; virGetHostname; virGetUserDirectory; virGetUserID; diff --git a/src/util/util.c b/src/util/util.c index 8663c4d664..fdfceaafd2 100644 --- a/src/util/util.c +++ b/src/util/util.c @@ -2187,6 +2187,56 @@ static char *virGetUserEnt(uid_t uid, return ret; } +static char *virGetGroupEnt(gid_t gid) +{ + char *strbuf; + char *ret; + struct group grbuf; + struct group *gr = NULL; + long val = sysconf(_SC_GETGR_R_SIZE_MAX); + size_t strbuflen = val; + int rc; + + /* sysconf is a hint; if it fails, fall back to a reasonable size */ + if (val < 0) + strbuflen = 1024; + + if (VIR_ALLOC_N(strbuf, strbuflen) < 0) { + virReportOOMError(); + return NULL; + } + + /* + * From the manpage (terrifying but true): + * + * ERRORS + * 0 or ENOENT or ESRCH or EBADF or EPERM or ... + * The given name or gid was not found. + */ + while ((rc = getgrgid_r(gid, &grbuf, strbuf, strbuflen, &gr)) == ERANGE) { + if (VIR_RESIZE_N(strbuf, strbuflen, strbuflen, strbuflen) < 0) { + virReportOOMError(); + VIR_FREE(strbuf); + return NULL; + } + } + if (rc != 0 || gr == NULL) { + virReportSystemError(rc, + _("Failed to find group record for gid '%u'"), + (unsigned int) gid); + VIR_FREE(strbuf); + return NULL; + } + + ret = strdup(gr->gr_name); + + VIR_FREE(strbuf); + if (!ret) + virReportOOMError(); + + return ret; +} + char *virGetUserDirectory(uid_t uid) { return virGetUserEnt(uid, VIR_USER_ENT_DIRECTORY); @@ -2197,6 +2247,11 @@ char *virGetUserName(uid_t uid) return virGetUserEnt(uid, VIR_USER_ENT_NAME); } +char *virGetGroupName(gid_t gid) +{ + return virGetGroupEnt(gid); +} + int virGetUserID(const char *name, uid_t *uid) diff --git a/src/util/util.h b/src/util/util.h index 977ab6cc64..a380144e53 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -236,6 +236,7 @@ int virKillProcess(pid_t pid, int sig); char *virGetUserDirectory(uid_t uid); char *virGetUserName(uid_t uid); +char *virGetGroupName(gid_t gid); int virGetUserID(const char *name, uid_t *uid) ATTRIBUTE_RETURN_CHECK; int virGetGroupID(const char *name,