summaryrefslogtreecommitdiffstats
path: root/lib/libc/net/getprotoent.c
diff options
context:
space:
mode:
authorume <ume@FreeBSD.org>2005-04-19 14:41:13 +0000
committerume <ume@FreeBSD.org>2005-04-19 14:41:13 +0000
commit9af2b4271232977fe523e77ee8fd7b200a23e98f (patch)
tree0e2d39bbb214743f8707b7ef40ff135b1ee0fa32 /lib/libc/net/getprotoent.c
parent6c9d475a3bb8332173bada9cd081a2aa96c32b1a (diff)
downloadFreeBSD-src-9af2b4271232977fe523e77ee8fd7b200a23e98f.zip
FreeBSD-src-9af2b4271232977fe523e77ee8fd7b200a23e98f.tar.gz
- add getproto{byname,bynumber,ent}_r for internal use within libc.
- make getproto{byname,bynumber,ent} thread-safe.
Diffstat (limited to 'lib/libc/net/getprotoent.c')
-rw-r--r--lib/libc/net/getprotoent.c141
1 files changed, 112 insertions, 29 deletions
diff --git a/lib/libc/net/getprotoent.c b/lib/libc/net/getprotoent.c
index e2d7a97..037547b 100644
--- a/lib/libc/net/getprotoent.c
+++ b/lib/libc/net/getprotoent.c
@@ -43,53 +43,101 @@ __FBSDID("$FreeBSD$");
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include "namespace.h"
+#include "reentrant.h"
+#include "un-namespace.h"
+#include "netdb_private.h"
-#define MAXALIASES 35
+static struct protodata protodata;
+static thread_key_t protodata_key;
+static once_t protodata_init_once = ONCE_INITIALIZER;
+static int protodata_thr_keycreated = 0;
-static FILE *protof = NULL;
-static char line[BUFSIZ+1];
-static struct protoent proto;
-static char *proto_aliases[MAXALIASES];
-int _proto_stayopen;
+static void
+protoent_data_clear(struct protoent_data *ped)
+{
+ if (ped->fp) {
+ fclose(ped->fp);
+ ped->fp = NULL;
+ }
+}
+
+static void
+protodata_free(void *ptr)
+{
+ struct protodata *pd = ptr;
+
+ if (pd == NULL)
+ return;
+ protoent_data_clear(&pd->data);
+ free(pd);
+}
+
+static void
+protodata_keycreate(void)
+{
+ protodata_thr_keycreated =
+ (thr_keycreate(&protodata_key, protodata_free) == 0);
+}
+
+struct protodata *
+__protodata_init(void)
+{
+ struct protodata *pd;
+
+ if (thr_main() != 0)
+ return (&protodata);
+ if (thr_once(&protodata_init_once, protodata_keycreate) != 0 ||
+ !protodata_thr_keycreated)
+ return (NULL);
+ if ((pd = thr_getspecific(protodata_key)) != NULL)
+ return (pd);
+ if ((pd = calloc(1, sizeof(*pd))) == NULL)
+ return (NULL);
+ if (thr_setspecific(protodata_key, pd) == 0)
+ return (pd);
+ free(pd);
+ return (NULL);
+}
void
-setprotoent(f)
- int f;
+setprotoent_r(int f, struct protoent_data *ped)
{
- if (protof == NULL)
- protof = fopen(_PATH_PROTOCOLS, "r" );
+ if (ped->fp == NULL)
+ ped->fp = fopen(_PATH_PROTOCOLS, "r");
else
- rewind(protof);
- _proto_stayopen |= f;
+ rewind(ped->fp);
+ ped->stayopen |= f;
}
void
-endprotoent()
+endprotoent_r(struct protoent_data *ped)
{
- if (protof) {
- fclose(protof);
- protof = NULL;
+ if (ped->fp) {
+ fclose(ped->fp);
+ ped->fp = NULL;
}
- _proto_stayopen = 0;
+ ped->stayopen = 0;
}
-struct protoent *
-getprotoent()
+int
+getprotoent_r(struct protoent *pe, struct protoent_data *ped)
{
char *p;
- char *cp, **q;
+ char *cp, **q, *endp;
+ long l;
- if (protof == NULL && (protof = fopen(_PATH_PROTOCOLS, "r" )) == NULL)
- return (NULL);
+ if (ped->fp == NULL && (ped->fp = fopen(_PATH_PROTOCOLS, "r")) == NULL)
+ return (-1);
again:
- if ((p = fgets(line, BUFSIZ, protof)) == NULL)
- return (NULL);
+ if ((p = fgets(ped->line, BUFSIZ, ped->fp)) == NULL)
+ return (-1);
if (*p == '#')
goto again;
cp = strpbrk(p, "#\n");
if (cp != NULL)
*cp = '\0';
- proto.p_name = p;
+ pe->p_name = p;
cp = strpbrk(p, " \t");
if (cp == NULL)
goto again;
@@ -99,8 +147,11 @@ again:
p = strpbrk(cp, " \t");
if (p != NULL)
*p++ = '\0';
- proto.p_proto = atoi(cp);
- q = proto.p_aliases = proto_aliases;
+ l = strtol(cp, &endp, 10);
+ if (endp == cp || *endp != '\0' || l < 0 || l > USHRT_MAX)
+ goto again;
+ pe->p_proto = l;
+ q = pe->p_aliases = ped->aliases;
if (p != NULL) {
cp = p;
while (cp && *cp) {
@@ -108,7 +159,7 @@ again:
cp++;
continue;
}
- if (q < &proto_aliases[MAXALIASES - 1])
+ if (q < &ped->aliases[PROTOENT_MAXALIASES - 1])
*q++ = cp;
cp = strpbrk(cp, " \t");
if (cp != NULL)
@@ -116,5 +167,37 @@ again:
}
}
*q = NULL;
- return (&proto);
+ return (0);
+}
+
+void
+setprotoent(int f)
+{
+ struct protodata *pd;
+
+ if ((pd = __protodata_init()) == NULL)
+ return;
+ setprotoent_r(f, &pd->data);
+}
+
+void
+endprotoent(void)
+{
+ struct protodata *pd;
+
+ if ((pd = __protodata_init()) == NULL)
+ return;
+ endprotoent_r(&pd->data);
+}
+
+struct protoent *
+getprotoent(void)
+{
+ struct protodata *pd;
+
+ if ((pd = __protodata_init()) == NULL)
+ return (NULL);
+ if (getprotoent_r(&pd->proto, &pd->data) != 0)
+ return (NULL);
+ return (&pd->proto);
}
OpenPOWER on IntegriCloud