map_uid_to_username() proposal

Robert P. J. Day rpjday at mindspring.com
Thu Apr 20 20:50:14 UTC 2006


On Thu, 20 Apr 2006, Tito wrote:

> On Thursday 20 April 2006 22:13, Robert P. J. Day wrote:
> >
> >   what about something like this?
> >
> > ===========================================================
> #include <stdio.h>
> #include <sys/types.h>
> #include <pwd.h>
> #include <stdlib.h>
>
> char*
> map_uid_to_username(uid_t uid)
> {
> 	static struct passwd *pptr ;
>  	struct passwd *res ;
>  	char buf[100] ;
>  	int ret ;
>
>  	if (pptr == NULL) {
>  		pptr = malloc(sizeof(struct passwd)) ;
>  	}
>
>  	ret = getpwuid_r(uid, pptr, buf, 100, &res) ;
>
>  	if (res != NULL) {
>  		return res->pw_name ;
>  	} else {
> +		bb_error_msg("uknown uid %d", uid);
> 		return NULL ;
>  	}
>  }
>  =============================================================
> >
> >   note the features of map_uid_to_username():
> >
> > 1) it is obviously a single point of entry so you pay for the size
> >    of that function only once.
> >
> > 2) it will never allocate space for the necessary data structures
> >    until it's called the first time.  (you can allocate buf the
> >    same way, of course.  in fact, you probably should.)
> >
> > 3) there is no possibility of a memory leak no matter how many
> >    times you call it (unless the actual library routines are
> >    screwed)
> >
> > 4) it has just the right semantics
> >
> >   thoughts?  it seems to work here.
>
> I fear that the missing functionality even if the code is cleaner
> will increase bb's size a lot.
>
>   * if bufsize is > 0 char *name can not be set to NULL.
>   *                   On success username is written on the static allocated
>   *                   buffer name (and a pointer to it is returned).
>   *                   On failure uid as string is written to the static <=
>   *                   allocated buffer name and NULL is returned. <=
>   * if bufsize is = 0 char *name can be set to NULL.
>   *                   On success username is returned.
>   *                   On failure NULL is returned.
>   * if bufsize is < 0 char *name can be set to NULL
>   *                   On success username is returned.
>   *                   On failure an error message is printed and
>   *                   the program exits.  <=
>
> Please try to actually substitute it in the code.

hang on, let me clarify something here.  the reason that function is a
little complicated is that it's designed to avoid any possible memory
leak, no matter how many times it's called, so if you *want* that
feature, you obviously have to pay for it with a little more size.

it's possible that the regular getpwuid() routine will reuse the same
structure space, so if that's true, then we can just fall back and use
that instead.  or, if you don't care about memory leaks, just call
getpwuid() no matter what.

in terms of size, i can measure the size of the code but make sure you
notice that that routine isn't using a whole lot more dynamic storage
than what you're going to use anyway.  regardless of how you implement
this, *somebody* is going to be allocating space for a struct passwd
and for the resulting strings.

i'll do some size measurements right away but, as i said, if you want
the convenience of a wrapper function with intuitive semantics, you're
going to have to pay for it *somehow*.  the only question is, how much
are you willing to pay?

rday

p.s.  can anyone verify whether getpwuid() will reuse the same static
space, or whether we even care and are willing to leave with a
potential memory leak there?



More information about the busybox mailing list