From b94c5ecf821db120dd4a81798257c68f3309c9a6 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Mon, 3 Nov 2014 15:21:06 +0100 Subject: NSDISPATCH(3): Add rtems_nss_register_module() --- freebsd/include/nsswitch.h | 18 ++++++++++++ freebsd/lib/libc/net/nsdispatch.c | 58 +++++++++++++++++++++++++++++++++++---- 2 files changed, 70 insertions(+), 6 deletions(-) diff --git a/freebsd/include/nsswitch.h b/freebsd/include/nsswitch.h index 112dff6d..771ccb6b 100644 --- a/freebsd/include/nsswitch.h +++ b/freebsd/include/nsswitch.h @@ -215,7 +215,9 @@ typedef struct _ns_mod { void *handle; /* handle from dlopen */ ns_mtab *mtab; /* method table */ unsigned int mtabsize; /* count of entries in method table */ +#ifndef __rtems__ nss_module_unregister_fn unregister; /* called to unload module */ +#endif /* __rtems__ */ } ns_mod; #endif /* _NS_PRIVATE */ @@ -238,6 +240,22 @@ extern int _nsyylineno; extern void _nsdbtdump(const ns_dbt *); #endif #endif /* _NS_PRIVATE */ +#ifdef __rtems__ +/** + * @brief Registers a name service module. + * + * @param[in] source The source identifier. + * @param[in] mtab The module table. This table will be claimed by the name + * service dispatcher. + * @param[in] mtabsize The module table entry count. + * + * @retval 0 Successful operation. + * @retval -1 An error occurred. The errno is set to indicate the error. + */ +int +rtems_nss_register_module(const char *source, ns_mtab *mtab, + unsigned int mtabsize); +#endif /* __rtems__ */ __END_DECLS diff --git a/freebsd/lib/libc/net/nsdispatch.c b/freebsd/lib/libc/net/nsdispatch.c index 87bd78ab..f1a88d8d 100644 --- a/freebsd/lib/libc/net/nsdispatch.c +++ b/freebsd/lib/libc/net/nsdispatch.c @@ -132,9 +132,11 @@ static ns_dbt *_nsmap = NULL; static unsigned int _nsmodsize; static ns_mod *_nsmod; +#ifndef __rtems__ /* Placeholder for builtin modules' dlopen `handle'. */ static int __nss_builtin_handle; static void *nss_builtin_handle = &__nss_builtin_handle; +#endif /* __rtems__ */ #ifdef NS_CACHING /* @@ -189,11 +191,15 @@ static int string_compare(const void *, const void *); static int mtab_compare(const void *, const void *); static int nss_configure(void); static void ns_dbt_free(ns_dbt *); +#ifndef __rtems__ static void ns_mod_free(ns_mod *); +#endif /* __rtems__ */ static void ns_src_free(ns_src **, int); +#ifndef __rtems__ static void nss_load_builtin_modules(void); static void nss_load_module(const char *, nss_module_register_fn); static void nss_atexit(void); +#endif /* __rtems__ */ /* nsparser */ extern FILE *_nsyyin; @@ -299,8 +305,12 @@ _nsdbtaddsrc(ns_dbt *dbt, const ns_src *src) sizeof(*src)); modp = vector_search(&src->name, _nsmod, _nsmodsize, sizeof(*_nsmod), string_compare); +#ifndef __rtems__ if (modp == NULL) nss_load_module(src->name, NULL); +#else /* __rtems__ */ + (void)modp; +#endif /* __rtems__ */ } @@ -379,14 +389,18 @@ nss_configure(void) goto fin; VECTOR_FREE(_nsmap, &_nsmapsize, sizeof(*_nsmap), (vector_free_elem)ns_dbt_free); +#ifndef __rtems__ VECTOR_FREE(_nsmod, &_nsmodsize, sizeof(*_nsmod), (vector_free_elem)ns_mod_free); nss_load_builtin_modules(); +#endif /* __rtems__ */ _nsyyparse(); (void)fclose(_nsyyin); vector_sort(_nsmap, _nsmapsize, sizeof(*_nsmap), string_compare); +#ifndef __rtems__ if (confmod == 0) (void)atexit(nss_atexit); +#endif /* __rtems__ */ confmod = statbuf.st_mtime; #ifdef NS_CACHING @@ -456,6 +470,7 @@ ns_src_free(ns_src **src, int srclistsize) +#ifndef __rtems__ /* * NSS module management. */ @@ -499,7 +514,6 @@ nss_load_module(const char *source, nss_module_register_fn reg_fn) fn = reg_fn; } else if (!is_dynamic()) goto fin; -#ifndef __rtems__ else { if (snprintf(buf, sizeof(buf), "nss_%s.so.%d", mod.name, NSS_MODULE_INTERFACE_VERSION) >= (int)sizeof(buf)) @@ -523,13 +537,10 @@ nss_load_module(const char *source, nss_module_register_fn reg_fn) goto fin; } } -#endif /* __rtems__ */ mod.mtab = fn(mod.name, &mod.mtabsize, &mod.unregister); if (mod.mtab == NULL || mod.mtabsize == 0) { -#ifndef __rtems__ if (mod.handle != nss_builtin_handle) (void)dlclose(mod.handle); -#endif /* __rtems__ */ mod.handle = NULL; nss_log(LOG_ERR, "%s, registration failed", mod.name); goto fin; @@ -553,10 +564,8 @@ ns_mod_free(ns_mod *mod) return; if (mod->unregister != NULL) mod->unregister(mod->mtab, mod->mtabsize); -#ifndef __rtems__ if (mod->handle != nss_builtin_handle) (void)dlclose(mod->handle); -#endif /* __rtems__ */ } @@ -579,6 +588,43 @@ nss_atexit(void) if (isthreaded) (void)_pthread_rwlock_unlock(&nss_lock); } +#else /* __rtems__ */ +int +rtems_nss_register_module(const char *source, ns_mtab *mtab, + unsigned int mtabsize) +{ + ns_mod mod; + int result; + + if (mtab == NULL || mtabsize == 0) { + errno = EINVAL; + return -1; + } + + memset(&mod, 0, sizeof(mod)); + mod.name = strdup(source); + if (mod.name == NULL) { + return -1; + } + mod.handle = (void *)1; + mod.mtab = mtab; + mod.mtabsize = mtabsize; + qsort(mod.mtab, mod.mtabsize, sizeof(mod.mtab[0]), mtab_compare); + + result = _pthread_rwlock_wrlock(&nss_lock); + if (result != 0) { + errno = result; + return -1; + } + + _nsmod = vector_append(&mod, _nsmod, &_nsmodsize, sizeof(*_nsmod)); + vector_sort(_nsmod, _nsmodsize, sizeof(*_nsmod), string_compare); + + (void)_pthread_rwlock_unlock(&nss_lock); + + return 0; +} +#endif /* __rtems__ */ -- cgit v1.2.3