Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

unix: malloc only once in uv_getaddrinfo()

  • Loading branch information...
commit e21cdf1e0d373ccaf01e0103e76882dcb1623fab 1 parent 61f0487
@bnoordhuis bnoordhuis authored
Showing with 47 additions and 24 deletions.
  1. +47 −24 src/unix/core.c
View
71 src/unix/core.c
@@ -298,9 +298,15 @@ static int uv_getaddrinfo_done(eio_req* req_) {
uv__req_unregister(req->loop, req);
- free(req->hints);
- free(req->service);
- free(req->hostname);
+ /* see initialization in uv_getaddrinfo() */
+ if (req->hints)
+ free(req->hints);
+ else if (req->service)
+ free(req->service);
+ else if (req->hostname)
+ free(req->hostname);
+ else
+ assert(0);
if (req->retcode == 0) {
/* OK */
@@ -335,54 +341,71 @@ static void getaddrinfo_thread_proc(eio_req *req_) {
}
-/* stub implementation of uv_getaddrinfo */
int uv_getaddrinfo(uv_loop_t* loop,
uv_getaddrinfo_t* req,
uv_getaddrinfo_cb cb,
const char* hostname,
const char* service,
const struct addrinfo* hints) {
+ size_t hostname_len;
+ size_t service_len;
+ size_t hints_len;
eio_req* req_;
+ size_t len;
+ char* buf;
+
+ if (req == NULL || cb == NULL || (hostname == NULL && service == NULL))
+ return uv__set_artificial_error(loop, UV_EINVAL);
uv_eio_init(loop);
- if (req == NULL || cb == NULL || (hostname == NULL && service == NULL)) {
- uv__set_artificial_error(loop, UV_EINVAL);
- return -1;
- }
+ hostname_len = hostname ? strlen(hostname) + 1 : 0;
+ service_len = service ? strlen(service) + 1 : 0;
+ hints_len = hints ? sizeof(*hints) : 0;
+ buf = malloc(hostname_len + service_len + hints_len);
+
+ if (buf == NULL)
+ return uv__set_artificial_error(loop, UV_ENOMEM);
uv__req_init(loop, req, UV_GETADDRINFO);
req->loop = loop;
req->cb = cb;
+ req->res = NULL;
+ req->hints = NULL;
+ req->service = NULL;
+ req->hostname = NULL;
+ req->retcode = 0;
- /* TODO don't alloc so much. */
+ /* order matters, see uv_getaddrinfo_done() */
+ len = 0;
if (hints) {
- req->hints = malloc(sizeof(struct addrinfo));
- memcpy(req->hints, hints, sizeof(struct addrinfo));
- }
- else {
- req->hints = NULL;
+ req->hints = memcpy(buf + len, hints, sizeof(*hints));
+ len += sizeof(*hints);
}
- /* TODO security! check lengths, check return values. */
-
- req->hostname = hostname ? strdup(hostname) : NULL;
- req->service = service ? strdup(service) : NULL;
- req->res = NULL;
- req->retcode = 0;
+ if (service) {
+ req->service = memcpy(buf + len, service, service_len);
+ len += service_len;
+ }
- /* TODO check handle->hostname == NULL */
- /* TODO check handle->service == NULL */
+ if (hostname) {
+ req->hostname = memcpy(buf + len, hostname, hostname_len);
+ len += hostname_len;
+ }
req_ = eio_custom(getaddrinfo_thread_proc,
EIO_PRI_DEFAULT,
uv_getaddrinfo_done,
req,
&loop->uv_eio_channel);
- assert(req_);
- return 0;
+ if (req_)
+ return 0;
+
+ free(buf);
+
+ return uv__set_artificial_error(loop, UV_ENOMEM);
}
Please sign in to comment.
Something went wrong with that request. Please try again.