diff options
author | ume <ume@FreeBSD.org> | 2005-04-19 14:41:13 +0000 |
---|---|---|
committer | ume <ume@FreeBSD.org> | 2005-04-19 14:41:13 +0000 |
commit | 9af2b4271232977fe523e77ee8fd7b200a23e98f (patch) | |
tree | 0e2d39bbb214743f8707b7ef40ff135b1ee0fa32 /lib | |
parent | 6c9d475a3bb8332173bada9cd081a2aa96c32b1a (diff) | |
download | FreeBSD-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')
-rw-r--r-- | lib/libc/net/getproto.c | 32 | ||||
-rw-r--r-- | lib/libc/net/getprotoent.c | 141 | ||||
-rw-r--r-- | lib/libc/net/getprotoname.c | 37 | ||||
-rw-r--r-- | lib/libc/net/netdb_private.h | 24 |
4 files changed, 181 insertions, 53 deletions
diff --git a/lib/libc/net/getproto.c b/lib/libc/net/getproto.c index b22bc51..400fa7c 100644 --- a/lib/libc/net/getproto.c +++ b/lib/libc/net/getproto.c @@ -38,20 +38,30 @@ static char sccsid[] = "@(#)getproto.c 8.1 (Berkeley) 6/4/93"; __FBSDID("$FreeBSD$"); #include <netdb.h> +#include "netdb_private.h" -extern int _proto_stayopen; +int +getprotobynumber_r(int proto, struct protoent *pe, struct protoent_data *ped) +{ + int error; + + setprotoent_r(ped->stayopen, ped); + while ((error = getprotoent_r(pe, ped)) == 0) + if (pe->p_proto == proto) + break; + if (!ped->stayopen) + endprotoent_r(ped); + return (error); +} struct protoent * -getprotobynumber(proto) - int proto; +getprotobynumber(int proto) { - struct protoent *p; + struct protodata *pd; - setprotoent(_proto_stayopen); - while ( (p = getprotoent()) ) - if (p->p_proto == proto) - break; - if (!_proto_stayopen) - endprotoent(); - return (p); + if ((pd = __protodata_init()) == NULL) + return (NULL); + if (getprotobynumber_r(proto, &pd->proto, &pd->data) != 0) + return (NULL); + return (&pd->proto); } 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); } diff --git a/lib/libc/net/getprotoname.c b/lib/libc/net/getprotoname.c index 7039b0a..99232a2 100644 --- a/lib/libc/net/getprotoname.c +++ b/lib/libc/net/getprotoname.c @@ -39,26 +39,37 @@ __FBSDID("$FreeBSD$"); #include <netdb.h> #include <string.h> +#include "netdb_private.h" -extern int _proto_stayopen; - -struct protoent * -getprotobyname(name) - const char *name; +int +getprotobyname_r(const char *name, struct protoent *pe, + struct protoent_data *ped) { - struct protoent *p; char **cp; + int error; - setprotoent(_proto_stayopen); - while ( (p = getprotoent()) ) { - if (strcmp(p->p_name, name) == 0) + setprotoent_r(ped->stayopen, ped); + while ((error = getprotoent_r(pe, ped)) == 0) { + if (strcmp(pe->p_name, name) == 0) break; - for (cp = p->p_aliases; *cp != 0; cp++) + for (cp = pe->p_aliases; *cp != 0; cp++) if (strcmp(*cp, name) == 0) goto found; } found: - if (!_proto_stayopen) - endprotoent(); - return (p); + if (!ped->stayopen) + endprotoent_r(ped); + return (error); +} + +struct protoent * +getprotobyname(const char *name) +{ + struct protodata *pd; + + if ((pd = __protodata_init()) == NULL) + return (NULL); + if (getprotobyname_r(name, &pd->proto, &pd->data) != 0) + return (NULL); + return (&pd->proto); } diff --git a/lib/libc/net/netdb_private.h b/lib/libc/net/netdb_private.h index a7cd4c9..b932620 100644 --- a/lib/libc/net/netdb_private.h +++ b/lib/libc/net/netdb_private.h @@ -30,8 +30,21 @@ #include <stdio.h> /* XXX: for BUFSIZ */ +#define PROTOENT_MAXALIASES 35 #define SERVENT_MAXALIASES 35 +struct protoent_data { + FILE *fp; + char *aliases[PROTOENT_MAXALIASES]; + int stayopen; + char line[BUFSIZ + 1]; +}; + +struct protodata { + struct protoent proto; + struct protoent_data data; +}; + struct servent_data { FILE *fp; char *aliases[SERVENT_MAXALIASES]; @@ -53,19 +66,30 @@ struct servdata { struct servent_data data; }; +#define endprotoent_r __endprotoent_r #define endservent_r __endservent_r +#define getprotobyname_r __getprotobyname_r +#define getprotobynumber_r __getprotobynumber_r +#define getprotoent_r __getprotoent_r #define getservbyname_r __getservbyname_r #define getservbyport_r __getservbyport_r #define getservent_r __getservent_r +#define setprotoent_r __setprotoent_r #define setservent_r __setservent_r +struct protodata *__protodata_init(void); struct servdata *__servdata_init(void); +void endprotoent_r(struct protoent_data *); void endservent_r(struct servent_data *); +int getprotobyname_r(const char *, struct protoent *, struct protoent_data *); +int getprotobynumber_r(int, struct protoent *, struct protoent_data *); +int getprotoent_r(struct protoent *, struct protoent_data *); int getservbyname_r(const char *, const char *, struct servent *, struct servent_data *); int getservbyport_r(int, const char *, struct servent *, struct servent_data *); int getservent_r(struct servent *, struct servent_data *); +void setprotoent_r(int, struct protoent_data *); void setservent_r(int, struct servent_data *); #endif /* _NETDB_PRIVATE_H_ */ |