This is the mail archive of the mailing list for the glibc project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: NSS error reporting (bug 20532)

On 08/04/2017 04:38 PM, Carlos O'Donell wrote:
> We stop setting errno in nss/getXXbyYY_r.c, because none of the reentrant
> versions are supposed to set errno, they are supposed to return the error
> as their result. This might not work easily if other more complex APIs use
> the *_r versions and need errno set.
> nss/getXXbyYY_r.c
> * save errno.
> * set errno to zero
> * resolve service to nss_files
> * call nss_files low-level functions: e.g. _nss_files_getpwnam_r (nss_files/files-pwd.c)
>   ... and get back NSS_STATUS_TRYAGAIN/ERANGE.
> * save result.
> * restore errno.
> * return result.
> nss/getXXbyYY.c
> * call reentrant version
> * save result
> * if (result == ERANGE) then try again with larger buffer.
>   Note: errno remains 0 the whole time (except within the *_r function impl)
> * if result != 0 then errno = result

I'm afraid this is not possible.  A pre-POSIX version of getpwnam_r set
errno and returned a flag (just like most non-pthread functions).  Here
is an excerpt from nscd:

static int
lookup (int type, union keytype key, struct passwd *resultbufp, char
	size_t buflen, struct passwd **pwd)
  if (type == GETPWBYNAME)
    return __getpwnam_r (key.v, resultbufp, buffer, buflen, pwd);
    return __getpwuid_r (key.u, resultbufp, buffer, buflen, pwd);


  while (lookup (req->type, key, &resultbuf, buffer, buflen, &pwd) != 0
	 && (errval = errno) == ERANGE)

Here is another excerpt from glob:

	  while (getpwnam_r (name, &pwbuf, pwtmpbuf, pwbuflen, &p)
		 != 0)
	      if (errno != ERANGE)
		  p = NULL;

wordexp has the same issue:

 while ((result = __getpwnam_r (user, &pwd, buffer, buflen, &tpwd)) != 0
        && errno == ERANGE)

Here's an example from OpenJDK:

        errno = 0;
        #ifdef __solaris__
            RESTARTABLE_RETURN_PTR(getgrgid_r((gid_t)gid, &grent, grbuf,
(size_t)buflen), g);
            RESTARTABLE(getgrgid_r((gid_t)gid, &grent, grbuf,
(size_t)buflen, &g), res);

        retry = 0;
        if (res != 0 || g == NULL || g->gr_name == NULL || *(g->gr_name)
== '\0') {
            /* not found or error */
            if (errno == ERANGE) {

In short, if we made this change, way too much code would break.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]