package = io.ktor.utils.io.internal.utils.test
compilerOpts.mingw_x64 = -DMINGW
---

#include <limits.h>

#ifdef MINGW
#include <winsock2.h>
#include <fcntl.h>
#include <errno.h>

static inline int make_socket_non_blocking(SOCKET fd) {
    int mode = 1;
    return (ioctlsocket(fd, FIONBIO, &mode) == 0) ? 1 : 0;
}

static inline void close_socket(SOCKET socket) {
    closesocket(socket);
}

static inline void set_no_delay(SOCKET socket) {
    int one = 1;
    setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (char*)&one, sizeof(int));
}

static inline int socket_get_error() {
    int rc = WSAGetLastError();
    if (rc == WSAEWOULDBLOCK) return EAGAIN;
    if (rc == WSAEINPROGRESS) return EINPROGRESS;
    if (rc == WSAEISCONN || rc == WSAEALREADY) return EISCONN;
    else return rc;
}

static inline int kx_init_sockets() {
    WSADATA data;

    if (WSAStartup(0x0202, &data) == 0) return 1;
    return 0;
}

#else

#include <errno.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <unistd.h>

static inline int make_socket_non_blocking(int fd) {
    int flags = fcntl(fd, F_GETFL, 0);
    if (flags == -1) return 0;
    flags = (flags | O_NONBLOCK);
    return (fcntl(fd, F_SETFL, flags) == 0) ? 0 : 1;
}

static inline void close_socket(int socket) {
    close(socket);
}

static inline void set_no_delay(int socket) {
    int one = 1;
    setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(int));
}

static inline int socket_get_error() {
    return errno;
}

static inline int kx_init_sockets() {
    return 1;
}

#endif

static inline void set_loopback(struct sockaddr_in * zzzz) {
    zzzz->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
}

