33 #if defined(_WIN32) || _POSIX_C_SOURCE >= 200112L
48 static void sock_fini(
struct io_handle *handle);
50 static ssize_t sock_read(
struct io_handle *handle,
void *buf,
size_t nbytes);
51 static ssize_t sock_write(
52 struct io_handle *handle,
const void *buf,
size_t nbytes);
53 static ssize_t sock_recv(
struct io_handle *handle,
void *buf,
size_t nbytes,
55 static ssize_t sock_send(
struct io_handle *handle,
const void *buf,
61 .size =
sizeof(
struct sock),
68 .accept = &sock_accept,
69 .connect = &sock_connect };
71 static int _socketpair(
int af,
int type,
int protocol, SOCKET sv[2]);
79 #if defined(__CYGWIN__) || defined(__linux__)
80 flags |= SOCK_CLOEXEC;
89 s = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
94 #elif defined(__linux__) && defined(HAVE_BLUETOOTH_BLUETOOTH_H) \
95 && defined(HAVE_BLUETOOTH_RFCOMM_H)
99 s = socket(AF_BLUETOOTH, SOCK_STREAM | flags,
109 s = socket(AF_INET, SOCK_STREAM | flags, 0);
112 s = socket(AF_INET, SOCK_DGRAM | flags, 0);
120 s = socket(AF_INET6, SOCK_STREAM | flags, 0);
123 s = socket(AF_INET6, SOCK_DGRAM | flags, 0);
128 #if _POSIX_C_SOURCE >= 200112L
132 s = socket(AF_UNIX, SOCK_STREAM | flags, 0);
135 s = socket(AF_UNIX, SOCK_DGRAM | flags, 0);
144 if (s == INVALID_SOCKET) {
149 #if _POSIX_C_SOURCE >= 200112L && !defined(__CYGINW__) && !defined(__linux__)
150 if (fcntl(s, F_SETFD, FD_CLOEXEC) == -1) {
159 goto error_alloc_handle;
162 handle->
fd = (HANDLE)s;
164 ((
struct sock *)handle)->type =
type;
169 #if _POSIX_C_SOURCE >= 200112L && !defined(__CYGINW__) && !defined(__linux__)
183 assert(handle_vector);
189 #if defined(__CYGWIN__) || defined(__linux__)
190 flags |= SOCK_CLOEXEC;
194 SOCKET socket_vector[2];
199 result = _socketpair(AF_INET, SOCK_STREAM | flags, 0,
203 result = _socketpair(AF_INET, SOCK_DGRAM | flags, 0,
212 result = _socketpair(AF_INET6, SOCK_STREAM | flags, 0,
216 result = _socketpair(AF_INET6, SOCK_DGRAM | flags, 0,
222 #if _POSIX_C_SOURCE >= 200112L
226 result = _socketpair(AF_UNIX, SOCK_STREAM | flags, 0,
230 result = _socketpair(AF_UNIX, SOCK_DGRAM | flags, 0,
240 if (result == SOCKET_ERROR) {
242 goto error_socketpair;
245 #if _POSIX_C_SOURCE >= 200112L && !defined(__CYGINW__) && !defined(__linux__)
246 if (fcntl(socket_vector[0], F_SETFD, FD_CLOEXEC) == -1) {
250 if (fcntl(socket_vector[1], F_SETFD, FD_CLOEXEC) == -1) {
257 if (!handle_vector[0]) {
259 goto error_alloc_handle_vector_0;
262 handle_vector[0]->
fd = (HANDLE)socket_vector[0];
263 ((
struct sock *)handle_vector[0])->domain =
domain;
264 ((
struct sock *)handle_vector[0])->type =
type;
267 if (!handle_vector[1]) {
269 goto error_alloc_handle_vector_1;
272 handle_vector[1]->
fd = (HANDLE)socket_vector[1];
273 ((
struct sock *)handle_vector[1])->domain =
domain;
274 ((
struct sock *)handle_vector[1])->type =
type;
281 error_alloc_handle_vector_1:
284 error_alloc_handle_vector_0:
286 #if _POSIX_C_SOURCE >= 200112L && !defined(__CYGINW__) && !defined(__linux__)
289 closesocket(socket_vector[1]);
290 closesocket(socket_vector[0]);
309 assert(handle->
vtab);
315 return handle->
vtab->
recv(handle, buf, nbytes, addr, flags);
327 assert(handle->
vtab);
333 return handle->
vtab->
send(handle, buf, nbytes, addr, flags);
344 assert(handle->
vtab);
361 assert(handle->
vtab);
370 #if defined(_WIN32) || _POSIX_C_SOURCE >= 200112L
380 if (handle->
vtab != &sock_vtab) {
385 return ((
struct sock *)handle)->domain;
396 if (handle->
vtab != &sock_vtab) {
401 return ((
struct sock *)handle)->type;
414 return bind((SOCKET)handle->
fd, (
const struct sockaddr *)&addr->
addr,
426 return listen((SOCKET)handle->
fd, backlog) ? -1 : 0;
462 return shutdown((SOCKET)handle->
fd, how) ? -1 : 0;
478 return getsockname((SOCKET)handle->
fd, (
struct sockaddr *)&addr->
addr,
479 (socklen_t *)&addr->
addrlen) ? -1 : 0;
483 int result = getsockname(handle->
fd, (
struct sockaddr *)&addr->
addr,
486 if (!result || errno != EINVAL
490 return getsockname(handle->
fd, (
struct sockaddr *)&addr->
addr,
508 return getpeername((SOCKET)handle->
fd, (
struct sockaddr *)&addr->
addr,
509 (socklen_t *)&addr->
addrlen) ? -1 : 0;
513 int result = getpeername(handle->
fd, (
struct sockaddr *)&addr->
addr,
516 if (!result || errno != EINVAL
520 return getpeername(handle->
fd, (
struct sockaddr *)&addr->
addr,
545 if (getsockopt((SOCKET)handle->
fd, SOL_SOCKET, SO_ACCEPTCONN,
546 (
char *)&optval, &(socklen_t){ sizeof(optval) }))
566 if (getsockopt((SOCKET)handle->
fd, SOL_SOCKET, SO_BROADCAST,
567 (
char *)&optval, &(socklen_t){ sizeof(optval) }))
582 BOOL optval = !!broadcast;
584 int optval = !!broadcast;
587 return setsockopt((SOCKET)handle->
fd, SOL_SOCKET, SO_BROADCAST,
588 (
const char *)&optval,
sizeof(optval)) ? -1 : 0;
606 if (getsockopt((SOCKET)handle->
fd, SOL_SOCKET, SO_DEBUG,
607 (
char *)&optval, &(socklen_t){ sizeof(optval) }))
622 BOOL optval = !!debug;
624 int optval = !!debug;
627 return setsockopt((SOCKET)handle->
fd, SOL_SOCKET, SO_DEBUG,
628 (
const char *)&optval,
sizeof(optval)) ? -1 : 0;
646 if (getsockopt((SOCKET)handle->
fd, SOL_SOCKET, SO_DONTROUTE,
647 (
char *)&optval, &(socklen_t){ sizeof(optval) }))
662 BOOL optval = !!dontroute;
664 int optval = !!dontroute;
667 return setsockopt((SOCKET)handle->
fd, SOL_SOCKET, SO_DONTROUTE,
668 (
const char *)&optval,
sizeof(optval)) ? -1 : 0;
681 return getsockopt((SOCKET)handle->
fd, SOL_SOCKET, SO_ERROR,
682 (
char *)perror, &(socklen_t){ sizeof(*perror) })
701 if (getsockopt((SOCKET)handle->
fd, SOL_SOCKET, SO_KEEPALIVE,
702 (
char *)&optval, &(socklen_t){ sizeof(optval) }))
717 struct tcp_keepalive kaInBuffer = { .onoff = keepalive,
719 .keepalivetime = time * 1000,
721 .keepaliveinterval = interval * 1000 };
722 DWORD dwBytesReturned;
724 return WSAIoctl((SOCKET)handle->
fd, SIO_KEEPALIVE_VALS, &kaInBuffer,
725 sizeof(kaInBuffer), NULL, 0, &dwBytesReturned, NULL,
730 if (setsockopt(handle->
fd, SOL_SOCKET, SO_KEEPALIVE, &keepalive,
731 sizeof(keepalive)) == -1)
737 if (setsockopt(handle->
fd, SOL_TCP, TCP_KEEPIDLE, &time,
742 if (setsockopt(handle->
fd, SOL_TCP, TCP_KEEPINTVL, &interval,
743 sizeof(interval)) == -1)
763 struct linger optval;
765 if (getsockopt((SOCKET)handle->
fd, SOL_SOCKET, SO_LINGER,
766 (
char *)&optval, &(socklen_t){ sizeof(optval) }))
769 return optval.l_onoff ? optval.l_linger : 0;
785 struct linger optval = { !!time, time };
787 return setsockopt((SOCKET)handle->
fd, SOL_SOCKET, SO_LINGER,
788 (
const char *)&optval,
sizeof(optval)) ? -1 : 0;
806 if (getsockopt((SOCKET)handle->
fd, SOL_SOCKET, SO_OOBINLINE,
807 (
char *)&optval, &(socklen_t){ sizeof(optval) }))
822 BOOL optval = !!oobinline;
824 int optval = !!oobinline;
827 return setsockopt((SOCKET)handle->
fd, SOL_SOCKET, SO_OOBINLINE,
828 (
const char *)&optval,
sizeof(optval)) ? -1 : 0;
842 if (getsockopt((SOCKET)handle->
fd, SOL_SOCKET, SO_RCVBUF,
843 (
char *)&optval, &(socklen_t){ sizeof(optval) }))
858 return setsockopt((SOCKET)handle->
fd, SOL_SOCKET, SO_RCVBUF,
859 (
const char *)&size,
sizeof(size)) ? -1 : 0;
872 DWORD optval = timeout;
874 struct timeval optval = { .tv_sec = timeout / 1000,
875 .tv_usec = (timeout % 1000) * 1000 };
878 return setsockopt((SOCKET)handle->
fd, SOL_SOCKET, SO_RCVTIMEO,
879 (
const char *)&optval,
sizeof(optval)) ? -1 : 0;
897 if (getsockopt((SOCKET)handle->
fd, SOL_SOCKET, SO_REUSEADDR,
898 (
char *)&optval, &(socklen_t){ sizeof(optval) }))
913 BOOL optval = !!reuseaddr;
915 int optval = !!reuseaddr;
918 return setsockopt((SOCKET)handle->
fd, SOL_SOCKET, SO_REUSEADDR,
919 (
const char *)&optval,
sizeof(optval)) ? -1 : 0;
933 if (getsockopt((SOCKET)handle->
fd, SOL_SOCKET, SO_SNDBUF,
934 (
char *)&optval, &(socklen_t){ sizeof(optval) }))
949 return setsockopt((SOCKET)handle->
fd, SOL_SOCKET, SO_SNDBUF,
950 (
const char *)&size,
sizeof(size)) ? -1 : 0;
963 DWORD optval = timeout;
965 struct timeval optval = { .tv_sec = timeout / 1000,
966 .tv_usec = (timeout % 1000) * 1000 };
969 return setsockopt((SOCKET)handle->
fd, SOL_SOCKET, SO_SNDTIMEO,
970 (
const char *)&optval,
sizeof(optval)) ? -1 : 0;
988 if (getsockopt((SOCKET)handle->
fd, IPPROTO_TCP, TCP_NODELAY,
989 (
char *)&optval, &(socklen_t){ sizeof(optval) }))
1004 BOOL optval = !!nodelay;
1006 int optval = !!nodelay;
1009 return setsockopt((SOCKET)handle->
fd, IPPROTO_TCP, TCP_NODELAY,
1010 (
const char *)&optval,
sizeof(optval)) ? -1 : 0;
1014 #if defined(_WIN32) || defined(HAVE_SYS_IOCTL_H)
1025 if (ioctlsocket((SOCKET)handle->
fd, FIONREAD, &optval))
1034 result = ioctl(handle->
fd, FIONREAD, &optval);
1035 }
while (result == -1 && errno == EINTR);
1043 #if defined(_WIN32) || defined(__CYGWIN__) || defined(__linux__)
1053 if (handle->
vtab != &sock_vtab) {
1063 switch (((
struct sock *)handle)->domain) {
1066 if (getsockopt((SOCKET)handle->
fd, IPPROTO_IP,
1067 IP_MULTICAST_LOOP, (
char *)&optval,
1068 &(socklen_t){ sizeof(optval) }))
1074 if (getsockopt((SOCKET)handle->
fd, IPPROTO_IPV6,
1075 IPV6_MULTICAST_LOOP, (
char *)&optval,
1076 &(socklen_t){ sizeof(optval) }))
1093 if (handle->
vtab != &sock_vtab) {
1099 DWORD optval = !!loop;
1101 int optval = !!loop;
1103 switch (((
struct sock *)handle)->domain) {
1106 return setsockopt((SOCKET)handle->
fd, IPPROTO_IP,
1107 IP_MULTICAST_LOOP, (
const char *)&optval,
1108 sizeof(optval)) ? -1 : 0;
1112 return setsockopt((SOCKET)handle->
fd, IPPROTO_IPV6,
1113 IPV6_MULTICAST_LOOP, (
const char *)&optval,
1114 sizeof(optval)) ? -1 : 0;
1128 if (handle->
vtab != &sock_vtab) {
1138 switch (((
struct sock *)handle)->domain) {
1141 if (getsockopt((SOCKET)handle->
fd, IPPROTO_IP, IP_MULTICAST_TTL,
1143 &(socklen_t){ sizeof(optval) }))
1149 if (getsockopt((SOCKET)handle->
fd, IPPROTO_IPV6,
1150 IPV6_MULTICAST_HOPS, (
char *)&optval,
1151 &(socklen_t){ sizeof(optval) }))
1168 if (handle->
vtab != &sock_vtab) {
1178 switch (((
struct sock *)handle)->domain) {
1181 return setsockopt((SOCKET)handle->
fd, IPPROTO_IP,
1182 IP_MULTICAST_TTL, (
const char *)&optval,
1183 sizeof(optval)) ? -1 : 0;
1187 return setsockopt((SOCKET)handle->
fd, IPPROTO_IPV6,
1188 IPV6_MULTICAST_HOPS, (
const char *)&optval,
1189 sizeof(optval)) ? -1 :0;
1206 if (handle->
vtab != &sock_vtab) {
1211 struct group_req greq;
1212 memset(&greq, 0,
sizeof(greq));
1213 greq.gr_interface = index;
1214 memcpy(&greq.gr_group, &group->
addr,
sizeof(greq.gr_group));
1220 return setsockopt((SOCKET)handle->
fd, level, MCAST_JOIN_GROUP,
1221 (
const char *)&greq,
sizeof(greq)) ? 0 : -1;
1237 if (handle->
vtab != &sock_vtab) {
1242 struct group_source_req greq;
1243 memset(&greq, 0,
sizeof(greq));
1244 greq.gsr_interface = index;
1245 memcpy(&greq.gsr_group, &group->
addr,
sizeof(greq.gsr_group));
1246 memcpy(&greq.gsr_source, &source->
addr,
sizeof(greq.gsr_source));
1252 return setsockopt((SOCKET)handle->
fd, level, MCAST_BLOCK_SOURCE,
1253 (
const char *)&greq,
sizeof(greq)) ? -1 : 0;
1269 if (handle->
vtab != &sock_vtab) {
1274 struct group_source_req greq;
1275 memset(&greq, 0,
sizeof(greq));
1276 greq.gsr_interface = index;
1277 memcpy(&greq.gsr_group, &group->
addr,
sizeof(greq.gsr_group));
1278 memcpy(&greq.gsr_source, &source->
addr,
sizeof(greq.gsr_source));
1284 return setsockopt((SOCKET)handle->
fd, level, MCAST_UNBLOCK_SOURCE,
1285 (
const char *)&greq,
sizeof(greq)) ? -1 : 0;
1300 if (handle->
vtab != &sock_vtab) {
1305 struct group_req greq;
1306 memset(&greq, 0,
sizeof(greq));
1307 greq.gr_interface = index;
1308 memcpy(&greq.gr_group, &group->
addr,
sizeof(greq.gr_group));
1314 return setsockopt((SOCKET)handle->
fd, level, MCAST_LEAVE_GROUP,
1315 (
const char *)&greq,
sizeof(greq)) ? -1 : 0;
1331 if (handle->
vtab != &sock_vtab) {
1336 struct group_source_req greq;
1337 memset(&greq, 0,
sizeof(greq));
1338 greq.gsr_interface = index;
1339 memcpy(&greq.gsr_group, &group->
addr,
sizeof(greq.gsr_group));
1340 memcpy(&greq.gsr_source, &source->
addr,
sizeof(greq.gsr_source));
1346 return setsockopt((SOCKET)handle->
fd, level, MCAST_JOIN_SOURCE_GROUP,
1347 (
const char *)&greq,
sizeof(greq)) ? -1 : 0;
1360 if (handle->
vtab != &sock_vtab) {
1365 struct group_source_req greq;
1366 memset(&greq, 0,
sizeof(greq));
1367 greq.gsr_interface = index;
1368 memcpy(&greq.gsr_group, &group->
addr,
sizeof(greq.gsr_group));
1369 memcpy(&greq.gsr_source, &source->
addr,
sizeof(greq.gsr_source));
1375 return setsockopt((SOCKET)handle->
fd, level, MCAST_LEAVE_SOURCE_GROUP,
1376 (
const char *)&greq,
sizeof(greq)) ? -1 : 0;
1386 closesocket((SOCKET)handle->
fd);
1390 sock_flags(
struct io_handle *handle,
int flags)
1396 return ioctlsocket((SOCKET)handle->
fd, FIONBIO, &iMode) ? -1 : 0;
1398 int arg = fcntl(handle->
fd, F_GETFL, 0);
1403 return fcntl(handle->
fd, F_SETFL, arg | O_NONBLOCK);
1405 return fcntl(handle->
fd, F_SETFL, arg & ~O_NONBLOCK);
1411 sock_read(
struct io_handle *handle,
void *buf,
size_t nbytes)
1413 return sock_recv(handle, buf, nbytes, NULL, 0);
1417 sock_write(
struct io_handle *handle,
const void *buf,
size_t nbytes)
1419 return sock_send(handle, buf, nbytes, NULL, 0);
1434 _flags |= MSG_WAITALL;
1440 result = recvfrom((SOCKET)handle->
fd, buf, nbytes, _flags,
1446 result = recvfrom(handle->
fd, buf, nbytes, _flags,
1447 (
struct sockaddr *)&addr->
addr,
1449 }
while (result == -1 && errno == EINTR);
1453 result = recv((SOCKET)handle->
fd, buf, nbytes, _flags);
1458 result = recv(handle->
fd, buf, nbytes, _flags);
1459 }
while (result == -1 && errno == EINTR);
1462 return result == SOCKET_ERROR ? -1 : result;
1466 sock_send(
struct io_handle *handle,
const void *buf,
size_t nbytes,
1475 _flags |= MSG_NOSIGNAL;
1482 ? sendto((SOCKET)handle->
fd, buf, nbytes, _flags,
1483 (
const struct sockaddr *)&addr->
addr, addr->
addrlen)
1484 : send((SOCKET)handle->fd, buf, nbytes, _flags);
1492 ? sendto(handle->
fd, buf, nbytes, _flags,
1493 (
const struct sockaddr *)&addr->
addr,
1495 : send(handle->fd, buf, nbytes, _flags);
1497 }
while (result == -1 && errno == EINTR);
1499 return result == SOCKET_ERROR ? -1 : result;
1514 s = accept((SOCKET)handle->
fd, (
struct sockaddr *)&addr->
addr,
1521 s = accept4(handle->
fd, (
struct sockaddr *)&addr->
addr,
1525 s = accept(handle->
fd, (
struct sockaddr *)&addr->
addr,
1528 }
while (s == -1 && errno == EINTR);
1532 s = accept((SOCKET)handle->
fd, NULL, NULL);
1538 s = accept4(handle->
fd, NULL, NULL, SOCK_CLOEXEC);
1540 s = accept(handle->
fd, NULL, NULL);
1542 }
while (s == -1 && errno == EINTR);
1546 if (s == INVALID_SOCKET) {
1551 #if _POSIX_C_SOURCE >= 200112L && !defined(_GNU_SOURCE)
1552 if (fcntl(s, F_SETFD, FD_CLOEXEC) == -1) {
1561 goto error_alloc_handle;
1564 handle->
fd = (HANDLE)s;
1571 #if _POSIX_C_SOURCE >= 200112L && !defined(_GNU_SOURCE)
1591 return connect((SOCKET)handle->
fd, (
const struct sockaddr *)&addr->
addr,
1599 result = connect(handle->
fd,
1600 (
const struct sockaddr *)&addr->
addr,
1602 }
while (result == -1 && errno == EINTR);
1608 _socketpair(
int af,
int type,
int protocol, SOCKET sv[2])
1611 sv[0] = sv[1] = INVALID_SOCKET;
1613 #if _POSIX_C_SOURCE >= 200112L
1615 return socketpair(af,
type, protocol, sv);
1620 if (af != AF_INET && af != AF_INET6) {
1626 #if defined(__CYGWIN__) || defined(__linux__)
1627 flags =
type & (SOCK_NONBLOCK | SOCK_CLOEXEC);
1631 if (
type != SOCK_STREAM &&
type != SOCK_DGRAM) {
1636 sv[0] = socket(af,
type | flags, protocol);
1637 if (sv[0] == INVALID_SOCKET) {
1639 goto error_socket_0;
1642 sv[1] = socket(af,
type | flags, protocol);
1643 if (sv[1] == INVALID_SOCKET) {
1645 goto error_socket_1;
1648 struct sockaddr_storage name[2];
1649 struct sockaddr *name_0 = (
struct sockaddr *)&name[0];
1650 struct sockaddr_in *name_in_0 = (
struct sockaddr_in *)name_0;
1651 struct sockaddr_in6 *name_in6_0 = (
struct sockaddr_in6 *)name_0;
1652 struct sockaddr *name_1 = (
struct sockaddr *)&name[1];
1653 struct sockaddr_in *name_in_1 = (
struct sockaddr_in *)name_1;
1654 struct sockaddr_in6 *name_in6_1 = (
struct sockaddr_in6 *)name_1;
1655 socklen_t namelen_0, namelen_1;
1657 if (af == AF_INET) {
1658 name_in_1->sin_family = AF_INET;
1659 name_in_1->sin_port = 0;
1660 name_in_1->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1661 namelen_1 =
sizeof(*name_in_1);
1663 name_in6_1->sin6_family = AF_INET6;
1664 name_in6_1->sin6_port = 0;
1665 name_in6_1->sin6_addr = in6addr_loopback;
1666 namelen_1 =
sizeof(*name_in6_1);
1669 if (bind(sv[1], name_1, namelen_1) == SOCKET_ERROR) {
1673 if (getsockname(sv[1], name_1, &namelen_1) == SOCKET_ERROR) {
1675 goto error_getsockname_1;
1678 if (type == SOCK_STREAM) {
1679 if (listen(sv[1], 1) == SOCKET_ERROR) {
1684 if (af == AF_INET) {
1685 name_in_0->sin_family = AF_INET;
1686 name_in_0->sin_port = 0;
1687 name_in_0->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1688 namelen_0 =
sizeof(*name_in_0);
1690 name_in6_0->sin6_family = AF_INET6;
1691 name_in6_0->sin6_port = 0;
1692 name_in6_0->sin6_addr = in6addr_loopback;
1693 namelen_0 =
sizeof(*name_in6_0);
1696 if (bind(sv[0], name_0, namelen_0) == SOCKET_ERROR) {
1700 if (getsockname(sv[0], name_0, &namelen_0) == SOCKET_ERROR) {
1702 goto error_getsockname_0;
1707 name_in_1->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1709 name_in6_1->sin6_addr = in6addr_loopback;
1710 if (connect(sv[0], name_1, namelen_1) == SOCKET_ERROR) {
1712 goto error_connect_0;
1715 if (type == SOCK_STREAM) {
1716 SOCKET s = accept(sv[1], NULL, NULL);
1717 if (s == INVALID_SOCKET) {
1725 name_in_0->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1727 name_in6_0->sin6_addr = in6addr_loopback;
1728 if (connect(sv[1], name_0, namelen_0) == SOCKET_ERROR) {
1730 goto error_connect_1;
1739 error_getsockname_0:
1742 error_getsockname_1:
1745 sv[1] = INVALID_SOCKET;
1748 sv[0] = INVALID_SOCKET;
This header file is part of the I/O library; it contains the network address declarations.
This header file is part of the utilities library; it contains the native and platform-independent er...
int errnum2c(errnum_t errnum)
Transforms a platform-independent error number to a native error code.
@ ERRNUM_AFNOSUPPORT
Address family not supported.
@ ERRNUM_BADF
Bad file descriptor.
@ ERRNUM_NOTSOCK
Not a socket.
@ ERRNUM_INVAL
Invalid argument.
@ ERRNUM_PROTOTYPE
Protocol wrong type for socket.
int get_errc(void)
Returns the last (thread-specific) native error code set by a system call or library function.
void set_errc(int errc)
Sets the current (thread-specific) native error code to errc.
void set_errnum(errnum_t errnum)
Sets the current (thread-specific) platform-independent error number to errnum.
void io_handle_free(struct io_handle *handle)
Frees an I/O device handle.
struct io_handle * io_handle_alloc(const struct io_handle_vtab *vtab)
Allocates a new I/O device handle from a virtual table.
This is the internal header file of the I/O handle declarations.
@ IO_TYPE_SOCK
A network socket.
io_handle_t io_handle_acquire(io_handle_t handle)
Increments the reference count of an I/O device handle.
@ IO_FLAG_NONBLOCK
Perform I/O operations in non-blocking mode.
@ IO_FLAG_NO_CLOSE
Do not close the native file descriptor when closing an I/O device.
#define IO_HANDLE_ERROR
The value of an invalid I/O device handle.
int io_sock_mcast_unblock_source(io_handle_t handle, unsigned int index, const io_addr_t *group, const io_addr_t *source)
Unblocks data from a given source to a given multicast group.
int io_sock_shutdown(io_handle_t handle, int how)
Causes all or part of a full-duplex connection on a socket to be shut down.
int io_sock_get_oobinline(io_handle_t handle)
Checks if out-of-band data is received in the normal data stream of a socket.
int io_sock_set_sndtimeo(io_handle_t handle, int timeout)
Sets the timeout (in milliseconds) of a send operation on a socket.
int io_sock_get_mcast_loop(io_handle_t handle)
Checks if the loopback of outgoing multicast datagrams is enabled for a socket.
int io_sock_mcast_join_source_group(io_handle_t handle, unsigned int index, const io_addr_t *group, const io_addr_t *source)
Joins a source-specific multicast group.
int io_sock_get_tcp_nodelay(io_handle_t handle)
Checks if Nagle's algorithm for send coalescing is enabled for a socket.
int io_open_socketpair(int domain, int type, io_handle_t handle_vector[2])
Opens a pair of connected sockets.
int io_sock_set_reuseaddr(io_handle_t handle, int reuseaddr)
Enables a socket to be bound to an address that is already in use if reuseaddr is non-zero,...
int io_sock_set_broadcast(io_handle_t handle, int broadcast)
Enables a socket to send broadcast messages if broadcast is non-zero, and disables this option otherw...
int io_sock_set_mcast_ttl(io_handle_t handle, int ttl)
Sets the TTL (time to live) value for IP multicast traffic on a socket (the default is 1).
int io_sock_mcast_leave_group(io_handle_t handle, unsigned int index, const io_addr_t *group)
Leaves an any-source multicast group.
ssize_t io_recv(io_handle_t handle, void *buf, size_t nbytes, io_addr_t *addr, int flags)
Performs a receive operation on a network socket.
int io_sock_get_error(io_handle_t handle, int *perror)
Obtains and clears the current error number of a socket, and stores the value in *perror.
int io_sock_get_sockname(io_handle_t handle, io_addr_t *addr)
Obtains the locally-bound name of a socket and stores the resulting address in *addr.
int io_sock_set_sndbuf(io_handle_t handle, int size)
Sets the size (in bytes) of the send buffer of a socket.
int io_sock_get_peername(io_handle_t handle, io_addr_t *addr)
Obtains the peer address of a socket and stores the result in *addr.
int io_sock_get_rcvbuf(io_handle_t handle)
Obtains the size (in bytes) of the receive buffer of a socket.
int io_sock_get_broadcast(io_handle_t handle)
Checks if a socket is allowed to send broadcast messages.
int io_sock_get_type(io_handle_t handle)
Obtains the type of a network socket (the second parameter in a call to io_open_socket() or io_open_s...
int io_sock_get_maxconn(void)
Returns the maximum queue length for pending connections.
int io_sock_mcast_leave_source_group(io_handle_t handle, unsigned int index, const io_addr_t *group, const io_addr_t *source)
Leaves a source-specific multicast group.
int io_sock_get_keepalive(io_handle_t handle)
Checks if the TCP keep-alive option is enabled for a socket.
int io_sock_listen(io_handle_t handle, int backlog)
Marks a connection-mode socket (IO_SOCK_STREAM) as accepting connections.
int io_sock_get_acceptconn(io_handle_t handle)
Checks if a socket is currently listening for incoming connections.
ssize_t io_send(io_handle_t handle, const void *buf, size_t nbytes, const io_addr_t *addr, int flags)
Performs a send operation on a network socket.
int io_sock_get_mcast_ttl(io_handle_t handle)
Obtains the TTL (time to live) value for IP multicast traffic on a socket.
int io_sock_get_dontroute(io_handle_t handle)
Checks if routing is disabled for a socket.
int io_sock_get_domain(io_handle_t handle)
Obtains the domain of a socket (the first parameter in a call to io_open_socket() or io_open_socketpa...
int io_sock_mcast_block_source(io_handle_t handle, unsigned int index, const io_addr_t *group, const io_addr_t *source)
Blocks data from a given source to a given multicast group.
int io_sock_set_rcvtimeo(io_handle_t handle, int timeout)
Sets the timeout (in milliseconds) of a receive operation on a socket.
int io_sock_bind(io_handle_t handle, const io_addr_t *addr)
Binds a local network address to a socket.
io_handle_t io_accept(io_handle_t handle, io_addr_t *addr)
Accepts an incoming connection on a listening socket.
io_handle_t io_open_socket(int domain, int type)
Opens a network socket.
ssize_t io_sock_get_nread(io_handle_t handle)
Obtains the amount of data (in bytes) in the input buffer of a socket.
int io_sock_set_linger(io_handle_t handle, int time)
Sets the time (in seconds) io_close() will wait for unsent messages to be sent.
int io_sock_set_oobinline(io_handle_t handle, int oobinline)
Requests that out-of-band data is placed into the normal data stream of socket if oobinline is non-ze...
int io_sock_set_mcast_loop(io_handle_t handle, int loop)
Enables the loopback of outgoing multicast datagrams for a socket if loop is non-zero,...
int io_sock_get_sndbuf(io_handle_t handle)
Obtains the size (in bytes) of the send buffer of a socket.
int io_sock_set_rcvbuf(io_handle_t handle, int size)
Sets the size (in bytes) of the receive buffer of a socket.
int io_sock_set_keepalive(io_handle_t handle, int keepalive, int time, int interval)
Enables or disables the TCP keep-alive option for a socket (disabled by default).
int io_sock_mcast_join_group(io_handle_t handle, unsigned int index, const io_addr_t *group)
Joins an any-source multicast group.
int io_sock_set_dontroute(io_handle_t handle, int dontroute)
Bypasses normal routing for a socket if dontroute is non-zero, and disables this option otherwise (di...
int io_sock_get_reuseaddr(io_handle_t handle)
Checks if a socket is allowed to be bound to an address that is already in use.
int io_sock_get_debug(io_handle_t handle)
Checks if debugging is enabled for a socket.
int io_sock_set_tcp_nodelay(io_handle_t handle, int nodelay)
Disables Nagle's algorithm for send coalescing if nodelay is non-zero, and enables it otherwise.
int io_sock_get_linger(io_handle_t handle)
Obtains the linger time (in seconds) of a socket.
int io_sock_set_debug(io_handle_t handle, int debug)
Enables (platform dependent) debugging output for a socket if debug is non-zero, and disables this op...
int io_connect(io_handle_t handle, const io_addr_t *addr)
Connects a socket to a network address.
This header file is part of the I/O library; it contains the network socket declarations.
@ IO_SHUT_RD
Disables further receive operations.
@ IO_SHUT_RDWR
Disables further send and receive operations.
@ IO_SHUT_WR
Disables further send operations.
@ IO_MSG_OOB
Requests out-of-band data.
@ IO_MSG_PEEK
Peeks at incoming data.
@ IO_MSG_WAITALL
On stream-oriented sockets, block until the full amount of data can be returned.
@ IO_SOCK_DGRAM
A datagram-oriented, typically connectionless-mode, socket type.
@ IO_SOCK_STREAM
A stream-oriented connection-mode socket type.
@ IO_SOCK_IPV4
An IPv4 socket.
@ IO_SOCK_UNIX
A UNIX domain socket (only supported on POSIX platforms).
@ IO_SOCK_IPV6
An IPv6 socket.
@ IO_SOCK_BTH
A Bluetooth socket.
This is the internal header file of the Windows-specific I/O declarations.
This header file is part of the C11 and POSIX compatibility library; it includes <string....
An opaque network address type.
union __io_addr::@5 addr
The network address.
int addrlen
The size (in bytes) of addr.
The virtual table of an I/O device handle.
ssize_t(* send)(struct io_handle *handle, const void *buf, size_t nbytes, const io_addr_t *addr, int flags)
A pointer to the send method.
struct io_handle *(* accept)(struct io_handle *handle, io_addr_t *addr)
A pointer to the accept method.
int type
The type of the device (one of IO_TYPE_CAN, IO_TYPE_FILE, IO_TYPE_PIPE, IO_TYPE_SERIAL or IO_TYPE_SOC...
int(* connect)(struct io_handle *handle, const io_addr_t *addr)
A pointer to the connect method.
ssize_t(* recv)(struct io_handle *handle, void *buf, size_t nbytes, io_addr_t *addr, int flags)
A pointer to the recv method.
int fd
The native file descriptor.
int flags
The I/O device flags (any combination of IO_FLAG_NO_CLOSE and IO_FLAG_NONBLOCK).
const struct io_handle_vtab * vtab
A pointer to the virtual table.
int type
The type of the socket (IO_SOCK_STREAM or IO_SOCK_DGRAM).
struct io_handle base
The I/O device base handle.
int domain
The domain of the socket (one of IO_SOCK_BTH, IO_SOCK_IPV4, IO_SOCK_IPV6 or IO_SOCK_UNIX).