libuv-svace-build
146 строк · 4.0 Кб
1/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
2*
3* Permission is hereby granted, free of charge, to any person obtaining a copy
4* of this software and associated documentation files (the "Software"), to
5* deal in the Software without restriction, including without limitation the
6* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7* sell copies of the Software, and to permit persons to whom the Software is
8* furnished to do so, subject to the following conditions:
9*
10* The above copyright notice and this permission notice shall be included in
11* all copies or substantial portions of the Software.
12*
13* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19* IN THE SOFTWARE.
20*/
21
22#include <assert.h>23#include <stdio.h>24
25#include "uv.h"26#include "internal.h"27#include "req-inl.h"28
29#ifndef GetNameInfo30int WSAAPI GetNameInfoW(31const SOCKADDR *pSockaddr,32socklen_t SockaddrLength,33PWCHAR pNodeBuffer,34DWORD NodeBufferSize,35PWCHAR pServiceBuffer,36DWORD ServiceBufferSize,37INT Flags
38);39#endif40
41static void uv__getnameinfo_work(struct uv__work* w) {42uv_getnameinfo_t* req;43WCHAR host[NI_MAXHOST];44WCHAR service[NI_MAXSERV];45size_t size;46int ret;47
48req = container_of(w, uv_getnameinfo_t, work_req);49if (GetNameInfoW((struct sockaddr*)&req->storage,50sizeof(req->storage),51host,52ARRAY_SIZE(host),53service,54ARRAY_SIZE(service),55req->flags)) {56ret = WSAGetLastError();57req->retcode = uv__getaddrinfo_translate_error(ret);58return;59}60
61size = sizeof(req->host);62ret = uv__copy_utf16_to_utf8(host, -1, req->host, &size);63if (ret < 0) {64req->retcode = ret;65return;66}67
68size = sizeof(req->service);69ret = uv__copy_utf16_to_utf8(service, -1, req->service, &size);70if (ret < 0) {71req->retcode = ret;72}73}
74
75
76/*
77* Called from uv_run when complete.
78*/
79static void uv__getnameinfo_done(struct uv__work* w, int status) {80uv_getnameinfo_t* req;81char* host;82char* service;83
84req = container_of(w, uv_getnameinfo_t, work_req);85uv__req_unregister(req->loop, req);86host = service = NULL;87
88if (status == UV_ECANCELED) {89assert(req->retcode == 0);90req->retcode = UV_EAI_CANCELED;91} else if (req->retcode == 0) {92host = req->host;93service = req->service;94}95
96if (req->getnameinfo_cb)97req->getnameinfo_cb(req, req->retcode, host, service);98}
99
100
101/*
102* Entry point for getnameinfo
103* return 0 if a callback will be made
104* return error code if validation fails
105*/
106int uv_getnameinfo(uv_loop_t* loop,107uv_getnameinfo_t* req,108uv_getnameinfo_cb getnameinfo_cb,109const struct sockaddr* addr,110int flags) {111if (req == NULL || addr == NULL)112return UV_EINVAL;113
114if (addr->sa_family == AF_INET) {115memcpy(&req->storage,116addr,117sizeof(struct sockaddr_in));118} else if (addr->sa_family == AF_INET6) {119memcpy(&req->storage,120addr,121sizeof(struct sockaddr_in6));122} else {123return UV_EINVAL;124}125
126UV_REQ_INIT(req, UV_GETNAMEINFO);127uv__req_register(loop, req);128
129req->getnameinfo_cb = getnameinfo_cb;130req->flags = flags;131req->loop = loop;132req->retcode = 0;133
134if (getnameinfo_cb) {135uv__work_submit(loop,136&req->work_req,137UV__WORK_SLOW_IO,138uv__getnameinfo_work,139uv__getnameinfo_done);140return 0;141} else {142uv__getnameinfo_work(&req->work_req);143uv__getnameinfo_done(&req->work_req, 0);144return req->retcode;145}146}
147