bool_t hdhomerun_sock_send(hdhomerun_sock_t sock, const void *data, size_t length, uint64_t timeout) { uint64_t stop_time = getcurrenttime() + timeout; const uint8_t *ptr = (uint8_t *)data; while (1) { int ret = send(sock, (char *)ptr, (int)length, 0); if (ret >= (int)length) { return TRUE; } if (ret > 0) { ptr += ret; length -= ret; } if (WSAGetLastError() != WSAEWOULDBLOCK) { return FALSE; } if (!hdhomerun_sock_wait_for_event(sock, FD_WRITE | FD_CLOSE, stop_time)) { return FALSE; } } }
bool_t hdhomerun_sock_recvfrom(hdhomerun_sock_t sock, uint32_t *remote_addr, uint16_t *remote_port, void *data, size_t *length, uint64_t timeout) { uint64_t stop_time = getcurrenttime() + timeout; while (1) { struct sockaddr_in sock_addr; memset(&sock_addr, 0, sizeof(sock_addr)); int sockaddr_size = sizeof(sock_addr); int ret = recvfrom(sock, (char *)data, (int)(*length), 0, (struct sockaddr *)&sock_addr, &sockaddr_size); if (ret < 0) { if (WSAGetLastError() != WSAEWOULDBLOCK) { return FALSE; } if (!hdhomerun_sock_wait_for_event(sock, FD_READ | FD_CLOSE, stop_time)) { return FALSE; } continue; } if (ret == 0) { return FALSE; } *remote_addr = ntohl(sock_addr.sin_addr.s_addr); *remote_port = ntohs(sock_addr.sin_port); *length = ret; return TRUE; } }
bool_t hdhomerun_sock_sendto(hdhomerun_sock_t sock, uint32_t remote_addr, uint16_t remote_port, const void *data, size_t length, uint64_t timeout) { uint64_t stop_time = getcurrenttime() + timeout; const uint8_t *ptr = (uint8_t *)data; while (1) { struct sockaddr_in sock_addr; memset(&sock_addr, 0, sizeof(sock_addr)); sock_addr.sin_family = AF_INET; sock_addr.sin_addr.s_addr = htonl(remote_addr); sock_addr.sin_port = htons(remote_port); int ret = sendto(sock, (char *)ptr, (int)length, 0, (struct sockaddr *)&sock_addr, sizeof(sock_addr)); if (ret <= 0) { if (WSAGetLastError() != WSAEWOULDBLOCK) { return FALSE; } if (!hdhomerun_sock_wait_for_event(sock, FD_WRITE | FD_CLOSE, stop_time)) { return FALSE; } continue; } if (ret < (int)length) { ptr += ret; length -= ret; continue; } return TRUE; } }
bool_t hdhomerun_sock_connect(hdhomerun_sock_t sock, uint32_t remote_addr, uint16_t remote_port, uint64_t timeout) { struct sockaddr_in sock_addr; memset(&sock_addr, 0, sizeof(sock_addr)); sock_addr.sin_family = AF_INET; sock_addr.sin_addr.s_addr = htonl(remote_addr); sock_addr.sin_port = htons(remote_port); if (connect(sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) != 0) { if ((errno != EAGAIN) && (errno != EWOULDBLOCK) && (errno != EINPROGRESS)) { return FALSE; } } uint64_t stop_time = getcurrenttime() + timeout; return hdhomerun_sock_wait_for_event(sock, POLLOUT, stop_time); }
bool_t hdhomerun_sock_recv(hdhomerun_sock_t sock, void *data, size_t *length, uint64_t timeout) { uint64_t stop_time = getcurrenttime() + timeout; while (1) { int ret = recv(sock, (char *)data, (int)(*length), 0); if (ret > 0) { *length = ret; return TRUE; } if (WSAGetLastError() != WSAEWOULDBLOCK) { return FALSE; } if (!hdhomerun_sock_wait_for_event(sock, FD_READ | FD_CLOSE, stop_time)) { return FALSE; } } }
bool_t hdhomerun_sock_recv(hdhomerun_sock_t sock, void *data, size_t *length, uint64_t timeout) { uint64_t stop_time = getcurrenttime() + timeout; while (1) { int ret = recv(sock, data, *length, 0); if (ret < 0) { if ((errno != EAGAIN) && (errno != EWOULDBLOCK) && (errno != EINPROGRESS)) { return FALSE; } if (!hdhomerun_sock_wait_for_event(sock, POLLIN, stop_time)) { return FALSE; } continue; } if (ret == 0) { return FALSE; } *length = ret; return TRUE; } }