diff --git a/src/base/remote_gdb.cc b/src/base/remote_gdb.cc index 1a2fef42d8..c8cb32fd71 100644 --- a/src/base/remote_gdb.cc +++ b/src/base/remote_gdb.cc @@ -392,7 +392,7 @@ std::map hardBreakMap; BaseRemoteGDB::BaseRemoteGDB(System *_system, int _port) : incomingConnectionEvent(nullptr), incomingDataEvent(nullptr), - _port(_port), fd(-1), sys(_system), + listener(_system->name() + ".remote_gdb", _port), fd(-1), sys(_system), connectEvent(*this), disconnectEvent(*this), trapEvent(this), singleStepEvent(*this) {} @@ -417,17 +417,14 @@ BaseRemoteGDB::listen() return; } - while (!listener.listen(_port)) { - DPRINTF(GDBMisc, "Can't bind port %d\n", _port); - _port++; - } + listener.listen(); incomingConnectionEvent = new IncomingConnectionEvent(this, listener.getfd(), POLLIN); pollQueue.schedule(incomingConnectionEvent); - ccprintf(std::cerr, "%d: %s: listening for remote gdb on port %d\n", - curTick(), name(), _port); + ccprintf(std::cerr, "%d: %s: listening for remote gdb on %s\n", + curTick(), name(), listener); } void @@ -448,12 +445,12 @@ BaseRemoteGDB::connect() } } -int -BaseRemoteGDB::port() const +const ListenSocket & +BaseRemoteGDB::hostSocket() const { panic_if(!listener.islistening(), - "Remote GDB port is unknown until listen() has been called.\n"); - return _port; + "Remote GDB socket is unknown until listen() has been called."); + return listener; } void diff --git a/src/base/remote_gdb.hh b/src/base/remote_gdb.hh index 80c108ba22..60a0d6a1eb 100644 --- a/src/base/remote_gdb.hh +++ b/src/base/remote_gdb.hh @@ -161,7 +161,7 @@ class BaseRemoteGDB void listen(); void connect(); - int port() const; + const ListenSocket &hostSocket() const; void attach(int fd); void detach(); @@ -232,7 +232,6 @@ class BaseRemoteGDB IncomingDataEvent *incomingDataEvent; ListenSocket listener; - int _port; // The socket commands come in through. int fd; diff --git a/src/base/socket.cc b/src/base/socket.cc index 280f92b593..1aff73a7ff 100644 --- a/src/base/socket.cc +++ b/src/base/socket.cc @@ -173,10 +173,12 @@ ListenSocket::acceptCloexec(int sockfd, struct sockaddr *addr, // // -ListenSocket::ListenSocket() - : listening(false), fd(-1) +ListenSocket::ListenSocket(const std::string &_name, int port) + : Named(_name), listening(false), fd(-1), _port(port) {} +ListenSocket::ListenSocket() : ListenSocket("", -1) {} + ListenSocket::~ListenSocket() { if (fd != -1) @@ -231,6 +233,23 @@ ListenSocket::listen(int port) return true; } +void +ListenSocket::listen() +{ + while (!listen(_port)) { + _port++; + fatal_if(_port > 65536, "%s: cannot find an available port.", name()); + } + ccprintf(std::cerr, "%s: Listening for connections on %s\n", + name(), *this); +} + +void +ListenSocket::output(std::ostream &os) const +{ + os << "port " << _port; +} + // Open a connection. Accept will block, so if you don't want it to, // make sure a connection is ready before you call accept. diff --git a/src/base/socket.hh b/src/base/socket.hh index d2393e9325..7a616bdd49 100644 --- a/src/base/socket.hh +++ b/src/base/socket.hh @@ -35,6 +35,8 @@ #include +#include "base/named.hh" + namespace gem5 { @@ -69,7 +71,7 @@ struct UnixSocketAddr std::string formattedPath; }; -class ListenSocket +class ListenSocket : public Named { protected: /** @@ -90,6 +92,7 @@ class ListenSocket protected: bool listening; int fd; + int _port; /* * cleanup resets the static variables back to their default values. @@ -101,12 +104,16 @@ class ListenSocket * @ingroup api_socket * @{ */ + ListenSocket(const std::string &_name, int port); ListenSocket(); virtual ~ListenSocket(); virtual int accept(); virtual bool listen(int port); + virtual void listen(); + + virtual void output(std::ostream &os) const; int getfd() const { return fd; } bool islistening() const { return listening; } @@ -119,6 +126,13 @@ class ListenSocket /** @} */ // end of api_socket }; +inline static std::ostream & +operator << (std::ostream &os, const ListenSocket &socket) +{ + socket.output(os); + return os; +} + } // namespace gem5 #endif //__SOCKET_HH__ diff --git a/src/base/vnc/vncserver.cc b/src/base/vnc/vncserver.cc index 39a1338799..2d32cef8bb 100644 --- a/src/base/vnc/vncserver.cc +++ b/src/base/vnc/vncserver.cc @@ -117,11 +117,11 @@ VncServer::DataEvent::process(int revent) */ VncServer::VncServer(const Params &p) : VncInput(p), listenEvent(NULL), dataEvent(NULL), number(p.number), - dataFd(-1), sendUpdate(false), + listener(p.name, p.port), sendUpdate(false), supportsRawEnc(false), supportsResizeEnc(false) { if (p.port) - listen(p.port); + listen(); curState = WaitForProtocolVersion; @@ -157,22 +157,14 @@ VncServer::~VncServer() //socket creation and vnc client attach void -VncServer::listen(int port) +VncServer::listen() { if (ListenSocket::allDisabled()) { warn_once("Sockets disabled, not accepting vnc client connections"); return; } - while (!listener.listen(port)) { - DPRINTF(VNC, - "can't bind address vnc server port %d in use PID %d\n", - port, getpid()); - port++; - } - - ccprintf(std::cerr, "%s: Listening for connections on port %d\n", - name(), port); + listener.listen(); listenEvent = new ListenEvent(this, listener.getfd(), POLLIN); pollQueue.schedule(listenEvent); diff --git a/src/base/vnc/vncserver.hh b/src/base/vnc/vncserver.hh index 091cb4d696..7455799025 100644 --- a/src/base/vnc/vncserver.hh +++ b/src/base/vnc/vncserver.hh @@ -182,7 +182,7 @@ class VncServer : public VncInput ListenSocket listener; - void listen(int port); + void listen(); void accept(); void data(); void detach(); diff --git a/src/cpu/nativetrace.cc b/src/cpu/nativetrace.cc index 714787ffa4..05fb41b3a5 100644 --- a/src/cpu/nativetrace.cc +++ b/src/cpu/nativetrace.cc @@ -39,17 +39,13 @@ namespace gem5 namespace trace { NativeTrace::NativeTrace(const Params &p) - : ExeTracer(p) + : ExeTracer(p), native_listener(p.name, 8000) { if (ListenSocket::allDisabled()) fatal("All listeners are disabled!"); - int port = 8000; - while (!native_listener.listen(port)) { - DPRINTF(GDBMisc, "Can't bind port %d\n", port); - port++; - } - ccprintf(std::cerr, "Listening for native process on port %d\n", port); + native_listener.listen(); + fd = native_listener.accept(); } diff --git a/src/dev/net/ethertap.cc b/src/dev/net/ethertap.cc index 0769ad1203..587dba5021 100644 --- a/src/dev/net/ethertap.cc +++ b/src/dev/net/ethertap.cc @@ -240,17 +240,16 @@ class TapListener }; friend class Event; - Event *event; + Event *event = nullptr; void accept(); protected: ListenSocket listener; EtherTapStub *tap; - int port; public: - TapListener(EtherTapStub *t, int p) : event(NULL), tap(t), port(p) {} + TapListener(EtherTapStub *t, int p) : listener(t->name(), p), tap(t) {} ~TapListener() { delete event; } void listen(); @@ -259,12 +258,8 @@ class TapListener void TapListener::listen() { - while (!listener.listen(port)) { - DPRINTF(Ethernet, "TapListener(listen): Can't bind port %d\n", port); - port++; - } + listener.listen(); - ccprintf(std::cerr, "Listening for tap connection on port %d\n", port); event = new Event(this, listener.getfd(), POLLIN|POLLERR); pollQueue.schedule(event); } diff --git a/src/dev/serial/terminal.cc b/src/dev/serial/terminal.cc index 9564876826..02052b5e1a 100644 --- a/src/dev/serial/terminal.cc +++ b/src/dev/serial/terminal.cc @@ -121,8 +121,8 @@ Terminal::DataEvent::process(int revent) */ Terminal::Terminal(const Params &p) : SerialDevice(p), listenEvent(NULL), dataEvent(NULL), - number(p.number), data_fd(-1), txbuf(16384), rxbuf(16384), - outfile(terminalDump(p)) + number(p.number), data_fd(-1), listener(p.name, p.port), + txbuf(16384), rxbuf(16384), outfile(terminalDump(p)) #if TRACING_ON == 1 , linebuf(16384) #endif @@ -131,7 +131,7 @@ Terminal::Terminal(const Params &p) outfile->stream()->setf(std::ios::unitbuf); if (p.port) - listen(p.port); + listen(); } Terminal::~Terminal() @@ -168,22 +168,14 @@ Terminal::terminalDump(const TerminalParams &p) // void -Terminal::listen(int port) +Terminal::listen() { if (ListenSocket::allDisabled()) { warn_once("Sockets disabled, not accepting terminal connections"); return; } - while (!listener.listen(port)) { - DPRINTF(Terminal, - ": can't bind address terminal port %d inuse PID %d\n", - port, getpid()); - port++; - } - - ccprintf(std::cerr, "%s: Listening for connections on port %d\n", - name(), port); + listener.listen(); listenEvent = new ListenEvent(this, listener.getfd(), POLLIN); pollQueue.schedule(listenEvent); diff --git a/src/dev/serial/terminal.hh b/src/dev/serial/terminal.hh index 83ea64b09c..bd6711da8a 100644 --- a/src/dev/serial/terminal.hh +++ b/src/dev/serial/terminal.hh @@ -103,7 +103,7 @@ class Terminal : public SerialDevice protected: ListenSocket listener; - void listen(int port); + void listen(); void accept(); protected: diff --git a/src/sim/workload.cc b/src/sim/workload.cc index ceb1029f77..84b1e40698 100644 --- a/src/sim/workload.cc +++ b/src/sim/workload.cc @@ -97,8 +97,8 @@ Workload::startup() // Now that we're about to start simulation, wait for GDB connections if // requested. if (gdb && waitForRemoteGDB) { - inform("%s: Waiting for a remote GDB connection on port %d.", name(), - gdb->port()); + inform("%s: Waiting for a remote GDB connection on %s.", name(), + gdb->hostSocket()); gdb->connect(); } }