all repos — mgba @ 968069ff5e9258ed6ceb1e033a6ebf84bd63cfa0

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