瀏覽代碼

dynamically allocate storage for gethostby* buffers

this change shaves ~1k off libc.so bss size, and also avoids hard
errors in the case where the static buffer was not large enough to
hold the result.

this whole framework is really ugly and might should be replaced or at
least heavily overhauled when some changes/factorizations are made to
getaddrinfo internals in the future.
Rich Felker 12 年之前
父節點
當前提交
a47ad3ebce
共有 2 個文件被更改,包括 32 次插入10 次删除
  1. 16 5
      src/network/gethostbyaddr.c
  2. 16 5
      src/network/gethostbyname2.c

+ 16 - 5
src/network/gethostbyaddr.c

@@ -3,13 +3,24 @@
 #include <netdb.h>
 #include <string.h>
 #include <netinet/in.h>
+#include <errno.h>
+#include <stdlib.h>
 
 struct hostent *gethostbyaddr(const void *a, socklen_t l, int af)
 {
-	static struct hostent h;
-	static long buf[512/sizeof(long)];
+	static struct hostent *h;
+	size_t size = 63;
 	struct hostent *res;
-	if (gethostbyaddr_r(a, l, af, &h,
-		(void *)buf, sizeof buf, &res, &h_errno)) return 0;
-	return &h;
+	int err;
+	do {
+		free(h);
+		h = malloc(size+=size+1);
+		if (!h) {
+			h_errno = NO_RECOVERY;
+			return 0;
+		}
+		err = gethostbyaddr_r(a, l, af, h,
+			(void *)(h+1), size-sizeof *h, &res, &h_errno);
+	} while (err == ERANGE);
+	return err ? 0 : h;
 }

+ 16 - 5
src/network/gethostbyname2.c

@@ -4,13 +4,24 @@
 #include <netdb.h>
 #include <string.h>
 #include <netinet/in.h>
+#include <errno.h>
+#include <stdlib.h>
 
 struct hostent *gethostbyname2(const char *name, int af)
 {
-	static struct hostent h;
-	static long buf[512/sizeof(long)];
+	static struct hostent *h;
+	size_t size = 63;
 	struct hostent *res;
-	if (gethostbyname2_r(name, af, &h,
-		(void *)buf, sizeof buf, &res, &h_errno)) return 0;
-	return &h;
+	int err;
+	do {
+		free(h);
+		h = malloc(size+=size+1);
+		if (!h) {
+			h_errno = NO_RECOVERY;
+			return 0;
+		}
+		err = gethostbyname2_r(name, af, h,
+			(void *)(h+1), size-sizeof *h, &res, &h_errno);
+	} while (err == ERANGE);
+	return err ? 0 : h;
 }