|
From: openocd-gerrit <ope...@us...> - 2026-07-25 10:47:42
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Main OpenOCD repository".
The branch, master has been updated
via 43441cd83b229c106ab505cda047da116d454023 (commit)
from c064a1999f55c66cf85df9f9e4e1e0744e052fe0 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 43441cd83b229c106ab505cda047da116d454023
Author: Tim Hutt <td...@gm...>
Date: Mon Jul 13 08:42:15 2026 +0100
server: add 'services' command to list service information
This addes a 'services' command which outputs a TCL list
where each entry is a TCL dict containing information about
the service.
This allows obtaining the actual TCP port used when the
requested port is 0. Tested with the following script:
adapter driver dummy
gdb port 0
jtag newtap tap cpu -irlen 5
target create tap.cpu riscv -chain-position tap.cpu
init
echo [services]
shutdown
Output is:
...
Info : [tap.cpu] starting gdb server on 0
Info : Listening on port 53811 for gdb connections
{
name gdb
port 53811
target tap.cpu
}
Change-Id: I29bc2d352c0058f8b6a1c4296345f9ece4fbe03f
Signed-off-by: Tim Hutt <td...@gm...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9535
Tested-by: jenkins
Reviewed-by: Evgeniy Naydanov <eu...@gm...>
Reviewed-by: Antonio Borneo <bor...@gm...>
diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c
index 7c8bfee8e..40fda1e4e 100644
--- a/src/server/gdb_server.c
+++ b/src/server/gdb_server.c
@@ -27,6 +27,7 @@
#include "config.h"
#endif
+#include <helper/tcl-common.h>
#include <target/breakpoints.h>
#include <target/target_request.h>
#include <target/register.h>
@@ -3913,6 +3914,20 @@ static void gdb_keep_client_alive(struct connection *connection)
}
}
+static COMMAND_HELPER(gdb_service_info, const struct service *service)
+{
+ struct gdb_service *gdb_service = service->priv;
+
+ char *cmd_name = tcl_escape_alloc(CMD_CTX->interp, gdb_service->target->cmd_name);
+ if (!cmd_name) {
+ LOG_ERROR("Unable to escape Tcl string");
+ return ERROR_FAIL;
+ }
+ command_print(cmd, " target %s", cmd_name);
+ free(cmd_name);
+ return ERROR_OK;
+}
+
static const struct service_driver gdb_service_driver = {
.name = "gdb",
.new_connection_during_keep_alive_handler = NULL,
@@ -3920,6 +3935,7 @@ static const struct service_driver gdb_service_driver = {
.input_handler = gdb_input,
.connection_closed_handler = gdb_connection_closed,
.keep_client_alive_handler = gdb_keep_client_alive,
+ .service_info_handler = gdb_service_info,
};
static int gdb_target_start(struct target *target, const char *port)
diff --git a/src/server/server.c b/src/server/server.c
index dce626201..cee1028c4 100644
--- a/src/server/server.c
+++ b/src/server/server.c
@@ -16,6 +16,7 @@
#endif
#include "server.h"
+#include <helper/tcl-common.h>
#include <helper/time_support.h>
#include <target/target.h>
#include <target/target_request.h>
@@ -231,6 +232,7 @@ int add_service(const struct service_driver *driver, const char *port,
c->connection_closed = driver->connection_closed_handler;
c->keep_client_alive = driver->keep_client_alive_handler;
c->service_dtor = driver->service_dtor_handler;
+ c->service_info = driver->service_info_handler;
c->priv = priv;
c->next = NULL;
@@ -873,6 +875,51 @@ COMMAND_HANDLER(handle_bindto_command)
return ERROR_OK;
}
+COMMAND_HANDLER(handle_services_command)
+{
+ if (CMD_ARGC != 0)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ for (const struct service *s = services; s; s = s->next) {
+ command_print(CMD, "{");
+
+ /* Escape the name in case it contains special characters. */
+ char *escaped_name = tcl_escape_alloc(CMD_CTX->interp, s->name);
+ if (!escaped_name) {
+ command_print(CMD, "Unable to escape Tcl string");
+ return ERROR_FAIL;
+ }
+ command_print(CMD, " name %s", escaped_name);
+ free(escaped_name);
+
+ struct sockaddr_in addr_in;
+ addr_in.sin_port = 0;
+ socklen_t addr_in_size = sizeof(addr_in);
+ /* If it's a TCP connection and they specified port 0 try to get the real port. */
+ if (s->type == CONNECTION_TCP &&
+ s->portnumber == 0 &&
+ getsockname(s->fd, (struct sockaddr *)&addr_in, &addr_in_size) == 0) {
+ command_print(CMD, " port %hu", ntohs(addr_in.sin_port));
+ } else {
+ /* Need to escape port because it could be a FIFO path which is
+ * allowed to contain basically any character. */
+ char *escaped_port = tcl_escape_alloc(CMD_CTX->interp, s->port);
+ if (!escaped_port) {
+ command_print(CMD, "Unable to escape Tcl string");
+ return ERROR_FAIL;
+ }
+ command_print(CMD, " port %s", escaped_port);
+ free(escaped_port);
+ }
+
+ if (s->service_info)
+ CALL_COMMAND_HANDLER(s->service_info, s);
+
+ command_print(CMD, "}");
+ }
+ return ERROR_OK;
+}
+
static const struct command_registration server_command_handlers[] = {
{
.name = "shutdown",
@@ -903,6 +950,13 @@ static const struct command_registration server_command_handlers[] = {
.help = "Specify address by name on which to listen for "
"incoming TCP/IP connections",
},
+ {
+ .name = "services",
+ .handler = &handle_services_command,
+ .mode = COMMAND_ANY,
+ .usage = "",
+ .help = "return information about running services"
+ },
COMMAND_REGISTRATION_DONE
};
diff --git a/src/server/server.h b/src/server/server.h
index bf3758274..063a1fa34 100644
--- a/src/server/server.h
+++ b/src/server/server.h
@@ -59,6 +59,8 @@ struct service_driver {
/** callback to handle incoming data */
int (*input_handler)(struct connection *connection);
void (*service_dtor_handler)(struct service *service);
+ /** Callback to provide more details for the `services` command. */
+ COMMAND_HELPER((*service_info_handler), const struct service *service);
/** callback to tear down the connection */
int (*connection_closed_handler)(struct connection *connection);
/** called periodically to send keep-alive messages on the connection */
@@ -68,7 +70,12 @@ struct service_driver {
struct service {
char *name;
enum connection_type type;
+ /**
+ * The 'port', which can be an integer for TCP, or 'disabled',
+ * 'pipe' (stdin/out) or a FIFO path.
+ */
char *port;
+ /** If port is an integer it is parsed and saved here. */
unsigned short portnumber;
int fd;
struct sockaddr_in sin;
@@ -78,6 +85,7 @@ struct service {
int (*new_connection)(struct connection *connection);
int (*input)(struct connection *connection);
void (*service_dtor)(struct service *service);
+ COMMAND_HELPER((*service_info), const struct service *service);
int (*connection_closed)(struct connection *connection);
void (*keep_client_alive)(struct connection *connection);
void *priv;
-----------------------------------------------------------------------
Summary of changes:
src/server/gdb_server.c | 16 +++++++++++++++
src/server/server.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++
src/server/server.h | 8 ++++++++
3 files changed, 78 insertions(+)
hooks/post-receive
--
Main OpenOCD repository
|