Abstract out sockets

This commit is contained in:
Jeffrey Pfau 2014-02-03 23:01:26 -08:00
parent 23e0737649
commit 20a5fa8476
3 changed files with 101 additions and 42 deletions

View File

@ -1,13 +1,8 @@
#include "gdb-stub.h" #include "gdb-stub.h"
#include <errno.h> #include <errno.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <signal.h> #include <signal.h>
#include <stdio.h>
#include <string.h> #include <string.h>
#include <sys/socket.h>
#include <unistd.h>
enum GDBError { enum GDBError {
GDB_NO_ERROR = 0x00, GDB_NO_ERROR = 0x00,
@ -50,15 +45,12 @@ static void _gdbStubEntered(struct ARMDebugger* debugger, enum DebuggerEntryReas
static void _gdbStubPoll(struct ARMDebugger* debugger) { static void _gdbStubPoll(struct ARMDebugger* debugger) {
struct GDBStub* stub = (struct GDBStub*) debugger; struct GDBStub* stub = (struct GDBStub*) debugger;
int flags;
while (stub->d.state == DEBUGGER_PAUSED) { while (stub->d.state == DEBUGGER_PAUSED) {
if (stub->connection >= 0) { if (stub->connection >= 0) {
flags = fcntl(stub->connection, F_GETFL); if (!SocketSetBlocking(stub->connection, 1)) {
if (flags == -1) {
GDBStubHangup(stub); GDBStubHangup(stub);
return; return;
} }
fcntl(stub->connection, F_SETFL, flags & ~O_NONBLOCK);
} }
GDBStubUpdate(stub); GDBStubUpdate(stub);
} }
@ -66,7 +58,7 @@ static void _gdbStubPoll(struct ARMDebugger* debugger) {
static void _ack(struct GDBStub* stub) { static void _ack(struct GDBStub* stub) {
char ack = '+'; char ack = '+';
send(stub->connection, &ack, 1, 0); SocketSend(stub->connection, &ack, 1);
} }
static void _nak(struct GDBStub* stub) { static void _nak(struct GDBStub* stub) {
@ -74,7 +66,7 @@ static void _nak(struct GDBStub* stub) {
if (stub->d.log) { if (stub->d.log) {
stub->d.log(&stub->d, DEBUGGER_LOG_WARN, "Packet error"); 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) { static uint32_t _hex2int(const char* hex, int maxDigits) {
@ -155,7 +147,7 @@ static void _sendMessage(struct GDBStub* stub) {
if (stub->d.log) { if (stub->d.log) {
stub->d.log(&stub->d, DEBUGGER_LOG_DEBUG, "> %s", stub->outgoing); 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) { 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) { static void _continue(struct GDBStub* stub, const char* message) {
stub->d.state = DEBUGGER_RUNNING; stub->d.state = DEBUGGER_RUNNING;
if (stub->connection >= 0) { if (stub->connection >= 0) {
int flags = fcntl(stub->connection, F_GETFL); if (!SocketSetBlocking(stub->connection, 0)) {
if (flags == -1) {
GDBStubHangup(stub); GDBStubHangup(stub);
return; return;
} }
fcntl(stub->connection, F_SETFL, flags | O_NONBLOCK);
} }
// TODO: parse message // TODO: parse message
(void) (message); (void) (message);
@ -445,34 +435,20 @@ int GDBStubListen(struct GDBStub* stub, int port, uint32_t bindAddress) {
GDBStubShutdown(stub); GDBStubShutdown(stub);
} }
// TODO: support IPv6 // TODO: support IPv6
stub->socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); stub->socket = SocketOpenTCP(port, bindAddress);
if (stub->socket < 0) { if (stub->socket < 0) {
if (stub->d.log) { if (stub->d.log) {
stub->d.log(&stub->d, DEBUGGER_LOG_ERROR, "Couldn't open socket"); stub->d.log(&stub->d, DEBUGGER_LOG_ERROR, "Couldn't open socket");
} }
return 0; return 0;
} }
int err = SocketListen(stub->socket, 1);
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));
if (err) { if (err) {
goto cleanup; goto cleanup;
} }
err = listen(stub->socket, 1); if (!SocketSetBlocking(stub->socket, 0)) {
if (err) {
goto cleanup; goto cleanup;
} }
int flags = fcntl(stub->socket, F_GETFL);
if (flags == -1) {
goto cleanup;
}
fcntl(stub->socket, F_SETFL, flags | O_NONBLOCK);
return 1; return 1;
@ -480,14 +456,14 @@ cleanup:
if (stub->d.log) { if (stub->d.log) {
stub->d.log(&stub->d, DEBUGGER_LOG_ERROR, "Couldn't listen on port"); stub->d.log(&stub->d, DEBUGGER_LOG_ERROR, "Couldn't listen on port");
} }
close(stub->socket); SocketClose(stub->socket);
stub->socket = -1; stub->socket = -1;
return 0; return 0;
} }
void GDBStubHangup(struct GDBStub* stub) { void GDBStubHangup(struct GDBStub* stub) {
if (stub->connection >= 0) { if (stub->connection >= 0) {
close(stub->connection); SocketClose(stub->connection);
stub->connection = -1; stub->connection = -1;
} }
if (stub->d.state == DEBUGGER_PAUSED) { if (stub->d.state == DEBUGGER_PAUSED) {
@ -498,7 +474,7 @@ void GDBStubHangup(struct GDBStub* stub) {
void GDBStubShutdown(struct GDBStub* stub) { void GDBStubShutdown(struct GDBStub* stub) {
GDBStubHangup(stub); GDBStubHangup(stub);
if (stub->socket >= 0) { if (stub->socket >= 0) {
close(stub->socket); SocketClose(stub->socket);
stub->socket = -1; stub->socket = -1;
} }
} }
@ -508,13 +484,11 @@ void GDBStubUpdate(struct GDBStub* stub) {
return; return;
} }
if (stub->connection == -1) { if (stub->connection == -1) {
stub->connection = accept(stub->socket, 0, 0); stub->connection = SocketAccept(stub->socket, 0, 0);
if (stub->connection >= 0) { if (stub->connection >= 0) {
int flags = fcntl(stub->connection, F_GETFL); if (!SocketSetBlocking(stub->connection, 0)) {
if (flags == -1) {
goto connectionLost; goto connectionLost;
} }
fcntl(stub->connection, F_SETFL, flags | O_NONBLOCK);
ARMDebuggerEnter(&stub->d, DEBUGGER_ENTER_ATTACHED); ARMDebuggerEnter(&stub->d, DEBUGGER_ENTER_ATTACHED);
} else if (errno == EWOULDBLOCK || errno == EAGAIN) { } else if (errno == EWOULDBLOCK || errno == EAGAIN) {
return; return;
@ -523,7 +497,7 @@ void GDBStubUpdate(struct GDBStub* stub) {
} }
} }
while (1) { 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) { if (messageLen == 0) {
goto connectionLost; goto connectionLost;
} }

View File

@ -2,6 +2,7 @@
#define GDB_STUB_H #define GDB_STUB_H
#include "debugger.h" #include "debugger.h"
#include "socket.h"
#define GDB_STUB_MAX_LINE 1200 #define GDB_STUB_MAX_LINE 1200
@ -19,8 +20,8 @@ struct GDBStub {
char outgoing[GDB_STUB_MAX_LINE]; char outgoing[GDB_STUB_MAX_LINE];
enum GDBStubAckState lineAck; enum GDBStubAckState lineAck;
int socket; Socket socket;
int connection; Socket connection;
}; };
void GDBStubCreate(struct GDBStub*); void GDBStubCreate(struct GDBStub*);

84
src/util/socket.h Normal file
View File

@ -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