* Exim - an Internet mail transport agent *
*************************************************/
+/* Copyright (c) The Exim Maintainers 2020 - 2023 */
/* Copyright (c) University of Cambridge 1995 - 2018 */
/* See the file NOTICE for conditions of use and distribution. */
+/* SPDX-License-Identifier: GPL-2.0-or-later */
/* Functions for doing things with sockets. With the advent of IPv6 this has
got messier, so that it's worth pulling out the code into separate functions
return sizeof(sin->v6);
}
else
-#else /* HAVE_IPv6 */
-af = af; /* Avoid compiler warning */
#endif /* HAVE_IPV6 */
/* Setup code when using IPv4 socket. The wildcard address is "". */
{
union sockaddr_46 sin;
int s_len = ip_addr(&sin, af, address, port);
-return bind(sock, (struct sockaddr *)&sin, s_len);
+int rc = bind(sock, (struct sockaddr *)&sin, s_len);
+if (rc < 0)
+ log_write(0, LOG_MAIN, "bind of [%s]:%d failed", address, port);
+return rc;
}
s_len = sizeof(s_in6);
}
else
-#else /* HAVE_IPV6 */
-af = af; /* Avoid compiler warning */
#endif /* HAVE_IPV6 */
/* For an IPv4 address, use an IPv4 sockaddr structure, even on a system with
for (int port = portlo; port <= porthi; port++)
if (ip_connect(fd, af, h->address, port, timeout, fastopen_blob) == 0)
{
- if (fd != fd6) close(fd6);
- if (fd != fd4) close(fd4);
+ if (fd6 >= 0 && fd != fd6) close(fd6);
+ if (fd4 >= 0 && fd != fd4) close(fd4);
if (connhost)
{
h->port = port;
BOOL
fd_ready(int fd, time_t timelimit)
{
-fd_set select_inset;
-int time_left = timelimit - time(NULL);
-int rc;
+int rc, time_left = timelimit - time(NULL);
if (time_left <= 0)
{
do
{
- struct timeval tv = { .tv_sec = time_left, .tv_usec = 0 };
- FD_ZERO (&select_inset);
- FD_SET (fd, &select_inset);
-
/*DEBUG(D_transport) debug_printf("waiting for data on fd\n");*/
- rc = select(fd + 1, (SELECT_ARG2_TYPE *)&select_inset, NULL, NULL, &tv);
+ rc = poll_one_fd(fd, POLLIN, time_left * 1000);
/* If some interrupt arrived, just retry. We presume this to be rare,
but it can happen (e.g. the SIGUSR1 signal sent by exiwhat causes
/* Checking the FD_ISSET is not enough, if we're interrupted, the
select_inset may still contain the 'input'. */
}
-while (rc < 0 || !FD_ISSET(fd, &select_inset));
+while (rc < 0);
return TRUE;
}