all repos — mgba @ 2ff580925222a8cc8012b641a0d4193986664257

mGBA Game Boy Advance Emulator

src/util/socket.h (view raw)

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