all repos — mgba @ 9c92a29b28d1f81224ba28d5fc83a9481eccd5eb

mGBA Game Boy Advance Emulator

src/util/socket.h (view raw)

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