summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2014-11-03 15:21:06 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2014-11-04 13:02:55 +0100
commitb94c5ecf821db120dd4a81798257c68f3309c9a6 (patch)
tree42bae62f727cc90bb4e4655566927f33579c8a8d
parentNSDISPATCH(3): Fix warning (diff)
downloadrtems-libbsd-b94c5ecf821db120dd4a81798257c68f3309c9a6.tar.bz2
NSDISPATCH(3): Add rtems_nss_register_module()
-rw-r--r--freebsd/include/nsswitch.h18
-rw-r--r--freebsd/lib/libc/net/nsdispatch.c58
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__ */