From: "Daniel P. Berrange" <berrange(a)redhat.com>
---
src/libvirt_private.syms | 1 +
src/util/util.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++
src/util/util.h | 1 +
3 files changed, 57 insertions(+), 0 deletions(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 0dfd4c1..8301c78 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 8663c4d..fdfceaa 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 977ab6c..a380144 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,
--
1.7.7.5