[libvirt] [PATCH 3/4] Add virGetGroupName to convert from GID to group name

Daniel P. Berrange berrange at redhat.com
Thu Jan 19 13:51:21 UTC 2012


From: "Daniel P. Berrange" <berrange at 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




More information about the libvir-list mailing list