all repos — mgba @ 64e8d3fb832a69689ac3753af7b9f6c0a05e648a

mGBA Game Boy Advance Emulator

src/util/socket.h (view raw)

  1#ifndef SOCKET_H
  2#define SOCKET_H
  3
  4#include "common.h"
  5
  6#ifdef _WIN32
  7#include <winsock2.h>
  8#include <ws2tcpip.h>
  9
 10#define SOCKET_FAILED(s) (s) == INVALID_SOCKET
 11typedef SOCKET Socket;
 12#else
 13#include <fcntl.h>
 14#include <netinet/in.h>
 15#include <netinet/tcp.h>
 16#include <sys/socket.h>
 17
 18#define INVALID_SOCKET (-1)
 19#define SOCKET_FAILED(s) (s) < 0
 20typedef int Socket;
 21#endif
 22
 23
 24static inline void SocketSubsystemInitialize() {
 25#ifdef _WIN32
 26	WSAStartup(MAKEWORD(2, 2), 0);
 27#endif
 28}
 29
 30static inline ssize_t SocketSend(Socket socket, const void* buffer, size_t size) {
 31	return write(socket, buffer, size);
 32}
 33
 34static inline ssize_t SocketRecv(Socket socket, void* buffer, size_t size) {
 35	return read(socket, buffer, size);
 36}
 37
 38static inline Socket SocketOpenTCP(int port, uint32_t bindAddress) {
 39	Socket sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
 40	if (SOCKET_FAILED(sock)) {
 41		return sock;
 42	}
 43
 44	struct sockaddr_in bindInfo = {
 45		.sin_family = AF_INET,
 46		.sin_port = htons(port),
 47		.sin_addr = {
 48			.s_addr = htonl(bindAddress)
 49		}
 50	};
 51	int err = bind(sock, (const struct sockaddr*) &bindInfo, sizeof(struct sockaddr_in));
 52	if (err) {
 53		close(sock);
 54		return -1;
 55	}
 56	return sock;
 57}
 58
 59static inline Socket SocketConnectTCP(int port, uint32_t destinationAddress) {
 60	Socket sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
 61	if (SOCKET_FAILED(sock)) {
 62		return sock;
 63	}
 64
 65	struct sockaddr_in bindInfo = {
 66		.sin_family = AF_INET,
 67		.sin_port = htons(port),
 68		.sin_addr = {
 69			.s_addr = htonl(destinationAddress)
 70		}
 71	};
 72	int err = connect(sock, (const struct sockaddr*) &bindInfo, sizeof(struct sockaddr_in));
 73	if (err) {
 74		close(sock);
 75		return -1;
 76	}
 77	return sock;
 78}
 79
 80static inline Socket SocketListen(Socket socket, int queueLength) {
 81	return listen(socket, queueLength);
 82}
 83
 84static inline Socket SocketAccept(Socket socket, struct sockaddr* restrict address, socklen_t* restrict addressLength) {
 85	return accept(socket, address, addressLength);
 86}
 87
 88static inline int SocketClose(Socket socket) {
 89	return close(socket) >= 0;
 90}
 91
 92static inline int SocketSetBlocking(Socket socket, int blocking) {
 93#ifdef _WIN32
 94	u_long unblocking = !blocking;
 95	return ioctlsocket(socket, FIONBIO, &unblocking) == NO_ERROR;
 96#else
 97	int flags = fcntl(socket, F_GETFL);
 98	if (flags == -1) {
 99		return 0;
100	}
101	if (blocking) {
102		flags &= ~O_NONBLOCK;
103	} else {
104		flags |= O_NONBLOCK;
105	}
106	return fcntl(socket, F_SETFL, flags) >= 0;
107#endif
108}
109
110static inline int SocketSetTCPPush(Socket socket, int push) {
111	return setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (char*) &push, sizeof(int)) >= 0;
112}
113
114#endif