19 #include <sys/types.h>
20 #include <sys/socket.h>
39 fcntl(sock, F_SETFD, fcntl(sock, F_GETFD) | FD_CLOEXEC);
42 fcntl(sock, F_SETFL, fcntl(sock, F_GETFL) | O_NONBLOCK);
49 sock = socket(family, socktype, 0);
57 setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one,
sizeof(one));
59 if (!bind(sock, sa, sa_len) &&
60 (socktype != SOCK_STREAM || !listen(sock, SOMAXCONN)))
63 if (!connect(sock, sa, sa_len) || errno == EINPROGRESS)
73 struct sockaddr_un sun = {.sun_family = AF_UNIX};
75 int socktype = ((
type & 0xff) ==
USOCK_TCP) ? SOCK_STREAM : SOCK_DGRAM;
77 if (strlen(host) >=
sizeof(sun.sun_path)) {
81 strcpy(sun.sun_path, host);
90 int socktype = ((
type & 0xff) ==
USOCK_TCP) ? SOCK_STREAM : SOCK_DGRAM;
94 for (rp = result; rp != NULL; rp = rp->ai_next) {
98 memcpy(addr, rp->ai_addr, rp->ai_addrlen);
108 struct timespec ts, cur;
109 int msec = timeout % 1000;
112 clock_gettime(CLOCK_MONOTONIC, &ts);
114 ts.tv_nsec += msec * 1000000;
115 if (ts.tv_nsec > 1000000000) {
117 ts.tv_nsec -= 1000000000;
119 ts.tv_sec += timeout / 1000;
122 ret = poll(fds, nfds, timeout);
123 if (ret >= 0 || (errno != EINTR && errno != EAGAIN))
126 clock_gettime(CLOCK_MONOTONIC, &cur);
127 timeout = (ts.tv_sec - cur.tv_sec) * 1000;
128 timeout += (ts.tv_nsec - cur.tv_nsec) / 1000000;
135 void *addr,
int timeout)
137 int socktype = ((
type & 0xff) ==
USOCK_TCP) ? SOCK_STREAM : SOCK_DGRAM;
139 struct addrinfo *result, *rp;
140 struct addrinfo hints = {
143 .ai_socktype = socktype,
144 .ai_flags = AI_ADDRCONFIG
148 struct addrinfo *rp_v6 = NULL;
149 struct addrinfo *rp_v4 = NULL;
150 struct pollfd pfds[2] = {
151 { .
fd = -1, .events = POLLOUT },
152 { .fd = -1, .events = POLLOUT },
157 if (getaddrinfo(host, service, &hints, &result))
160 if (timeout <= 0 ||
server) {
165 for (rp = result; rp != NULL; rp = rp->ai_next) {
166 if (rp->ai_family == AF_INET6 && !rp_v6)
168 if (rp->ai_family == AF_INET && !rp_v4)
172 if (!rp_v6 && !rp_v4)
178 rp->ai_addrlen, rp->ai_family,
180 if (pfds[0].
fd < 0) {
199 rp->ai_addrlen, rp->ai_family,
201 if (pfds[1].
fd < 0) {
210 poll_restart(pfds + !rp_v6, !!rp_v6 + !!rp_v4, timeout);
211 if (pfds[0].revents & POLLOUT) {
217 if (pfds[1].revents & POLLOUT) {
224 for (i = 0; i < 2; i++) {
226 if (
fd >= 0 &&
fd != sock)
231 fcntl(sock, F_SETFL, fcntl(sock, F_GETFL) & ~O_NONBLOCK);
233 if (addr && sock >= 0)
234 memcpy(addr, rp->ai_addr, rp->ai_addrlen);
236 freeaddrinfo(result);
242 static char buffer[
sizeof(
"65535\0")];
244 if (port < 0 || port > 65535)
247 snprintf(buffer,
sizeof(buffer),
"%u",
port);
252 int usock(
int type,
const char *host,
const char *service) {
267 struct pollfd fds[1];
271 fds[0].events = POLLOUT;
273 res = poll(fds, 1, msecs);
276 }
else if (res == 0) {
280 socklen_t optlen =
sizeof(err);
282 res = getsockopt(
fd, SOL_SOCKET, SO_ERROR, &err, &optlen);
static int usock_unix(int type, const char *host)
static int usock_connect(int type, struct sockaddr *sa, int sa_len, int family, int socktype, bool server)
static int poll_restart(struct pollfd *fds, int nfds, int timeout)
const char * usock_port(int port)
static int usock_inet_notimeout(int type, struct addrinfo *result, void *addr)
int usock(int type, const char *host, const char *service)
static void usock_set_flags(int sock, unsigned int type)
int usock_wait_ready(int fd, int msecs)
int usock_inet_timeout(int type, const char *host, const char *service, void *addr, int timeout)
static int usock_inet(int type, const char *host, const char *service, void *addr)
static struct uloop_fd server