summaryrefslogtreecommitdiffstats
path: root/lib
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
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')
-rw-r--r--lib/libc/net/getproto.c32
-rw-r--r--lib/libc/net/getprotoent.c141
-rw-r--r--lib/libc/net/getprotoname.c37
-rw-r--r--lib/libc/net/netdb_private.h24
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_ */
OpenPOWER on IntegriCloud