all repos — mgba @ 20a5fa8476993eb5ca89b3d974641f65489b8dfa

mGBA Game Boy Advance Emulator

Abstract out sockets
Jeffrey Pfau jeffrey@endrift.com
Mon, 03 Feb 2014 23:01:26 -0800
commit

20a5fa8476993eb5ca89b3d974641f65489b8dfa

parent

23e0737649091d592a12040702ce961def8d29ea

3 files changed, 101 insertions(+), 42 deletions(-)

jump to
M src/debugger/gdb-stub.csrc/debugger/gdb-stub.c

@@ -1,13 +1,8 @@

#include "gdb-stub.h" #include <errno.h> -#include <fcntl.h> -#include <netinet/in.h> #include <signal.h> -#include <stdio.h> #include <string.h> -#include <sys/socket.h> -#include <unistd.h> enum GDBError { GDB_NO_ERROR = 0x00,

@@ -50,15 +45,12 @@ }

static void _gdbStubPoll(struct ARMDebugger* debugger) { struct GDBStub* stub = (struct GDBStub*) debugger; - int flags; while (stub->d.state == DEBUGGER_PAUSED) { if (stub->connection >= 0) { - flags = fcntl(stub->connection, F_GETFL); - if (flags == -1) { + if (!SocketSetBlocking(stub->connection, 1)) { GDBStubHangup(stub); return; } - fcntl(stub->connection, F_SETFL, flags & ~O_NONBLOCK); } GDBStubUpdate(stub); }

@@ -66,7 +58,7 @@ }

static void _ack(struct GDBStub* stub) { char ack = '+'; - send(stub->connection, &ack, 1, 0); + SocketSend(stub->connection, &ack, 1); } static void _nak(struct GDBStub* stub) {

@@ -74,7 +66,7 @@ char nak = '-';

if (stub->d.log) { stub->d.log(&stub->d, DEBUGGER_LOG_WARN, "Packet error"); } - send(stub->connection, &nak, 1, 0); + SocketSend(stub->connection, &nak, 1); } static uint32_t _hex2int(const char* hex, int maxDigits) {

@@ -155,7 +147,7 @@ stub->outgoing[i + 3] = 0;

if (stub->d.log) { stub->d.log(&stub->d, DEBUGGER_LOG_DEBUG, "> %s", stub->outgoing); } - send(stub->connection, stub->outgoing, i + 3, 0); + SocketSend(stub->connection, stub->outgoing, i + 3); } static void _error(struct GDBStub* stub, enum GDBError error) {

@@ -171,12 +163,10 @@

static void _continue(struct GDBStub* stub, const char* message) { stub->d.state = DEBUGGER_RUNNING; if (stub->connection >= 0) { - int flags = fcntl(stub->connection, F_GETFL); - if (flags == -1) { + if (!SocketSetBlocking(stub->connection, 0)) { GDBStubHangup(stub); return; } - fcntl(stub->connection, F_SETFL, flags | O_NONBLOCK); } // TODO: parse message (void) (message);

@@ -445,34 +435,20 @@ if (stub->socket >= 0) {

GDBStubShutdown(stub); } // TODO: support IPv6 - stub->socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + stub->socket = SocketOpenTCP(port, bindAddress); if (stub->socket < 0) { if (stub->d.log) { stub->d.log(&stub->d, DEBUGGER_LOG_ERROR, "Couldn't open socket"); } return 0; } - - struct sockaddr_in bindInfo = { - .sin_family = AF_INET, - .sin_port = htons(port), - .sin_addr = { - .s_addr = htonl(bindAddress) - } - }; - int err = bind(stub->socket, (const struct sockaddr*) &bindInfo, sizeof(struct sockaddr_in)); + int err = SocketListen(stub->socket, 1); if (err) { goto cleanup; } - err = listen(stub->socket, 1); - if (err) { - goto cleanup; - } - int flags = fcntl(stub->socket, F_GETFL); - if (flags == -1) { + if (!SocketSetBlocking(stub->socket, 0)) { goto cleanup; } - fcntl(stub->socket, F_SETFL, flags | O_NONBLOCK); return 1;

@@ -480,14 +456,14 @@ cleanup:

if (stub->d.log) { stub->d.log(&stub->d, DEBUGGER_LOG_ERROR, "Couldn't listen on port"); } - close(stub->socket); + SocketClose(stub->socket); stub->socket = -1; return 0; } void GDBStubHangup(struct GDBStub* stub) { if (stub->connection >= 0) { - close(stub->connection); + SocketClose(stub->connection); stub->connection = -1; } if (stub->d.state == DEBUGGER_PAUSED) {

@@ -498,7 +474,7 @@

void GDBStubShutdown(struct GDBStub* stub) { GDBStubHangup(stub); if (stub->socket >= 0) { - close(stub->socket); + SocketClose(stub->socket); stub->socket = -1; } }

@@ -508,13 +484,11 @@ if (stub->socket == -1) {

return; } if (stub->connection == -1) { - stub->connection = accept(stub->socket, 0, 0); + stub->connection = SocketAccept(stub->socket, 0, 0); if (stub->connection >= 0) { - int flags = fcntl(stub->connection, F_GETFL); - if (flags == -1) { + if (!SocketSetBlocking(stub->connection, 0)) { goto connectionLost; } - fcntl(stub->connection, F_SETFL, flags | O_NONBLOCK); ARMDebuggerEnter(&stub->d, DEBUGGER_ENTER_ATTACHED); } else if (errno == EWOULDBLOCK || errno == EAGAIN) { return;

@@ -523,7 +497,7 @@ goto connectionLost;

} } while (1) { - ssize_t messageLen = recv(stub->connection, stub->line, GDB_STUB_MAX_LINE - 1, 0); + ssize_t messageLen = SocketRecv(stub->connection, stub->line, GDB_STUB_MAX_LINE - 1); if (messageLen == 0) { goto connectionLost; }
M src/debugger/gdb-stub.hsrc/debugger/gdb-stub.h

@@ -2,6 +2,7 @@ #ifndef GDB_STUB_H

#define GDB_STUB_H #include "debugger.h" +#include "socket.h" #define GDB_STUB_MAX_LINE 1200

@@ -19,8 +20,8 @@ char line[GDB_STUB_MAX_LINE];

char outgoing[GDB_STUB_MAX_LINE]; enum GDBStubAckState lineAck; - int socket; - int connection; + Socket socket; + Socket connection; }; void GDBStubCreate(struct GDBStub*);
A src/util/socket.h

@@ -0,0 +1,84 @@

+#ifndef SOCKET_H +#define SOCKET_H + +#ifdef _WIN32 +#include <winsock2.h> + +typedef SOCKET Socket; +#else +#include <fcntl.h> +#include <netinet/in.h> +#include <stdio.h> +#include <sys/socket.h> +#include <unistd.h> + +typedef int Socket; +#endif + + +void SocketSubsystemInitialize() { +#ifdef _WIN32 + WSAStartup(MAKEWORD(2, 2), 0); +#endif +} + +ssize_t SocketSend(Socket socket, const void* buffer, size_t size) { + return write(socket, buffer, size); +} + +ssize_t SocketRecv(Socket socket, void* buffer, size_t size) { + return read(socket, buffer, size); +} + +Socket SocketOpenTCP(int port, uint32_t bindAddress) { + Socket sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + if (sock < 0) { + return sock; + } + + struct sockaddr_in bindInfo = { + .sin_family = AF_INET, + .sin_port = htons(port), + .sin_addr = { + .s_addr = htonl(bindAddress) + } + }; + int err = bind(sock, (const struct sockaddr*) &bindInfo, sizeof(struct sockaddr_in)); + if (err) { + close(sock); + return -1; + } + return sock; +} + +Socket SocketListen(Socket socket, int queueLength) { + return listen(socket, queueLength); +} + +Socket SocketAccept(Socket socket, struct sockaddr* restrict address, socklen_t* restrict addressLength) { + return accept(socket, address, addressLength); +} + +int SocketClose(Socket socket) { + return close(socket) >= 0; +} + +int SocketSetBlocking(Socket socket, int blocking) { +#ifdef _WIN32 + blocking = !blocking; + return ioctlsocket(socket, FIONBIO, &blocking) == NO_ERROR; +#else + int flags = fcntl(socket, F_GETFL); + if (flags == -1) { + return 0; + } + if (blocking) { + flags &= ~O_NONBLOCK; + } else { + flags |= O_NONBLOCK; + } + return fcntl(socket, F_SETFL, flags) >= 0; +#endif +} + +#endif