summaryrefslogtreecommitdiffstats
path: root/lib/libc/net/getnetnamadr.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc/net/getnetnamadr.c')
-rw-r--r--lib/libc/net/getnetnamadr.c133
1 files changed, 107 insertions, 26 deletions
diff --git a/lib/libc/net/getnetnamadr.c b/lib/libc/net/getnetnamadr.c
index eec3d9a..7b8aaa6 100644
--- a/lib/libc/net/getnetnamadr.c
+++ b/lib/libc/net/getnetnamadr.c
@@ -27,6 +27,7 @@
__FBSDID("$FreeBSD$");
#include "namespace.h"
+#include "reentrant.h"
#include <sys/param.h>
#include <sys/socket.h>
#include <netinet/in.h>
@@ -34,6 +35,7 @@ __FBSDID("$FreeBSD$");
#include <netdb.h>
#include <stdio.h>
#include <ctype.h>
+#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <nsswitch.h>
@@ -54,10 +56,53 @@ static const ns_src default_src[] = {
{ 0 }
};
-struct netent *
-getnetbyname(const char *name)
+static struct netdata netdata;
+static thread_key_t netdata_key;
+static once_t netdata_init_once = ONCE_INITIALIZER;
+static int netdata_thr_keycreated = 0;
+
+static void
+netdata_free(void *ptr)
+{
+ struct netdata *nd = ptr;
+
+ if (nd == NULL)
+ return;
+ nd->data.stayopen = 0;
+ _endnethtent(&nd->data);
+ free(nd);
+}
+
+static void
+netdata_keycreate(void)
+{
+ netdata_thr_keycreated =
+ (thr_keycreate(&netdata_key, netdata_free) == 0);
+}
+
+struct netdata *
+__netdata_init(void)
+{
+ struct netdata *nd;
+
+ if (thr_main() != 0)
+ return &netdata;
+ if (thr_once(&netdata_init_once, netdata_keycreate) != 0 ||
+ !netdata_thr_keycreated)
+ return NULL;
+ if ((nd = thr_getspecific(netdata_key)) != NULL)
+ return nd;
+ if ((nd = calloc(1, sizeof(*nd))) == NULL)
+ return NULL;
+ if (thr_setspecific(netdata_key, nd) == 0)
+ return nd;
+ free(nd);
+ return NULL;
+}
+
+int
+getnetbyname_r(const char *name, struct netent *ne, struct netent_data *ned)
{
- struct netent *hp = 0;
int rval;
@@ -66,21 +111,17 @@ getnetbyname(const char *name)
{ NSSRC_DNS, _dns_getnetbyname, NULL },
NS_NIS_CB(_nis_getnetbyname, NULL) /* force -DHESIOD */
{ 0 }
- };
-
- rval = _nsdispatch((void *)&hp, dtab, NSDB_NETWORKS, "getnetbyname",
- default_src, name);
+ };
- if (rval != NS_SUCCESS)
- return NULL;
- else
- return hp;
+ rval = _nsdispatch(NULL, dtab, NSDB_NETWORKS, "getnetbyname",
+ default_src, name, ne, ned);
+
+ return (rval == NS_SUCCESS) ? 0 : -1;
}
-struct netent *
-getnetbyaddr(u_long addr, int af)
+int
+getnetbyaddr_r(u_long addr, int af, struct netent *ne, struct netent_data *ned)
{
- struct netent *hp = 0;
int rval;
static const ns_dtab dtab[] = {
@@ -88,28 +129,68 @@ getnetbyaddr(u_long addr, int af)
{ NSSRC_DNS, _dns_getnetbyaddr, NULL },
NS_NIS_CB(_nis_getnetbyaddr, NULL) /* force -DHESIOD */
{ 0 }
- };
+ };
- rval = _nsdispatch((void *)&hp, dtab, NSDB_NETWORKS, "getnetbyaddr",
- default_src, addr, af);
+ rval = _nsdispatch(NULL, dtab, NSDB_NETWORKS, "getnetbyaddr",
+ default_src, addr, af, ne, ned);
- if (rval != NS_SUCCESS)
- return NULL;
- else
- return hp;
+ return (rval == NS_SUCCESS) ? 0 : -1;
}
void
-setnetent(stayopen)
- int stayopen;
+setnetent_r(int stayopen, struct netent_data *ned)
{
- _setnethtent(stayopen);
+ _setnethtent(stayopen, ned);
_setnetdnsent(stayopen);
}
void
-endnetent()
+endnetent_r(struct netent_data *ned)
{
- _endnethtent();
+ _endnethtent(ned);
_endnetdnsent();
}
+
+struct netent *
+getnetbyname(const char *name)
+{
+ struct netdata *nd;
+
+ if ((nd = __netdata_init()) == NULL)
+ return NULL;
+ if (getnetbyname_r(name, &nd->net, &nd->data) != 0)
+ return NULL;
+ return &nd->net;
+}
+
+struct netent *
+getnetbyaddr(u_long addr, int af)
+{
+ struct netdata *nd;
+
+ if ((nd = __netdata_init()) == NULL)
+ return NULL;
+ if (getnetbyaddr_r(addr, af, &nd->net, &nd->data) != 0)
+ return NULL;
+ return &nd->net;
+}
+
+void
+setnetent(int stayopen)
+{
+ struct netdata *nd;
+
+ if ((nd = __netdata_init()) == NULL)
+ return;
+ setnetent_r(stayopen, &nd->data);
+}
+
+void
+endnetent(void)
+{
+ struct netdata *nd;
+
+ if ((nd = __netdata_init()) == NULL)
+ return;
+ endnetent_r(&nd->data);
+}
OpenPOWER on IntegriCloud