NSDISPATCH(3): Add rtems_nss_register_module()

This commit is contained in:
Sebastian Huber 2014-11-03 15:21:06 +01:00
parent f90fdf3b68
commit b94c5ecf82
2 changed files with 70 additions and 6 deletions

View File

@ -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

View File

@ -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__ */