From eae90a29f226809527585d7ba688d0af8627db58 Mon Sep 17 00:00:00 2001 From: millert <> Date: Sun, 17 Oct 2004 20:24:23 +0000 Subject: Reentrant versions of getprotoent(3) and getservent(3). Adapted from changes in NetBSD by Christos. OK otto@ --- src/lib/libc/net/getservent.c | 122 ++++++++++++++++++++++++++++-------------- 1 file changed, 83 insertions(+), 39 deletions(-) (limited to 'src/lib/libc/net/getservent.c') diff --git a/src/lib/libc/net/getservent.c b/src/lib/libc/net/getservent.c index 475e25a1f8..9cf53774d6 100644 --- a/src/lib/libc/net/getservent.c +++ b/src/lib/libc/net/getservent.c @@ -28,68 +28,68 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: getservent.c,v 1.7 2004/09/16 03:13:22 deraadt Exp $"; +static char rcsid[] = "$OpenBSD: getservent.c,v 1.8 2004/10/17 20:24:23 millert Exp $"; #endif /* LIBC_SCCS and not lint */ #include #include + +#include #include #include #include #include -#define MAXALIASES 35 - -static FILE *servf = NULL; -static char line[BUFSIZ+1]; -static struct servent serv; -static char *serv_aliases[MAXALIASES]; -int _serv_stayopen; - void -setservent(int f) +setservent_r(int f, struct servent_data *sd) { - if (servf == NULL) - servf = fopen(_PATH_SERVICES, "r" ); + if (sd->fp == NULL) + sd->fp = fopen(_PATH_SERVICES, "r" ); else - rewind(servf); - _serv_stayopen |= f; + rewind(sd->fp); + sd->stayopen |= f; } void -endservent(void) +endservent_r(struct servent_data *sd) { - if (servf) { - fclose(servf); - servf = NULL; + if (sd->fp) { + fclose(sd->fp); + sd->fp = NULL; } - _serv_stayopen = 0; + free(sd->aliases); + sd->aliases = NULL; + sd->maxaliases = 0; + free(sd->line); + sd->line = NULL; + sd->stayopen = 0; } struct servent * -getservent(void) +getservent_r(struct servent *se, struct servent_data *sd) { char *p, *cp, **q, *endp; - long l; size_t len; + long l; + int serrno; - if (servf == NULL && (servf = fopen(_PATH_SERVICES, "r" )) == NULL) + if (sd->fp == NULL && (sd->fp = fopen(_PATH_SERVICES, "r" )) == NULL) return (NULL); again: - if ((p = fgetln(servf, &len)) == NULL) + if ((p = fgetln(sd->fp, &len)) == NULL) return (NULL); + if (len == 0 || *p == '#' || *p == '\n') + goto again; if (p[len-1] == '\n') len--; - if (len >= sizeof(line) || len == 0) - goto again; - p = memcpy(line, p, len); - line[len] = '\0'; - if (*p == '#') - goto again; - if ((cp = strchr(p, '#')) != NULL) - *cp = '\0'; - serv.s_name = p; - p = strpbrk(p, " \t"); + if ((cp = memchr(p, '#', len)) != NULL) + len = cp - p; + cp = realloc(sd->line, len + 1); + if (cp == NULL) + return (NULL); + sd->line = se->s_name = memcpy(cp, p, len); + cp[len] = '\0'; + p = strpbrk(cp, " \t"); if (p == NULL) goto again; *p++ = '\0'; @@ -102,9 +102,19 @@ again: l = strtol(p, &endp, 10); if (endp == p || *endp != '\0' || l < 0 || l > USHRT_MAX) goto again; - serv.s_port = htons((in_port_t)l); - serv.s_proto = cp; - q = serv.s_aliases = serv_aliases; + se->s_port = htons((in_port_t)l); + se->s_proto = cp; + if (sd->aliases == NULL) { + sd->maxaliases = 10; + sd->aliases = malloc(sd->maxaliases * sizeof(char *)); + if (sd->aliases == NULL) { + serrno = errno; + endservent_r(sd); + errno = serrno; + return (NULL); + } + } + q = se->s_aliases = sd->aliases; cp = strpbrk(cp, " \t"); if (cp != NULL) *cp++ = '\0'; @@ -113,12 +123,46 @@ again: cp++; continue; } - if (q < &serv_aliases[MAXALIASES - 1]) - *q++ = cp; + if (q == &se->s_aliases[sd->maxaliases - 1]) { + p = realloc(se->s_aliases, + 2 * sd->maxaliases * sizeof(char *)); + if (p == NULL) { + serrno = errno; + endservent_r(sd); + errno = serrno; + return (NULL); + } + sd->maxaliases *= 2; + q = (char **)p + (q - se->s_aliases); + se->s_aliases = sd->aliases = (char **)p; + } + *q++ = cp; cp = strpbrk(cp, " \t"); if (cp != NULL) *cp++ = '\0'; } *q = NULL; - return (&serv); + return (se); +} + +struct servent_data _servent_data; /* shared with getservby{name,port}.c */ + +void +setservent(int f) +{ + setservent_r(f, &_servent_data); +} + +void +endservent(void) +{ + endservent_r(&_servent_data); +} + +struct servent * +getservent(void) +{ + static struct servent serv; + + return getservent_r(&serv, &_servent_data); } -- cgit v1.2.3-55-g6feb