21 #ifndef XAPIAN_INCLUDED_SAFESYSSOCKET_H
22 #define XAPIAN_INCLUDED_SAFESYSSOCKET_H
26 #include <sys/types.h>
28 # include <sys/socket.h>
34 # include <type_traits>
35 # if defined SOCK_CLOEXEC
36 static_assert(!
SOCK_CLOEXEC,
"__WIN32__ doesn't support SOCK_CLOEXEC");
38 # define SOCK_CLOEXEC 0
40 static_assert(std::is_unsigned_v<SOCKET>,
"SOCKET is unsigned");
42 inline int xapian_convert_socket_to_int_(SOCKET sock) {
62 if (
rare(sock > SOCKET(0x7fffffff) && sock != INVALID_SOCKET)) {
64 sock = INVALID_SOCKET;
66 WSASetLastError(WSAEMFILE);
71 inline int socket_(
int domain,
int type,
int protocol) {
72 return xapian_convert_socket_to_int_(socket(domain, type, protocol));
78 # define socket(D,T,P) socket_(D,T,P)
80 inline int accept_(
int sockfd,
struct sockaddr* addr,
SOCKLEN_T* addrlen) {
81 return xapian_convert_socket_to_int_(accept(sockfd, addr, addrlen));
87 # define accept(S,A,L) accept_(S,A,L)
95 inline int bind(SOCKET s,
const struct sockaddr* addr,
size_t addrlen) {
99 inline int connect(SOCKET s,
const struct sockaddr* addr,
size_t addrlen) {
100 return connect(s, addr,
SOCKLEN_T(addrlen));
103 #elif !defined SOCK_CLOEXEC
104 # define SOCK_CLOEXEC 0
111 inline int socket_(
int domain,
int type,
int protocol) {
115 int save_errno = errno;
116 int r = socket(domain, type, protocol);
117 if (r < 0 && errno == EINVAL) {
123 return socket(domain, type, protocol);
127 inline int socketpair_(
int domain,
int type,
int protocol,
int *sv) {
131 int save_errno = errno;
132 int r = socketpair(domain, type, protocol, sv);
133 if (r != 0 && errno == EINVAL) {
135 r = socketpair(domain, type &~
SOCK_CLOEXEC, protocol, sv);
139 return socketpair(domain, type, protocol, sv);
146 # define socket(D,T,P) socket_(D,T,P)
150 # define socketpair(D,T,P,S) socketpair_(D,T,P,S)
include <winsock2.h> but working around problems.