From 9af2b4271232977fe523e77ee8fd7b200a23e98f Mon Sep 17 00:00:00 2001 From: ume Date: Tue, 19 Apr 2005 14:41:13 +0000 Subject: - add getproto{byname,bynumber,ent}_r for internal use within libc. - make getproto{byname,bynumber,ent} thread-safe. --- lib/libc/net/getprotoent.c | 141 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 112 insertions(+), 29 deletions(-) (limited to 'lib/libc/net/getprotoent.c') 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 #include #include +#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); } -- cgit v1.1