all repos — mgba @ 4da65d0f2f041e2db4874087e1e0d8da5a2d96be

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 __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 = {
 52			.s_addr = htonl(bindAddress)
 53		}
 54	};
 55	int err = bind(sock, (const struct sockaddr*) &bindInfo, sizeof(struct sockaddr_in));
 56	if (err) {
 57		close(sock);
 58		return -1;
 59	}
 60	return sock;
 61}
 62
 63static inline Socket SocketConnectTCP(int port, uint32_t destinationAddress) {
 64	Socket sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
 65	if (SOCKET_FAILED(sock)) {
 66		return sock;
 67	}
 68
 69	struct sockaddr_in bindInfo = {
 70		.sin_family = AF_INET,
 71		.sin_port = htons(port),
 72		.sin_addr = {
 73			.s_addr = htonl(destinationAddress)
 74		}
 75	};
 76	int err = connect(sock, (const struct sockaddr*) &bindInfo, sizeof(struct sockaddr_in));
 77	if (err) {
 78		close(sock);
 79		return -1;
 80	}
 81	return sock;
 82}
 83
 84static inline Socket SocketListen(Socket socket, int queueLength) {
 85	return listen(socket, queueLength);
 86}
 87
 88static inline Socket SocketAccept(Socket socket, struct sockaddr* restrict address, socklen_t* restrict addressLength) {
 89	return accept(socket, address, addressLength);
 90}
 91
 92static inline int SocketClose(Socket socket) {
 93	return close(socket) >= 0;
 94}
 95
 96static inline int SocketSetBlocking(Socket socket, int blocking) {
 97#ifdef _WIN32
 98	u_long unblocking = !blocking;
 99	return ioctlsocket(socket, FIONBIO, &unblocking) == NO_ERROR;
100#else
101	int flags = fcntl(socket, F_GETFL);
102	if (flags == -1) {
103		return 0;
104	}
105	if (blocking) {
106		flags &= ~O_NONBLOCK;
107	} else {
108		flags |= O_NONBLOCK;
109	}
110	return fcntl(socket, F_SETFL, flags) >= 0;
111#endif
112}
113
114static inline int SocketSetTCPPush(Socket socket, int push) {
115	return setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (char*) &push, sizeof(int)) >= 0;
116}
117
118#endif