aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2001-10-03 21:42:04 +0000
committerDaniel Stenberg <daniel@haxx.se>2001-10-03 21:42:04 +0000
commit9d066935e5e4e0d7477520eeb6fd7b82ce6bebc2 (patch)
treef41587230842b08a0680807f5a3ed855ecf5705c
parentbc40063e072ee186712e3d3b8af0af58727643ea (diff)
Keith McGuigan's excellent fix that makes a cloned copy of the hostent struct
for when gethostbyname() is used so that we have the memory of the struct allocated. This turns out to be needed if the curl handled is passed between threads on Windows and possibly other operating systems where we use that function.
-rw-r--r--lib/hostip.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/lib/hostip.c b/lib/hostip.c
index 7177554af..4fb25bd47 100644
--- a/lib/hostip.c
+++ b/lib/hostip.c
@@ -94,6 +94,75 @@ Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data,
}
#else /* following code is IPv4-only */
+/**
+ * Performs a "deep" copy of a hostent into a buffer
+ * (returns a pointer to the copy).
+ *
+ * Keith McGuigan
+ * 10/3/2001
+ */
+static struct hostent* pack_hostent(char* buf, struct hostent* orig)
+{
+ char* bufptr;
+ struct hostent* copy;
+
+ int i;
+ char* str;
+ int len;
+
+ bufptr = buf;
+ copy = (struct hostent*)bufptr;
+
+ bufptr += sizeof(struct hostent);
+ copy->h_name = bufptr;
+ len = strlen(orig->h_name) + 1;
+ strncpy(bufptr, orig->h_name, len);
+ bufptr += len;
+
+ copy->h_aliases = (char**)bufptr;
+
+ /* Figure out how many aliases there are */
+ for (i = 0; orig->h_aliases[i] != NULL; ++i);
+
+ /* Reserve room for the array */
+ bufptr += (i + 1) * sizeof(char*);
+
+ i = 0;
+ str = orig->h_aliases[i];
+ while (str != NULL) {
+ len = strlen(str) + 1;
+ strncpy(bufptr, str, len);
+ copy->h_aliases[i] = bufptr;
+ bufptr += len;
+ str = orig->h_aliases[++i];
+ }
+ copy->h_aliases[i] = NULL;
+
+ copy->h_addrtype = orig->h_addrtype;
+ copy->h_length = orig->h_length;
+
+ copy->h_addr_list = (char**)bufptr;
+
+ /* Figure out how many addresses there are */
+ for (i = 0; orig->h_addr_list[i] != NULL; ++i);
+
+ /* Reserve room for the array */
+ bufptr += (i + 1) * sizeof(char*);
+
+ i = 0;
+ len = orig->h_length;
+ str = orig->h_addr_list[i];
+ while (str != NULL) {
+ memcpy(bufptr, str, len);
+ copy->h_addr_list[i] = bufptr;
+ bufptr += len;
+ str = orig->h_addr_list[++i];
+ }
+ copy->h_addr_list[i] = NULL;
+
+ return copy;
+}
+
static char *MakeIP(unsigned long num,char *addr, int addr_len)
{
#if defined(HAVE_INET_NTOA) || defined(HAVE_INET_NTOA_R)
@@ -217,6 +286,11 @@ Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data,
free(buf);
*bufp=NULL;
}
+ else
+ /* we make a copy of the hostent right now, right here, as the
+ static one we got a pointer to might get removed when we don't
+ want/expect that */
+ h = pack_hostent(buf, h);
#endif
}
return (h);