This is the mail archive of the libc-alpha@sourceware.org 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 10:08 AM, Florian Weimer wrote:
> On 08/04/2017 03:52 PM, Carlos O'Donell wrote:
>> The level of the *_r functions is nss/getXXbyYY_r.c, and I don't see why
>> we could not intelligently save and restore errno at that level?
>>
>> Given your example it would look like this, and some of this is defensive
>> errno saving because we are going to have flawed service modules that
>> set errno explicitly.
>>
>> 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.
>> * Since ERANGE we flag that error has occured
>> * if (errno == 0) then restore errno.
> 
> How would you pass ERANGE to the caller?
> 
> For getpwnam, the sequence could be:
> 
>   Call getpwnam_r.
>   Get back ERANGE error.
>   Allocate larger buffer.
>   Call getpwnam_r again.
>   Get back result.
>   Return to caller with success.
> 
> If the second getpwnam_r saved and restored errno, we'll return ERANGE
> (or whatever malloc set) to the caller, not the original errno value.

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


-- 
Cheers,
Carlos.


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