From 20a5fa8476993eb5ca89b3d974641f65489b8dfa Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Mon, 3 Feb 2014 23:01:26 -0800 Subject: [PATCH] Abstract out sockets --- src/debugger/gdb-stub.c | 54 +++++++------------------- src/debugger/gdb-stub.h | 5 ++- src/util/socket.h | 84 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+), 42 deletions(-) create mode 100644 src/util/socket.h diff --git a/src/debugger/gdb-stub.c b/src/debugger/gdb-stub.c index 7ad1fe27d..b8759a12d 100644 --- a/src/debugger/gdb-stub.c +++ b/src/debugger/gdb-stub.c @@ -1,13 +1,8 @@ #include "gdb-stub.h" #include -#include -#include #include -#include #include -#include -#include enum GDBError { GDB_NO_ERROR = 0x00, @@ -50,15 +45,12 @@ static void _gdbStubEntered(struct ARMDebugger* debugger, enum DebuggerEntryReas 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 _gdbStubPoll(struct ARMDebugger* debugger) { 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 @@ static void _nak(struct GDBStub* stub) { 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 @@ static void _sendMessage(struct GDBStub* stub) { 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 _writeHostInfo(struct GDBStub* stub) { 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 @@ int GDBStubListen(struct GDBStub* stub, int port, uint32_t bindAddress) { 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) { + if (!SocketSetBlocking(stub->socket, 0)) { goto cleanup; } - int flags = fcntl(stub->socket, F_GETFL); - if (flags == -1) { - 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 GDBStubHangup(struct GDBStub* stub) { void GDBStubShutdown(struct GDBStub* stub) { GDBStubHangup(stub); if (stub->socket >= 0) { - close(stub->socket); + SocketClose(stub->socket); stub->socket = -1; } } @@ -508,13 +484,11 @@ void GDBStubUpdate(struct GDBStub* stub) { 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 @@ void GDBStubUpdate(struct GDBStub* stub) { } } 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; } diff --git a/src/debugger/gdb-stub.h b/src/debugger/gdb-stub.h index 5be0fd0ad..b60540edf 100644 --- a/src/debugger/gdb-stub.h +++ b/src/debugger/gdb-stub.h @@ -2,6 +2,7 @@ #define GDB_STUB_H #include "debugger.h" +#include "socket.h" #define GDB_STUB_MAX_LINE 1200 @@ -19,8 +20,8 @@ struct GDBStub { char outgoing[GDB_STUB_MAX_LINE]; enum GDBStubAckState lineAck; - int socket; - int connection; + Socket socket; + Socket connection; }; void GDBStubCreate(struct GDBStub*); diff --git a/src/util/socket.h b/src/util/socket.h new file mode 100644 index 000000000..1f643346e --- /dev/null +++ b/src/util/socket.h @@ -0,0 +1,84 @@ +#ifndef SOCKET_H +#define SOCKET_H + +#ifdef _WIN32 +#include + +typedef SOCKET Socket; +#else +#include +#include +#include +#include +#include + +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