A small followup with additional comments.

Justin Pryzby wrote:
[]
It seems that your request can be easily satisfied by using the
reentrant versions of these functions, like getpwnam_r.  I'm including
a test file I've been playing with, which indicates that a patch, if
necessary, would be unintrusive.

I said it's a PITA to get getpwnam_r() usage right. Here's why:

------------------------------------------------------------------------

#include <unistd.h>

#include <pwd.h>
#include <sys/types.h>

int main()
{
        struct passwd p,q;
        char *buf,*buf2;

        int buflen=sysconf(_SC_GETPW_R_SIZE_MAX);

        buf=(char *)malloc(buflen);
        buf2=(char *)malloc(buflen);

        struct passwd *v=malloc(sizeof (void *));

        //struct passwd *p=getpwnam("pryzbyj");
        getpwnam_r("pryzbyj", &p, buf, buflen, (struct passwd **)&v);

Here, we have to deal with errno = ERANGE. I re-read linux getpwnam_r() manpage - it changed since I last looked there. Now it says:

      The maximum needed size for buf can be found using sysconf(3) with  the
      _SC_GETPW_R_SIZE_MAX parameter.

(exactly the thing you did here).  Previously, preferred way
to call getpwnam_r was a loop like this (error checking omitted):

 int bufsize = _GETPWNAM_PREFERRED_BUFSIZE;
 char *buf = malloc(bufsize);

 while((err = getpwnam_r(name, pwent, buf, bufsize, &pwent)) == ERANGE) {
   bufsize *= 2;
   buf = realloc(buf, bufsize);
 }

(again, I don't remember how the constant "GETPWNAM_PREFERRED_BUFSIZE" was
named, it's a "suggested initial bufsize").

Here's what glibc.info says about getpwuid_r():

     If a user with ID UID is found, the pointer returned in RESULT
     points to the record which contains the wanted data (i.e., RESULT
     contains the value RESULT_BUF).  If no user is found or if an
     error occurred, the pointer returned in RESULT is a null pointer.
     The function returns zero or an error code.  If the buffer BUFFER
     is too small to contain all the needed information, the error code
     `ERANGE' is returned and ERRNO is set to `ERANGE'.

(no mention of that POSIX sysconf stuff).

Obviously, this "loop-way" is.. difficult and ugly.


And BTW, not all systems are using /etc/passwd. For other database implementations, things may be different.

/mjt


-- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]



Reply via email to