ares_fds.c (2672B)
1 /* MIT License 2 * 3 * Copyright (c) 1998 Massachusetts Institute of Technology 4 * Copyright (c) The c-ares project and its contributors 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 * copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the next 14 * paragraph) shall be included in all copies or substantial portions of the 15 * Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 * SOFTWARE. 24 * 25 * SPDX-License-Identifier: MIT 26 */ 27 28 #include "ares_private.h" 29 30 int ares_fds(const ares_channel_t *channel, fd_set *read_fds, fd_set *write_fds) 31 { 32 ares_socket_t nfds; 33 ares_slist_node_t *snode; 34 /* Are there any active queries? */ 35 size_t active_queries; 36 37 if (channel == NULL || read_fds == NULL || write_fds == NULL) { 38 return 0; 39 } 40 41 ares_channel_lock(channel); 42 43 active_queries = ares_llist_len(channel->all_queries); 44 45 nfds = 0; 46 for (snode = ares_slist_node_first(channel->servers); snode != NULL; 47 snode = ares_slist_node_next(snode)) { 48 ares_server_t *server = ares_slist_node_val(snode); 49 ares_llist_node_t *node; 50 51 for (node = ares_llist_node_first(server->connections); node != NULL; 52 node = ares_llist_node_next(node)) { 53 const ares_conn_t *conn = ares_llist_node_val(node); 54 55 if (!active_queries && !(conn->flags & ARES_CONN_FLAG_TCP)) { 56 continue; 57 } 58 59 /* Silence coverity, shouldn't be possible */ 60 if (conn->fd == ARES_SOCKET_BAD) { 61 continue; 62 } 63 64 /* Always wait on read */ 65 FD_SET(conn->fd, read_fds); 66 67 if (conn->fd >= nfds) { 68 nfds = conn->fd + 1; 69 } 70 71 /* TCP only wait on write if we have the flag set */ 72 if (conn->state_flags & ARES_CONN_STATE_WRITE) { 73 FD_SET(conn->fd, write_fds); 74 } 75 } 76 } 77 78 ares_channel_unlock(channel); 79 return (int)nfds; 80 }