Subject: Re: nsswitch / nsdispatch(3) cleanup ...
To: None <tech-userlevel@NetBSD.org>
From: Luke Mewburn <lukem@NetBSD.org>
List: tech-userlevel
Date: 09/29/2004 09:26:28
--v6gilOcl2gU05R9Q
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Mon, Sep 27, 2004 at 07:31:58PM +1000, Luke Mewburn wrote:
  | To recap, an nsswitch method has the API:
  | 	typedef int (*nss_method)(void *retval, void *cb_data, va_list ap);
  | (See nsdispatch(3) for more details).
  |
  | We need to standardize the API used between the "standard"
  | functions and the nsswitch methods invoked via nsdispatch(3)
  | by those functions.

Based on a suggestion from from Brian Ginsbach, I've changed the
proposal to:

    1.	`void *retval' is a pointer for any "return" value that
	is not a formal part of the public API of the "stadard"
	function but needs to be provided back to the user,
	such as errno.
	For reentrant functions this may be needed to determine
	when ERANGE should be returned.

    2.	`va_list ap' has the same layout at the external function's
	calling convention, with the first argument being a pointer
	to the return value.
	This also has the benefit of providing type checking of
	the assignment of the variable containing the return value.

E.g, for
	int getgrgid_r(gid_t gid, struct group *grp,
	    char *buffer, size_t buflen, struct group **result)

the DNS method would start as:

	static int
	_nss_dns_getgrgid_r(void *nsrv, void *nscb, va_list ap)
	{
		int		*retval	= va_arg(ap, int *);
		gid_t		 gid	= va_arg(ap, gid_t);
		struct group	*grp	= va_arg(ap, struct group *);
		char		*buffer	= va_arg(ap, char *);
		size_t		 buflen	= va_arg(ap, size_t);
		struct group   **result	= va_arg(ap, struct group **);

		/* .... */
	}

This simplifies the work of an implementer of a third party
libnss_foo.so module because the API of the method's va_list
is directly derived from the API of standard function that
invokes it.

This suggestion does not enforce a particular naming convention
on the back-end method's function name for static methods,
although we should consider the ramifications of the namespace
of dynamic methods in libnss_foo.so.


lib/libc/gen/getgrouplist.c has been modified to use this
system, and I have a reworked getgrent.c (which includes
getgrgid_r() and getgrnam_r()) ready to commit.


Luke.

--v6gilOcl2gU05R9Q
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.6 (NetBSD)

iD8DBQFBWfMkpBhtmn8zJHIRAuhJAKCMkXAagBnvhW4Y6zk51YR8TQboywCggtPv
Bae0ZKi6rGWYfPoJvv7yv0M=
=sv1k
-----END PGP SIGNATURE-----

--v6gilOcl2gU05R9Q--