On Thu, Jan 22, 2009 at 10:48:59AM +0000, Daniel P. Berrange wrote:
On Fri, Jan 16, 2009 at 12:25:02PM +0000, Daniel P. Berrange wrote:
> On Fri, Jan 16, 2009 at 12:21:59PM +0000, Richard W.M. Jones wrote:
> > On Tue, Jan 13, 2009 at 05:46:37PM +0000, Daniel P. Berrange wrote:
> > > + char buf[1024];
> >
> > sysconf (_SC_GETPW_R_SIZE_MAX)?
> >
> > Looking at glibc's implementation of getpwuid (which uses getpwuid_r),
> > I see that glibc dynamically reallocates the buffer as necessary to
> > the correct size for the return value. The logic of this is fairly
> > simple so maybe we should do the same?
> >
> > From glibc:
> >
> > buffer = malloc (/*some_initial_size*/);
> >
> > while (buffer != NULL
> > && (getpwuid_r (const char *name, &resbuf, buffer,
> > buffer_size, &result)
> > == ERANGE))
> > {
> > char *new_buf;
> > buffer_size *= 2;
> > new_buf = (char *) realloc (buffer, buffer_size);
> > if (new_buf == NULL)
> > {
> > free (buffer);
> > errno = ENOMEM;
> > }
> > buffer = new_buf;
> > }
> >
> >
> > Anyhow, +1 but I'd be happier if these functions were centralized in
> > somewhere like src/utils.c.
>
> That's a good idea - in all the cases where we currently use getpwuid
> all we actually want is the home directory path. So we could add a
> simple func:
>
> char *virUserHomeDirectory(uid_t uid);
>
> and hide all the horrific code in there.
Here's an update with that usage in it
diff --git a/src/util.c b/src/util.c
--- a/src/util.c
+++ b/src/util.c
@@ -49,6 +49,9 @@
#include <paths.h>
#endif
#include <netdb.h>
+#ifdef HAVE_GETPWUID_R
+#include <pwd.h>
+#endif
#include "virterror_internal.h"
#include "logging.h"
@@ -1431,3 +1434,37 @@ int virKillProcess(pid_t pid, int sig)
return kill(pid, sig);
#endif
}
+
+
+#ifdef HAVE_GETPWUID_R
+char *virGetUserDirectory(virConnectPtr conn,
+ uid_t uid)
+{
+ char *strbuf;
+ char *ret;
+ struct passwd pwbuf;
+ struct passwd *pw;
+ size_t strbuflen = sysconf(_SC_GETPW_R_SIZE_MAX);
+
+ if (VIR_ALLOC_N(strbuf, strbuflen) < 0) {
+ virReportOOMError(conn);
+ return NULL;
+ }
+
+ if (getpwuid_r(uid, &pwbuf, strbuf, strbuflen, &pw) != 0) {
+ virReportSystemError(conn, errno,
+ _("Failed to find user record for uid
'%d'"),
+ uid);
+ VIR_FREE(strbuf);
+ return NULL;
+ }
+
+ ret = strdup(pw->pw_dir);
+
+ VIR_FREE(strbuf);
+ if (!ret)
+ virReportOOMError(conn);
+
+ return NULL;
+}
+#endif
Delibrate mistake here :-)
s/return NULL/return ret/
Otherwise it always returns NULL :-)
Daniel
--
|: Red Hat, Engineering, London -o-
http://people.redhat.com/berrange/ :|
|:
http://libvirt.org -o-
http://virt-manager.org -o-
http://ovirt.org :|
|:
http://autobuild.org -o-
http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|