Path: blob/master/Utilities/cmlibuv/src/unix/getnameinfo.c
3156 views
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.1*2* Permission is hereby granted, free of charge, to any person obtaining a copy3* of this software and associated documentation files (the "Software"), to4* deal in the Software without restriction, including without limitation the5* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or6* sell copies of the Software, and to permit persons to whom the Software is7* furnished to do so, subject to the following conditions:8*9* The above copyright notice and this permission notice shall be included in10* all copies or substantial portions of the Software.11*12* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR13* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,14* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE15* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER16* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING17* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS18* IN THE SOFTWARE.19*/2021#include "uv.h"22#include "internal.h"2324#include <assert.h>25#include <stdlib.h>26#include <stdio.h>27#include <string.h>282930static void uv__getnameinfo_work(struct uv__work* w) {31uv_getnameinfo_t* req;32int err;33socklen_t salen;3435req = container_of(w, uv_getnameinfo_t, work_req);3637if (req->storage.ss_family == AF_INET)38salen = sizeof(struct sockaddr_in);39else if (req->storage.ss_family == AF_INET6)40salen = sizeof(struct sockaddr_in6);41else42abort();4344err = getnameinfo((struct sockaddr*) &req->storage,45salen,46req->host,47sizeof(req->host),48req->service,49sizeof(req->service),50req->flags);51req->retcode = uv__getaddrinfo_translate_error(err);52}5354static void uv__getnameinfo_done(struct uv__work* w, int status) {55uv_getnameinfo_t* req;56char* host;57char* service;5859req = container_of(w, uv_getnameinfo_t, work_req);60uv__req_unregister(req->loop, req);61host = service = NULL;6263if (status == UV_ECANCELED) {64assert(req->retcode == 0);65req->retcode = UV_EAI_CANCELED;66} else if (req->retcode == 0) {67host = req->host;68service = req->service;69}7071if (req->getnameinfo_cb)72req->getnameinfo_cb(req, req->retcode, host, service);73}7475/*76* Entry point for getnameinfo77* return 0 if a callback will be made78* return error code if validation fails79*/80int uv_getnameinfo(uv_loop_t* loop,81uv_getnameinfo_t* req,82uv_getnameinfo_cb getnameinfo_cb,83const struct sockaddr* addr,84int flags) {85if (req == NULL || addr == NULL)86return UV_EINVAL;8788if (addr->sa_family == AF_INET) {89memcpy(&req->storage,90addr,91sizeof(struct sockaddr_in));92} else if (addr->sa_family == AF_INET6) {93memcpy(&req->storage,94addr,95sizeof(struct sockaddr_in6));96} else {97return UV_EINVAL;98}99100uv__req_init(loop, (uv_req_t*)req, UV_GETNAMEINFO);101102req->getnameinfo_cb = getnameinfo_cb;103req->flags = flags;104req->type = UV_GETNAMEINFO;105req->loop = loop;106req->retcode = 0;107108if (getnameinfo_cb) {109uv__work_submit(loop,110&req->work_req,111UV__WORK_SLOW_IO,112uv__getnameinfo_work,113uv__getnameinfo_done);114return 0;115} else {116uv__getnameinfo_work(&req->work_req);117uv__getnameinfo_done(&req->work_req, 0);118return req->retcode;119}120}121122123