summaryrefslogtreecommitdiff
path: root/libc/inet/getservice.c
diff options
context:
space:
mode:
Diffstat (limited to 'libc/inet/getservice.c')
-rw-r--r--libc/inet/getservice.c257
1 files changed, 143 insertions, 114 deletions
diff --git a/libc/inet/getservice.c b/libc/inet/getservice.c
index 0625a46e1..5e90f8198 100644
--- a/libc/inet/getservice.c
+++ b/libc/inet/getservice.c
@@ -53,6 +53,7 @@
#define __FORCE_GLIBC
+#define _GNU_SOURCE
#include <features.h>
#include <sys/types.h>
#include <sys/socket.h>
@@ -64,6 +65,21 @@
#include <arpa/inet.h>
#include <errno.h>
+
+
+#ifdef __UCLIBC_HAS_THREADS__
+#include <pthread.h>
+static pthread_mutex_t mylock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+# define LOCK pthread_mutex_lock(&mylock)
+# define UNLOCK pthread_mutex_unlock(&mylock);
+#else
+# define LOCK
+# define UNLOCK
+#endif
+
+
+
+
#define MAXALIASES 35
static FILE *servf = NULL;
@@ -73,156 +89,169 @@ static int serv_stayopen;
void setservent(int f)
{
- if (servf == NULL)
- servf = fopen(_PATH_SERVICES, "r" );
- else
- rewind(servf);
- serv_stayopen |= f;
+ LOCK;
+ if (servf == NULL)
+ servf = fopen(_PATH_SERVICES, "r" );
+ else
+ rewind(servf);
+ serv_stayopen |= f;
+ UNLOCK;
}
void endservent(void)
{
- if (servf) {
- fclose(servf);
- servf = NULL;
- }
- serv_stayopen = 0;
+ LOCK;
+ if (servf) {
+ fclose(servf);
+ servf = NULL;
+ }
+ serv_stayopen = 0;
+ UNLOCK;
}
struct servent * getservent(void)
{
- struct servent *result;
- getservent_r(&serv, buf, sizeof(buf), &result);
- return result;
+ struct servent *result;
+ getservent_r(&serv, buf, sizeof(buf), &result);
+ return result;
}
struct servent *getservbyname(const char *name, const char *proto)
{
- struct servent *result;
- getservbyname_r(name, proto, &serv, buf, sizeof(buf), &result);
- return result;
+ struct servent *result;
+ getservbyname_r(name, proto, &serv, buf, sizeof(buf), &result);
+ return result;
}
struct servent * getservbyport(int port, const char *proto)
{
- struct servent *result;
- getservbyport_r(port, proto, &serv, buf, sizeof(buf), &result);
- return result;
+ struct servent *result;
+ getservbyport_r(port, proto, &serv, buf, sizeof(buf), &result);
+ return result;
}
int getservent_r(struct servent * result_buf,
char * buf, size_t buflen,
struct servent ** result)
{
- char *p;
- register char *cp, **q;
- char **serv_aliases;
- char *line;
+ char *p;
+ register char *cp, **q;
+ char **serv_aliases;
+ char *line;
- *result=NULL;
+ *result=NULL;
- if (buflen < sizeof(*serv_aliases)*MAXALIASES) {
- errno=ERANGE;
- return errno;
- }
- serv_aliases=(char **)buf;
- buf+=sizeof(*serv_aliases)*MAXALIASES;
- buflen-=sizeof(*serv_aliases)*MAXALIASES;
-
- if (buflen < BUFSIZ+1) {
- errno=ERANGE;
- return errno;
- }
- line=buf;
- buf+=BUFSIZ+1;
- buflen-=BUFSIZ+1;
+ if (buflen < sizeof(*serv_aliases)*MAXALIASES) {
+ errno=ERANGE;
+ return errno;
+ }
+ LOCK;
+ serv_aliases=(char **)buf;
+ buf+=sizeof(*serv_aliases)*MAXALIASES;
+ buflen-=sizeof(*serv_aliases)*MAXALIASES;
+
+ if (buflen < BUFSIZ+1) {
+ UNLOCK;
+ errno=ERANGE;
+ return errno;
+ }
+ line=buf;
+ buf+=BUFSIZ+1;
+ buflen-=BUFSIZ+1;
- if (servf == NULL && (servf = fopen(_PATH_SERVICES, "r" )) == NULL)
- return errno;
+ if (servf == NULL && (servf = fopen(_PATH_SERVICES, "r" )) == NULL) {
+ UNLOCK;
+ return errno;
+ }
again:
- if ((p = fgets(line, BUFSIZ, servf)) == NULL)
- return TRY_AGAIN;
- if (*p == '#')
- goto again;
- cp = strpbrk(p, "#\n");
- if (cp == NULL)
- goto again;
- *cp = '\0';
- result_buf->s_name = p;
- p = strpbrk(p, " \t");
- if (p == NULL)
- goto again;
- *p++ = '\0';
- while (*p == ' ' || *p == '\t')
- p++;
- cp = strpbrk(p, ",/");
- if (cp == NULL)
- goto again;
+ if ((p = fgets(line, BUFSIZ, servf)) == NULL) {
+ UNLOCK;
+ return TRY_AGAIN;
+ }
+ if (*p == '#')
+ goto again;
+ cp = strpbrk(p, "#\n");
+ if (cp == NULL)
+ goto again;
+ *cp = '\0';
+ result_buf->s_name = p;
+ p = strpbrk(p, " \t");
+ if (p == NULL)
+ goto again;
+ *p++ = '\0';
+ while (*p == ' ' || *p == '\t')
+ p++;
+ cp = strpbrk(p, ",/");
+ if (cp == NULL)
+ goto again;
+ *cp++ = '\0';
+ result_buf->s_port = htons((u_short)atoi(p));
+ result_buf->s_proto = cp;
+ q = result_buf->s_aliases = serv_aliases;
+ cp = strpbrk(cp, " \t");
+ if (cp != NULL)
*cp++ = '\0';
- result_buf->s_port = htons((u_short)atoi(p));
- result_buf->s_proto = cp;
- q = result_buf->s_aliases = serv_aliases;
+ while (cp && *cp) {
+ if (*cp == ' ' || *cp == '\t') {
+ cp++;
+ continue;
+ }
+ if (q < &serv_aliases[MAXALIASES - 1])
+ *q++ = cp;
cp = strpbrk(cp, " \t");
if (cp != NULL)
- *cp++ = '\0';
- while (cp && *cp) {
- if (*cp == ' ' || *cp == '\t') {
- cp++;
- continue;
- }
- if (q < &serv_aliases[MAXALIASES - 1])
- *q++ = cp;
- cp = strpbrk(cp, " \t");
- if (cp != NULL)
- *cp++ = '\0';
- }
- *q = NULL;
- *result=result_buf;
- return 0;
+ *cp++ = '\0';
+ }
+ *q = NULL;
+ *result=result_buf;
+ UNLOCK;
+ return 0;
}
-int getservbyname_r(const char *name, const char *proto,
- struct servent * result_buf,
- char * buf, size_t buflen,
- struct servent ** result)
+int getservbyname_r(const char *name, const char *proto,
+ struct servent * result_buf, char * buf, size_t buflen,
+ struct servent ** result)
{
- register char **cp;
- int ret;
-
- setservent(serv_stayopen);
- while (!(ret=getservent_r(result_buf, buf, buflen, result))) {
- if (strcmp(name, result_buf->s_name) == 0)
- goto gotname;
- for (cp = result_buf->s_aliases; *cp; cp++)
- if (strcmp(name, *cp) == 0)
- goto gotname;
- continue;
+ register char **cp;
+ int ret;
+
+ LOCK;
+ setservent(serv_stayopen);
+ while (!(ret=getservent_r(result_buf, buf, buflen, result))) {
+ if (strcmp(name, result_buf->s_name) == 0)
+ goto gotname;
+ for (cp = result_buf->s_aliases; *cp; cp++)
+ if (strcmp(name, *cp) == 0)
+ goto gotname;
+ continue;
gotname:
- if (proto == 0 || strcmp(result_buf->s_proto, proto) == 0)
- break;
- }
- if (!serv_stayopen)
- endservent();
- return *result?0:ret;
+ if (proto == 0 || strcmp(result_buf->s_proto, proto) == 0)
+ break;
+ }
+ if (!serv_stayopen)
+ endservent();
+ UNLOCK;
+ return *result?0:ret;
}
-int getservbyport_r(int port, const char *proto,
- struct servent * result_buf,
- char * buf, size_t buflen,
- struct servent ** result)
+int getservbyport_r(int port, const char *proto,
+ struct servent * result_buf, char * buf,
+ size_t buflen, struct servent ** result)
{
- int ret;
-
- setservent(serv_stayopen);
- while (!(ret=getservent_r(result_buf, buf, buflen, result))) {
- if (result_buf->s_port != port)
- continue;
- if (proto == 0 || strcmp(result_buf->s_proto, proto) == 0)
- break;
- }
- if (!serv_stayopen)
- endservent();
- return *result?0:ret;
+ int ret;
+
+ LOCK;
+ setservent(serv_stayopen);
+ while (!(ret=getservent_r(result_buf, buf, buflen, result))) {
+ if (result_buf->s_port != port)
+ continue;
+ if (proto == 0 || strcmp(result_buf->s_proto, proto) == 0)
+ break;
+ }
+ if (!serv_stayopen)
+ endservent();
+ UNLOCK;
+ return *result?0:ret;
}