Reentrant versions of get{prt,srv}name (XCC)
authorBarret Rhoden <brho@cs.berkeley.edu>
Fri, 5 Jun 2015 20:10:04 +0000 (16:10 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Fri, 12 Jun 2015 16:03:18 +0000 (12:03 -0400)
Similar to the gethostbyname* versions.  They each have slight differences.
The get-service-by-protocol uses srvbynm under the hood, since it's all the
same to CS.

As with gethostbyname*, these haven't been tested and may have the same old
bugs from the original plan 9 shims.

Rebuild glibc.

tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/getprtname.c
tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/getprtname_r.c
tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/getsrvbynm.c
tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/getsrvbynm_r.c
tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/getsrvbypt_r.c

index d0e58e6..6bffc2c 100644 (file)
@@ -1,94 +1,20 @@
-/* 
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-/* posix */
-#include <sys/types.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <string.h>
-#include <errno.h>
-
-/* bsd extensions */
-#include <sys/uio.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
 #include <netdb.h>
-
-#include "plan9_sockets.h"
-
-enum {
-       Nname = 6,
-};
-
-static struct protoent r;
+#include <errno.h>
+#include <assert.h>
 
 struct protoent *getprotobyname(const char *name)
 {
-       int fd, i, m;
-       char *p, *bp;
-       int nn, na;
-       unsigned long x;
-       static char buf[1024], proto[1024];
-       static char *nptr[Nname + 1];
-
-       /* connect to server */
-       fd = open("/net/cs", O_RDWR);
-       if (fd < 0) {
-               h_errno = NO_RECOVERY;
-               return 0;
-       }
-
-       /* construct the query, always expect a protocol# back */
-       snprintf(buf, sizeof buf, "!protocol=%s ipv4proto=*", name);
-
-       /* query the server */
-       if (write(fd, buf, strlen(buf)) < 0) {
-               h_errno = TRY_AGAIN;
+       static struct protoent r;
+       static char buf[1024];
+       int ret_r;
+       struct protoent *ret;
+
+       ret_r = getprotobyname_r(name, &r, buf, sizeof(buf), &ret);
+       if (ret_r) {
+               /* _r method returns -ERROR on error.  not sure who wants it. */
+               __set_errno(-ret_r);
                return 0;
        }
-       lseek(fd, 0, 0);
-       for (i = 0; i < sizeof(buf) - 1; i += m) {
-               m = read(fd, buf + i, sizeof(buf) - 1 - i);
-               if (m <= 0)
-                       break;
-               buf[i + m++] = ' ';
-       }
-       close(fd);
-       buf[i] = 0;
-
-       /* parse the reply */
-       nn = na = 0;
-       for (bp = buf;;) {
-               p = strchr(bp, '=');
-               if (p == 0)
-                       break;
-               *p++ = 0;
-               if (strcmp(bp, "protocol") == 0) {
-                       if (!nn)
-                               r.p_name = p;
-                       if (nn < Nname)
-                               nptr[nn++] = p;
-               } else if (strcmp(bp, "ipv4proto") == 0) {
-                       r.p_proto = atoi(p);
-                       na++;
-               }
-               while (*p && *p != ' ')
-                       p++;
-               if (*p)
-                       *p++ = 0;
-               bp = p;
-       }
-       nptr[nn] = 0;
-       r.p_aliases = nptr;
-       if (nn + na == 0)
-               return 0;
-
+       assert(ret == &r);
        return &r;
 }
index bf77108..70f956e 100644 (file)
@@ -1,9 +1,107 @@
+/* 
+ * This file is part of the UCB release of Plan 9. It is subject to the license
+ * terms in the LICENSE file found in the top-level directory of this
+ * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
+ * part of the UCB release of Plan 9, including this file, may be copied,
+ * modified, propagated, or distributed except according to the terms contained
+ * in the LICENSE file.
+ */
+/* posix */
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <string.h>
+#include <errno.h>
+
+/* bsd extensions */
+#include <sys/uio.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
 #include <netdb.h>
 
+#include "plan9_sockets.h"
+
+enum {
+       Nname = 6,
+};
+
 int __getprotobyname_r(const char *name, struct protoent *result_buf, char *buf,
                        size_t buflen, struct protoent **result)
 {
+       int fd, i, m;
+       char *p, *bp;
+       int nn, na;
+       unsigned long x;
+       /* This used to be:
+               static char *nptr[Nname + 1];
+        * we need to use space in buf for it */
+       char **nptr;
+       size_t nptr_sz = sizeof(char *) * (Nname + 1);
+
+       if (nptr_sz >= buflen) {
+               *result = 0;
+               return -ERANGE;
+       }
+       nptr = buf; buf += nptr_sz; buflen -= nptr_sz;
+
+       /* connect to server */
+       fd = open("/net/cs", O_RDWR);
+       if (fd < 0) {
+               *result = 0;
+               return -errno;
+       }
+
+       /* construct the query, always expect a protocol# back */
+       snprintf(buf, sizeof buf, "!protocol=%s ipv4proto=*", name);
+
+       /* query the server */
+       if (write(fd, buf, strlen(buf)) < 0) {
+               close(fd);
+               *result = 0;
+               return -errno;
+       }
+       lseek(fd, 0, 0);
+       for (i = 0; i < sizeof(buf) - 1; i += m) {
+               m = read(fd, buf + i, sizeof(buf) - 1 - i);
+               if (m <= 0)
+                       break;
+               buf[i + m++] = ' ';
+       }
+       close(fd);
+       buf[i] = 0;
+
+       /* parse the reply */
+       nn = na = 0;
+       for (bp = buf;;) {
+               p = strchr(bp, '=');
+               if (p == 0)
+                       break;
+               *p++ = 0;
+               if (strcmp(bp, "protocol") == 0) {
+                       if (!nn)
+                               result_buf->p_name = p;
+                       if (nn < Nname)
+                               nptr[nn++] = p;
+               } else if (strcmp(bp, "ipv4proto") == 0) {
+                       result_buf->p_proto = atoi(p);
+                       na++;
+               }
+               while (*p && *p != ' ')
+                       p++;
+               if (*p)
+                       *p++ = 0;
+               bp = p;
+       }
+       nptr[nn] = 0;
+       result_buf->p_aliases = nptr;
+       if (nn + na == 0) {
+               *result = 0;
+               return -1;
+       }
+
+       *result = result_buf;
        return 0;
 }
 weak_alias(__getprotobyname_r, getprotobyname_r);
-stub_warning(getprotobyname_r);
index 41019a2..23ad214 100644 (file)
-/* 
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-/* posix */
-#include <sys/types.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <string.h>
-#include <errno.h>
-#include <ctype.h>
-
-/* bsd extensions */
-#include <sys/uio.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
 #include <netdb.h>
+#include <errno.h>
+#include <assert.h>
 
-#include "plan9_sockets.h"
-
-enum {
-       Nname = 6,
-};
-
-/*
- *  for inet addresses only
- */
 struct servent *getservbyname(const char *name, const char *proto)
 {
-       int i, fd, m, num;
-       char *p;
-       char *bp;
-       int nn, na;
        static struct servent s;
        static char buf[1024];
-       static char *nptr[Nname + 1];
+       int ret_r;
+       struct servent *ret;
 
-       num = 1;
-       for (p = (char *)name; *p; p++)
-               if (!isdigit(*p))
-                       num = 0;
-
-       s.s_name = 0;
-
-       /* connect to server */
-       fd = open("/net/cs", O_RDWR);
-       if (fd < 0) {
+       ret_r = getservbyname_r(name, proto, &s, buf, sizeof(buf), &ret);
+       if (ret_r) {
+               /* _r method returns -ERROR on error.  not sure who wants it. */
+               __set_errno(-ret_r);
                return 0;
        }
-
-       /* construct the query, always expect an ip# back */
-       if (num)
-               snprintf(buf, sizeof buf, "!port=%s %s=*", name, proto);
-       else
-               snprintf(buf, sizeof buf, "!%s=%s port=*", proto, name);
-
-       /* query the server */
-       if (write(fd, buf, strlen(buf)) < 0) {
-               return 0;
-       }
-       lseek(fd, 0, 0);
-       for (i = 0; i < sizeof(buf) - 1; i += m) {
-               m = read(fd, buf + i, sizeof(buf) - 1 - i);
-               if (m <= 0)
-                       break;
-               buf[i + m++] = ' ';
-       }
-       close(fd);
-       buf[i] = 0;
-
-       /* parse the reply */
-       nn = na = 0;
-       for (bp = buf;;) {
-               p = strchr(bp, '=');
-               if (p == 0)
-                       break;
-               *p++ = 0;
-               if (strcmp(bp, proto) == 0) {
-                       if (nn < Nname)
-                               nptr[nn++] = p;
-               } else if (strcmp(bp, "port") == 0) {
-                       s.s_port = htons(atoi(p));
-               }
-               while (*p && *p != ' ')
-                       p++;
-               if (*p)
-                       *p++ = 0;
-               bp = p;
-       }
-       if (nn + na == 0)
-               return 0;
-
-       nptr[nn] = 0;
-       s.s_aliases = nptr;
-       if (s.s_name == 0)
-               s.s_name = nptr[0];
-
+       assert(ret == &s);
        return &s;
 }
index 1518d7f..9785c2d 100644 (file)
+/* 
+ * This file is part of the UCB release of Plan 9. It is subject to the license
+ * terms in the LICENSE file found in the top-level directory of this
+ * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
+ * part of the UCB release of Plan 9, including this file, may be copied,
+ * modified, propagated, or distributed except according to the terms contained
+ * in the LICENSE file.
+ */
+/* posix */
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+
+/* bsd extensions */
+#include <sys/uio.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
 #include <netdb.h>
 
+#include "plan9_sockets.h"
+
+enum {
+       Nname = 6,
+};
+
+/*
+ *  for inet addresses only
+ */
 int __getservbyname_r(const char *name, const char *proto,
                       struct servent *result_buf, char *buf, size_t buflen,
                       struct servent **result)
 {
+       int i, fd, m, num;
+       char *p;
+       char *bp;
+       int nn, na;
+       /* This used to be:
+               static char *nptr[Nname + 1];
+        * we need to use space in buf for it */
+       char **nptr;
+       size_t nptr_sz = sizeof(char *) * (Nname + 1);
+
+       if (nptr_sz >= buflen) {
+               *result = 0;
+               return -ERANGE;
+       }
+       nptr = buf; buf += nptr_sz; buflen -= nptr_sz;
+
+       num = 1;
+       for (p = (char *)name; *p; p++)
+               if (!isdigit(*p))
+                       num = 0;
+
+       result_buf->s_name = 0;
+
+       /* connect to server */
+       fd = open("/net/cs", O_RDWR);
+       if (fd < 0) {
+               *result = 0;
+               return -errno;
+       }
+
+       /* construct the query, always expect an ip# back */
+       if (num)
+               snprintf(buf, sizeof buf, "!port=%s %s=*", name, proto);
+       else
+               snprintf(buf, sizeof buf, "!%s=%s port=*", proto, name);
+
+       /* query the server */
+       if (write(fd, buf, strlen(buf)) < 0) {
+               close(fd);
+               *result = 0;
+               return -errno;
+       }
+       lseek(fd, 0, 0);
+       for (i = 0; i < sizeof(buf) - 1; i += m) {
+               m = read(fd, buf + i, sizeof(buf) - 1 - i);
+               if (m <= 0)
+                       break;
+               buf[i + m++] = ' ';
+       }
+       close(fd);
+       buf[i] = 0;
+
+       /* parse the reply */
+       nn = na = 0;
+       for (bp = buf;;) {
+               p = strchr(bp, '=');
+               if (p == 0)
+                       break;
+               *p++ = 0;
+               if (strcmp(bp, proto) == 0) {
+                       if (nn < Nname)
+                               nptr[nn++] = p;
+               } else if (strcmp(bp, "port") == 0) {
+                       result_buf->s_port = htons(atoi(p));
+               }
+               while (*p && *p != ' ')
+                       p++;
+               if (*p)
+                       *p++ = 0;
+               bp = p;
+       }
+       if (nn + na == 0) {
+               *result = 0;
+               return -1;
+       }
+
+       nptr[nn] = 0;
+       result_buf->s_aliases = nptr;
+       if (result_buf->s_name == 0)
+               result_buf->s_name = nptr[0];
+
+       *result = result_buf;
        return 0;
 }
 weak_alias(__getservbyname_r, getservbyname_r);
-stub_warning(getservbyname_r);
index 009c6ef..815c3ba 100644 (file)
@@ -1,9 +1,32 @@
+/* 
+ * This file is part of the UCB release of Plan 9. It is subject to the license
+ * terms in the LICENSE file found in the top-level directory of this
+ * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
+ * part of the UCB release of Plan 9, including this file, may be copied,
+ * modified, propagated, or distributed except according to the terms contained
+ * in the LICENSE file.
+ */
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdio.h>
+
+/* bsd extensions */
+#include <sys/uio.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
 #include <netdb.h>
+#include <arpa/inet.h>
+
+#include "plan9_sockets.h"
 
 int __getservbyport_r(int port, const char *proto, struct servent *result_buf,
                       char *buf, size_t buflen, struct servent **result)
 {
-       return 0;
+
+       char port_buf[32];
+
+       snprintf(port_buf, sizeof(port_buf), "%d", port);
+       /* the plan 9 version can handle a port or a name */
+       return getservbyname_r(port_buf, proto, result_buf, buf, buflen, result);
 }
 weak_alias(__getservbyport_r, getservbyport_r);
-stub_warning(getservbyport_r);