37#if _WIN32 || _POSIX_C_SOURCE >= 200112L
52static void sock_fini(
struct io_handle *handle);
54static ssize_t sock_read(
struct io_handle *handle,
void *buf,
size_t nbytes);
55static ssize_t sock_write(
56 struct io_handle *handle,
const void *buf,
size_t nbytes);
57static ssize_t sock_recv(
struct io_handle *handle,
void *buf,
size_t nbytes,
59static ssize_t sock_send(
struct io_handle *handle,
const void *buf,
65 .size =
sizeof(
struct sock),
72 .accept = &sock_accept,
73 .connect = &sock_connect };
75static int _socketpair(
int af,
int type,
int protocol, SOCKET sv[2]);
83#if defined(__CYGWIN__) || defined(__linux__)
84 flags |= SOCK_CLOEXEC;
93 s = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
98#elif defined(__linux__) && defined(HAVE_BLUETOOTH_BLUETOOTH_H) \
99 && defined(HAVE_BLUETOOTH_RFCOMM_H)
103 s = socket(AF_BLUETOOTH, SOCK_STREAM | flags,
113 s = socket(AF_INET, SOCK_STREAM | flags, 0);
116 s = socket(AF_INET, SOCK_DGRAM | flags, 0);
124 s = socket(AF_INET6, SOCK_STREAM | flags, 0);
127 s = socket(AF_INET6, SOCK_DGRAM | flags, 0);
132#if _POSIX_C_SOURCE >= 200112L
136 s = socket(AF_UNIX, SOCK_STREAM | flags, 0);
139 s = socket(AF_UNIX, SOCK_DGRAM | flags, 0);
148 if (s == INVALID_SOCKET) {
153#if _POSIX_C_SOURCE >= 200112L && !defined(__CYGINW__) && !defined(__linux__)
154 if (fcntl(s, F_SETFD, FD_CLOEXEC) == -1) {
163 goto error_alloc_handle;
166 handle->
fd = (HANDLE)s;
168 ((
struct sock *)handle)->type =
type;
173#if _POSIX_C_SOURCE >= 200112L && !defined(__CYGINW__) && !defined(__linux__)
187 assert(handle_vector);
193#if defined(__CYGWIN__) || defined(__linux__)
194 flags |= SOCK_CLOEXEC;
198 SOCKET socket_vector[2];
203 result = _socketpair(AF_INET, SOCK_STREAM | flags, 0,
207 result = _socketpair(AF_INET, SOCK_DGRAM | flags, 0,
216 result = _socketpair(AF_INET6, SOCK_STREAM | flags, 0,
220 result = _socketpair(AF_INET6, SOCK_DGRAM | flags, 0,
226#if _POSIX_C_SOURCE >= 200112L
230 result = _socketpair(AF_UNIX, SOCK_STREAM | flags, 0,
234 result = _socketpair(AF_UNIX, SOCK_DGRAM | flags, 0,
244 if (result == SOCKET_ERROR) {
246 goto error_socketpair;
249#if _POSIX_C_SOURCE >= 200112L && !defined(__CYGINW__) && !defined(__linux__)
250 if (fcntl(socket_vector[0], F_SETFD, FD_CLOEXEC) == -1) {
254 if (fcntl(socket_vector[1], F_SETFD, FD_CLOEXEC) == -1) {
261 if (!handle_vector[0]) {
263 goto error_alloc_handle_vector_0;
266 handle_vector[0]->
fd = (HANDLE)socket_vector[0];
267 ((
struct sock *)handle_vector[0])->domain =
domain;
268 ((
struct sock *)handle_vector[0])->type =
type;
271 if (!handle_vector[1]) {
273 goto error_alloc_handle_vector_1;
276 handle_vector[1]->
fd = (HANDLE)socket_vector[1];
277 ((
struct sock *)handle_vector[1])->domain =
domain;
278 ((
struct sock *)handle_vector[1])->type =
type;
285error_alloc_handle_vector_1:
288error_alloc_handle_vector_0:
290#if _POSIX_C_SOURCE >= 200112L && !defined(__CYGINW__) && !defined(__linux__)
293 closesocket(socket_vector[1]);
294 closesocket(socket_vector[0]);
313 assert(handle->
vtab);
319 return handle->
vtab->
recv(handle, buf, nbytes, addr, flags);
331 assert(handle->
vtab);
337 return handle->
vtab->
send(handle, buf, nbytes, addr, flags);
348 assert(handle->
vtab);
365 assert(handle->
vtab);
374#if _WIN32 || _POSIX_C_SOURCE >= 200112L
384 if (handle->
vtab != &sock_vtab) {
389 return ((
struct sock *)handle)->domain;
400 if (handle->
vtab != &sock_vtab) {
405 return ((
struct sock *)handle)->type;
418 return bind((SOCKET)handle->
fd, (
const struct sockaddr *)&addr->
addr,
430 return listen((SOCKET)handle->
fd, backlog) ? -1 : 0;
466 return shutdown((SOCKET)handle->
fd, how) ? -1 : 0;
482 return getsockname((SOCKET)handle->
fd, (
struct sockaddr *)&addr->
addr,
483 (socklen_t *)&addr->
addrlen) ? -1 : 0;
487 int result = getsockname(handle->
fd, (
struct sockaddr *)&addr->
addr,
490 if (!result || errno != EINVAL
494 return getsockname(handle->
fd, (
struct sockaddr *)&addr->
addr,
512 return getpeername((SOCKET)handle->
fd, (
struct sockaddr *)&addr->
addr,
513 (socklen_t *)&addr->
addrlen) ? -1 : 0;
517 int result = getpeername(handle->
fd, (
struct sockaddr *)&addr->
addr,
520 if (!result || errno != EINVAL
524 return getpeername(handle->
fd, (
struct sockaddr *)&addr->
addr,
549 if (getsockopt((SOCKET)handle->
fd, SOL_SOCKET, SO_ACCEPTCONN,
550 (
char *)&optval, &(socklen_t){ sizeof(optval) }))
570 if (getsockopt((SOCKET)handle->
fd, SOL_SOCKET, SO_BROADCAST,
571 (
char *)&optval, &(socklen_t){ sizeof(optval) }))
586 BOOL optval = !!broadcast;
588 int optval = !!broadcast;
591 return setsockopt((SOCKET)handle->
fd, SOL_SOCKET, SO_BROADCAST,
592 (
const char *)&optval,
sizeof(optval)) ? -1 : 0;
610 if (getsockopt((SOCKET)handle->
fd, SOL_SOCKET, SO_DEBUG,
611 (
char *)&optval, &(socklen_t){ sizeof(optval) }))
626 BOOL optval = !!debug;
628 int optval = !!debug;
631 return setsockopt((SOCKET)handle->
fd, SOL_SOCKET, SO_DEBUG,
632 (
const char *)&optval,
sizeof(optval)) ? -1 : 0;
650 if (getsockopt((SOCKET)handle->
fd, SOL_SOCKET, SO_DONTROUTE,
651 (
char *)&optval, &(socklen_t){ sizeof(optval) }))
666 BOOL optval = !!dontroute;
668 int optval = !!dontroute;
671 return setsockopt((SOCKET)handle->
fd, SOL_SOCKET, SO_DONTROUTE,
672 (
const char *)&optval,
sizeof(optval)) ? -1 : 0;
685 return getsockopt((SOCKET)handle->
fd, SOL_SOCKET, SO_ERROR,
686 (
char *)perror, &(socklen_t){ sizeof(*perror) })
705 if (getsockopt((SOCKET)handle->
fd, SOL_SOCKET, SO_KEEPALIVE,
706 (
char *)&optval, &(socklen_t){ sizeof(optval) }))
721 struct tcp_keepalive kaInBuffer = { .onoff = keepalive,
723 .keepalivetime = time * 1000,
725 .keepaliveinterval = interval * 1000 };
726 DWORD dwBytesReturned;
728 return WSAIoctl((SOCKET)handle->
fd, SIO_KEEPALIVE_VALS, &kaInBuffer,
729 sizeof(kaInBuffer), NULL, 0, &dwBytesReturned, NULL,
734 if (setsockopt(handle->
fd, SOL_SOCKET, SO_KEEPALIVE, &keepalive,
735 sizeof(keepalive)) == -1)
741 if (setsockopt(handle->
fd, SOL_TCP, TCP_KEEPIDLE, &time,
746 if (setsockopt(handle->
fd, SOL_TCP, TCP_KEEPINTVL, &interval,
747 sizeof(interval)) == -1)
767 struct linger optval;
769 if (getsockopt((SOCKET)handle->
fd, SOL_SOCKET, SO_LINGER,
770 (
char *)&optval, &(socklen_t){ sizeof(optval) }))
773 return optval.l_onoff ? optval.l_linger : 0;
789 struct linger optval = { !!time, time };
791 return setsockopt((SOCKET)handle->
fd, SOL_SOCKET, SO_LINGER,
792 (
const char *)&optval,
sizeof(optval)) ? -1 : 0;
810 if (getsockopt((SOCKET)handle->
fd, SOL_SOCKET, SO_OOBINLINE,
811 (
char *)&optval, &(socklen_t){ sizeof(optval) }))
826 BOOL optval = !!oobinline;
828 int optval = !!oobinline;
831 return setsockopt((SOCKET)handle->
fd, SOL_SOCKET, SO_OOBINLINE,
832 (
const char *)&optval,
sizeof(optval)) ? -1 : 0;
846 if (getsockopt((SOCKET)handle->
fd, SOL_SOCKET, SO_RCVBUF,
847 (
char *)&optval, &(socklen_t){ sizeof(optval) }))
862 return setsockopt((SOCKET)handle->
fd, SOL_SOCKET, SO_RCVBUF,
863 (
const char *)&size,
sizeof(size)) ? -1 : 0;
876 DWORD optval = timeout;
878 struct timeval optval = { .tv_sec = timeout / 1000,
879 .tv_usec = (timeout % 1000) * 1000 };
882 return setsockopt((SOCKET)handle->
fd, SOL_SOCKET, SO_RCVTIMEO,
883 (
const char *)&optval,
sizeof(optval)) ? -1 : 0;
901 if (getsockopt((SOCKET)handle->
fd, SOL_SOCKET, SO_REUSEADDR,
902 (
char *)&optval, &(socklen_t){ sizeof(optval) }))
917 BOOL optval = !!reuseaddr;
919 int optval = !!reuseaddr;
922 return setsockopt((SOCKET)handle->
fd, SOL_SOCKET, SO_REUSEADDR,
923 (
const char *)&optval,
sizeof(optval)) ? -1 : 0;
937 if (getsockopt((SOCKET)handle->
fd, SOL_SOCKET, SO_SNDBUF,
938 (
char *)&optval, &(socklen_t){ sizeof(optval) }))
953 return setsockopt((SOCKET)handle->
fd, SOL_SOCKET, SO_SNDBUF,
954 (
const char *)&size,
sizeof(size)) ? -1 : 0;
967 DWORD optval = timeout;
969 struct timeval optval = { .tv_sec = timeout / 1000,
970 .tv_usec = (timeout % 1000) * 1000 };
973 return setsockopt((SOCKET)handle->
fd, SOL_SOCKET, SO_SNDTIMEO,
974 (
const char *)&optval,
sizeof(optval)) ? -1 : 0;
992 if (getsockopt((SOCKET)handle->
fd, IPPROTO_TCP, TCP_NODELAY,
993 (
char *)&optval, &(socklen_t){ sizeof(optval) }))
1008 BOOL optval = !!nodelay;
1010 int optval = !!nodelay;
1013 return setsockopt((SOCKET)handle->
fd, IPPROTO_TCP, TCP_NODELAY,
1014 (
const char *)&optval,
sizeof(optval)) ? -1 : 0;
1018#if _WIN32 || defined(HAVE_SYS_IOCTL_H)
1029 if (ioctlsocket((SOCKET)handle->
fd, FIONREAD, &optval))
1038 result = ioctl(handle->
fd, FIONREAD, &optval);
1039 }
while (result == -1 && errno == EINTR);
1047#if _WIN32 || defined(__CYGWIN__) || defined(__linux__)
1057 if (handle->
vtab != &sock_vtab) {
1067 switch (((
struct sock *)handle)->domain) {
1070 if (getsockopt((SOCKET)handle->
fd, IPPROTO_IP,
1071 IP_MULTICAST_LOOP, (
char *)&optval,
1072 &(socklen_t){ sizeof(optval) }))
1078 if (getsockopt((SOCKET)handle->
fd, IPPROTO_IPV6,
1079 IPV6_MULTICAST_LOOP, (
char *)&optval,
1080 &(socklen_t){ sizeof(optval) }))
1097 if (handle->
vtab != &sock_vtab) {
1103 DWORD optval = !!loop;
1105 int optval = !!loop;
1107 switch (((
struct sock *)handle)->domain) {
1110 return setsockopt((SOCKET)handle->
fd, IPPROTO_IP,
1111 IP_MULTICAST_LOOP, (
const char *)&optval,
1112 sizeof(optval)) ? -1 : 0;
1116 return setsockopt((SOCKET)handle->
fd, IPPROTO_IPV6,
1117 IPV6_MULTICAST_LOOP, (
const char *)&optval,
1118 sizeof(optval)) ? -1 : 0;
1132 if (handle->
vtab != &sock_vtab) {
1142 switch (((
struct sock *)handle)->domain) {
1145 if (getsockopt((SOCKET)handle->
fd, IPPROTO_IP, IP_MULTICAST_TTL,
1147 &(socklen_t){ sizeof(optval) }))
1153 if (getsockopt((SOCKET)handle->
fd, IPPROTO_IPV6,
1154 IPV6_MULTICAST_HOPS, (
char *)&optval,
1155 &(socklen_t){ sizeof(optval) }))
1172 if (handle->
vtab != &sock_vtab) {
1182 switch (((
struct sock *)handle)->domain) {
1185 return setsockopt((SOCKET)handle->
fd, IPPROTO_IP,
1186 IP_MULTICAST_TTL, (
const char *)&optval,
1187 sizeof(optval)) ? -1 : 0;
1191 return setsockopt((SOCKET)handle->
fd, IPPROTO_IPV6,
1192 IPV6_MULTICAST_HOPS, (
const char *)&optval,
1193 sizeof(optval)) ? -1 :0;
1210 if (handle->
vtab != &sock_vtab) {
1215 struct group_req greq;
1216 memset(&greq, 0,
sizeof(greq));
1217 greq.gr_interface = index;
1218 memcpy(&greq.gr_group, &group->
addr,
sizeof(greq.gr_group));
1224 return setsockopt((SOCKET)handle->
fd, level, MCAST_JOIN_GROUP,
1225 (
const char *)&greq,
sizeof(greq)) ? 0 : -1;
1241 if (handle->
vtab != &sock_vtab) {
1246 struct group_source_req greq;
1247 memset(&greq, 0,
sizeof(greq));
1248 greq.gsr_interface = index;
1249 memcpy(&greq.gsr_group, &group->
addr,
sizeof(greq.gsr_group));
1250 memcpy(&greq.gsr_source, &source->
addr,
sizeof(greq.gsr_source));
1256 return setsockopt((SOCKET)handle->
fd, level, MCAST_BLOCK_SOURCE,
1257 (
const char *)&greq,
sizeof(greq)) ? -1 : 0;
1273 if (handle->
vtab != &sock_vtab) {
1278 struct group_source_req greq;
1279 memset(&greq, 0,
sizeof(greq));
1280 greq.gsr_interface = index;
1281 memcpy(&greq.gsr_group, &group->
addr,
sizeof(greq.gsr_group));
1282 memcpy(&greq.gsr_source, &source->
addr,
sizeof(greq.gsr_source));
1288 return setsockopt((SOCKET)handle->
fd, level, MCAST_UNBLOCK_SOURCE,
1289 (
const char *)&greq,
sizeof(greq)) ? -1 : 0;
1304 if (handle->
vtab != &sock_vtab) {
1309 struct group_req greq;
1310 memset(&greq, 0,
sizeof(greq));
1311 greq.gr_interface = index;
1312 memcpy(&greq.gr_group, &group->
addr,
sizeof(greq.gr_group));
1318 return setsockopt((SOCKET)handle->
fd, level, MCAST_LEAVE_GROUP,
1319 (
const char *)&greq,
sizeof(greq)) ? -1 : 0;
1335 if (handle->
vtab != &sock_vtab) {
1340 struct group_source_req greq;
1341 memset(&greq, 0,
sizeof(greq));
1342 greq.gsr_interface = index;
1343 memcpy(&greq.gsr_group, &group->
addr,
sizeof(greq.gsr_group));
1344 memcpy(&greq.gsr_source, &source->
addr,
sizeof(greq.gsr_source));
1350 return setsockopt((SOCKET)handle->
fd, level, MCAST_JOIN_SOURCE_GROUP,
1351 (
const char *)&greq,
sizeof(greq)) ? -1 : 0;
1364 if (handle->
vtab != &sock_vtab) {
1369 struct group_source_req greq;
1370 memset(&greq, 0,
sizeof(greq));
1371 greq.gsr_interface = index;
1372 memcpy(&greq.gsr_group, &group->
addr,
sizeof(greq.gsr_group));
1373 memcpy(&greq.gsr_source, &source->
addr,
sizeof(greq.gsr_source));
1379 return setsockopt((SOCKET)handle->
fd, level, MCAST_LEAVE_SOURCE_GROUP,
1380 (
const char *)&greq,
sizeof(greq)) ? -1 : 0;
1390 closesocket((SOCKET)handle->
fd);
1394sock_flags(
struct io_handle *handle,
int flags)
1400 return ioctlsocket((SOCKET)handle->
fd, FIONBIO, &iMode) ? -1 : 0;
1402 int arg = fcntl(handle->
fd, F_GETFL, 0);
1407 return fcntl(handle->
fd, F_SETFL, arg | O_NONBLOCK);
1409 return fcntl(handle->
fd, F_SETFL, arg & ~O_NONBLOCK);
1415sock_read(
struct io_handle *handle,
void *buf,
size_t nbytes)
1417 return sock_recv(handle, buf, nbytes, NULL, 0);
1421sock_write(
struct io_handle *handle,
const void *buf,
size_t nbytes)
1423 return sock_send(handle, buf, nbytes, NULL, 0);
1438 _flags |= MSG_WAITALL;
1444 result = recvfrom((SOCKET)handle->
fd, buf, nbytes, _flags,
1450 result = recvfrom(handle->
fd, buf, nbytes, _flags,
1451 (
struct sockaddr *)&addr->
addr,
1453 }
while (result == -1 && errno == EINTR);
1457 result = recv((SOCKET)handle->
fd, buf, nbytes, _flags);
1462 result = recv(handle->
fd, buf, nbytes, _flags);
1463 }
while (result == -1 && errno == EINTR);
1466 return result == SOCKET_ERROR ? -1 : result;
1470sock_send(
struct io_handle *handle,
const void *buf,
size_t nbytes,
1479 _flags |= MSG_NOSIGNAL;
1486 ? sendto((SOCKET)handle->
fd, buf, nbytes, _flags,
1487 (
const struct sockaddr *)&addr->
addr, addr->
addrlen)
1488 : send((SOCKET)handle->fd, buf, nbytes, _flags);
1496 ? sendto(handle->
fd, buf, nbytes, _flags,
1497 (
const struct sockaddr *)&addr->
addr,
1499 : send(handle->fd, buf, nbytes, _flags);
1501 }
while (result == -1 && errno == EINTR);
1503 return result == SOCKET_ERROR ? -1 : result;
1518 s = accept((SOCKET)handle->
fd, (
struct sockaddr *)&addr->
addr,
1525 s = accept4(handle->
fd, (
struct sockaddr *)&addr->
addr,
1529 s = accept(handle->
fd, (
struct sockaddr *)&addr->
addr,
1532 }
while (s == -1 && errno == EINTR);
1536 s = accept((SOCKET)handle->
fd, NULL, NULL);
1542 s = accept4(handle->
fd, NULL, NULL, SOCK_CLOEXEC);
1544 s = accept(handle->
fd, NULL, NULL);
1546 }
while (s == -1 && errno == EINTR);
1550 if (s == INVALID_SOCKET) {
1555#if _POSIX_C_SOURCE >= 200112L && !defined(_GNU_SOURCE)
1556 if (fcntl(s, F_SETFD, FD_CLOEXEC) == -1) {
1565 goto error_alloc_handle;
1568 handle->
fd = (HANDLE)s;
1575#if _POSIX_C_SOURCE >= 200112L && !defined(_GNU_SOURCE)
1595 return connect((SOCKET)handle->
fd, (
const struct sockaddr *)&addr->
addr,
1603 result = connect(handle->
fd,
1604 (
const struct sockaddr *)&addr->
addr,
1606 }
while (result == -1 && errno == EINTR);
1612_socketpair(
int af,
int type,
int protocol, SOCKET sv[2])
1615 sv[0] = sv[1] = INVALID_SOCKET;
1617#if _POSIX_C_SOURCE >= 200112L
1619 return socketpair(af,
type, protocol, sv);
1624 if (af != AF_INET && af != AF_INET6) {
1630#if defined(__CYGWIN__) || defined(__linux__)
1631 flags =
type & (SOCK_NONBLOCK | SOCK_CLOEXEC);
1635 if (
type != SOCK_STREAM &&
type != SOCK_DGRAM) {
1640 sv[0] = socket(af,
type | flags, protocol);
1641 if (sv[0] == INVALID_SOCKET) {
1643 goto error_socket_0;
1646 sv[1] = socket(af,
type | flags, protocol);
1647 if (sv[1] == INVALID_SOCKET) {
1649 goto error_socket_1;
1652 struct sockaddr_storage name[2];
1653 struct sockaddr *name_0 = (
struct sockaddr *)&name[0];
1654 struct sockaddr_in *name_in_0 = (
struct sockaddr_in *)name_0;
1655 struct sockaddr_in6 *name_in6_0 = (
struct sockaddr_in6 *)name_0;
1656 struct sockaddr *name_1 = (
struct sockaddr *)&name[1];
1657 struct sockaddr_in *name_in_1 = (
struct sockaddr_in *)name_1;
1658 struct sockaddr_in6 *name_in6_1 = (
struct sockaddr_in6 *)name_1;
1659 socklen_t namelen_0, namelen_1;
1661 if (af == AF_INET) {
1662 name_in_1->sin_family = AF_INET;
1663 name_in_1->sin_port = 0;
1664 name_in_1->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1665 namelen_1 =
sizeof(*name_in_1);
1667 name_in6_1->sin6_family = AF_INET6;
1668 name_in6_1->sin6_port = 0;
1669 name_in6_1->sin6_addr = in6addr_loopback;
1670 namelen_1 =
sizeof(*name_in6_1);
1673 if (bind(sv[1], name_1, namelen_1) == SOCKET_ERROR) {
1677 if (getsockname(sv[1], name_1, &namelen_1) == SOCKET_ERROR) {
1679 goto error_getsockname_1;
1682 if (type == SOCK_STREAM) {
1683 if (listen(sv[1], 1) == SOCKET_ERROR) {
1688 if (af == AF_INET) {
1689 name_in_0->sin_family = AF_INET;
1690 name_in_0->sin_port = 0;
1691 name_in_0->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1692 namelen_0 =
sizeof(*name_in_0);
1694 name_in6_0->sin6_family = AF_INET6;
1695 name_in6_0->sin6_port = 0;
1696 name_in6_0->sin6_addr = in6addr_loopback;
1697 namelen_0 =
sizeof(*name_in6_0);
1700 if (bind(sv[0], name_0, namelen_0) == SOCKET_ERROR) {
1704 if (getsockname(sv[0], name_0, &namelen_0) == SOCKET_ERROR) {
1706 goto error_getsockname_0;
1711 name_in_1->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1713 name_in6_1->sin6_addr = in6addr_loopback;
1714 if (connect(sv[0], name_1, namelen_1) == SOCKET_ERROR) {
1716 goto error_connect_0;
1719 if (type == SOCK_STREAM) {
1720 SOCKET s = accept(sv[1], NULL, NULL);
1721 if (s == INVALID_SOCKET) {
1729 name_in_0->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1731 name_in6_0->sin6_addr = in6addr_loopback;
1732 if (connect(sv[1], name_0, namelen_0) == SOCKET_ERROR) {
1734 goto error_connect_1;
1749 sv[1] = INVALID_SOCKET;
1752 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.
struct io_handle *(* accept)(struct io_handle *handle, io_addr_t *addr)
A pointer to the accept method.
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.
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).