89 lines
2.5 KiB
C
89 lines
2.5 KiB
C
/**
|
|
* Единые socket_t, коды ошибок и wrappers сокетов POSIX/Windows (включая MSYS2 UCRT64).
|
|
* platform_init/cleanup обслуживают Winsock; UDP/nonblocking/options/sendto/recvfrom — операции ОС.
|
|
* Созданные сокеты закрывает владелец через socket_close_wrapper; event loop находится в u_async.h.
|
|
*/
|
|
|
|
#ifndef SOCKET_COMPAT_H
|
|
#define SOCKET_COMPAT_H
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#include <stdint.h>
|
|
|
|
#ifdef _WIN32
|
|
#include <winsock2.h>
|
|
#include <ws2tcpip.h>
|
|
|
|
typedef SOCKET socket_t;
|
|
#define SOCKET_INVALID INVALID_SOCKET
|
|
#define SOCKET_ERROR_CODE SOCKET_ERROR
|
|
|
|
// Error codes
|
|
#define ERR_WOULDBLOCK WSAEWOULDBLOCK
|
|
#define ERR_AGAIN WSAEWOULDBLOCK
|
|
#define ERR_INTR WSAEINTR
|
|
|
|
#else
|
|
// POSIX systems
|
|
#include <sys/socket.h>
|
|
#include <arpa/inet.h>
|
|
#include <netinet/in.h>
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
#include <errno.h>
|
|
#include <string.h>
|
|
|
|
typedef int socket_t;
|
|
#define SOCKET_INVALID (-1)
|
|
#define SOCKET_ERROR_CODE (-1)
|
|
|
|
#define ERR_WOULDBLOCK EWOULDBLOCK
|
|
#define ERR_AGAIN EAGAIN
|
|
#define ERR_INTR EINTR
|
|
#endif
|
|
|
|
// Platform initialization/cleanup
|
|
int socket_platform_init(void);
|
|
void socket_platform_cleanup(void);
|
|
|
|
// Socket operations
|
|
socket_t socket_create_udp(int family);
|
|
int socket_set_nonblocking(socket_t sock);
|
|
int socket_close_wrapper(socket_t sock);
|
|
static inline int socket_get_error(void) {
|
|
#ifdef _WIN32
|
|
return WSAGetLastError();
|
|
#else
|
|
return errno;
|
|
#endif
|
|
}
|
|
|
|
// Socket options
|
|
int socket_set_buffers(socket_t sock, int sndbuf, int rcvbuf);
|
|
int socket_set_reuseaddr(socket_t sock, int reuse);
|
|
int socket_bind_to_device(socket_t sock, const char* ifname);
|
|
int socket_set_mark(socket_t sock, int mark);
|
|
|
|
// I/O operations
|
|
ssize_t socket_sendto(socket_t sock, const void* buf, size_t len,
|
|
const struct sockaddr* dest, socklen_t dest_len);
|
|
ssize_t socket_recvfrom(socket_t sock, void* buf, size_t len,
|
|
struct sockaddr* src, socklen_t* src_len);
|
|
|
|
// Utility
|
|
const char* socket_strerror(int err);
|
|
|
|
// взять порт из sockaddr_storage
|
|
uint16_t ss_get_port(const struct sockaddr_storage *addr);
|
|
// Фактический IPv4/IPv6-порт уже привязанного сокета; 0 при ошибке.
|
|
uint16_t socket_get_bound_port(socket_t sock);
|
|
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
#endif // SOCKET_COMPAT_H
|