|
From: openocd-gerrit <ope...@us...> - 2026-03-08 10:14:23
|
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 0c6fe74351352fad03bd7115a38ef8c7c2ef83f6 (commit)
from 5b3db97c42b62e4c2559f3384120626b28401b4e (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 0c6fe74351352fad03bd7115a38ef8c7c2ef83f6
Author: Jan Matyas <jan...@co...>
Date: Mon Jan 5 07:20:37 2026 +0100
server: Make "exit" command behave consistently
Before this fix, the "exit" command behaved differently
depending on where it was called from:
- "exit" in a telnet session: Session disconnected.
- "exit" in a Tcl session: Empty response sent but the
session remained connected.
- "exit" in a script (outside of Telnet or Tcl): OpenOCD
exited with code 0. Based on the help and documentation
"exit" was apparently not intended for these cases.
What's more, if "exit" is allowed in Tcl scripts,
user may confuse it with the Tcl's native "exit"
command that is not available in OpenOCD (it is
shadowed with this OpenOCD's "exit" command).
This fix makes the behavior of "exit" consistent:
- "exit" in a telnet session: Session disconnected
(no change).
- "exit" in a Tcl session: Session disconnected
(same as for telnet).
- "exit" in a script: Notify the user that "exit"
is deprecated outside of telnet/tcl but
still shut down OpenOCD (to preserve the original
behavior).
Update the documentation to make it very clear to users
when to use "exit" vs. "shutdown".
Change-Id: I790495330e1fa705b34097a1347fdc57aaa86de1
Signed-off-by: Jan Matyas <jan...@co...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9380
Reviewed-by: Antonio Borneo <bor...@gm...>
Tested-by: jenkins
diff --git a/doc/openocd.texi b/doc/openocd.texi
index 579f39844..a21a3e4bd 100644
--- a/doc/openocd.texi
+++ b/doc/openocd.texi
@@ -9529,7 +9529,12 @@ port is 6666.
@section Server Commands
@deffn {Command} {exit}
-Exits the current telnet session.
+Exits the current telnet or Tcl session but the OpenOCD process remains running.
+This command should only be used in telnet or Tcl sessions (and not directly
+in Tcl scripts).
+
+Note: To terminate the whole OpenOCD process, use the
+@command{shutdown} command instead.
@end deffn
@deffn {Command} {help} [string]
diff --git a/src/server/server.c b/src/server/server.c
index 0b957836d..62c2ce821 100644
--- a/src/server/server.c
+++ b/src/server/server.c
@@ -783,6 +783,23 @@ COMMAND_HANDLER(handle_shutdown_command)
return ERROR_COMMAND_CLOSE_CONNECTION;
}
+COMMAND_HANDLER(handle_exit_command)
+{
+ if (!tcl_is_from_tcl_session(CMD_CTX)
+ && !telnet_is_from_telnet_session(CMD_CTX)) {
+ LOG_WARNING("DEPRECATED: 'exit' should only be used in telnet or Tcl "
+ "sessions to close the session");
+ LOG_WARNING("Did you mean 'shutdown'?");
+ return command_run_line(CMD_CTX, "shutdown");
+ }
+
+ if (CMD_ARGC != 0)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ /* Disconnect telnet / Tcl session */
+ return ERROR_COMMAND_CLOSE_CONNECTION;
+}
+
COMMAND_HANDLER(handle_poll_period_command)
{
if (CMD_ARGC == 0)
@@ -819,6 +836,13 @@ static const struct command_registration server_command_handlers[] = {
.usage = "",
.help = "shut the server down",
},
+ {
+ .name = "exit",
+ .handler = &handle_exit_command,
+ .mode = COMMAND_ANY,
+ .usage = "",
+ .help = "exit (disconnect) telnet or Tcl session",
+ },
{
.name = "poll_period",
.handler = &handle_poll_period_command,
diff --git a/src/server/tcl_server.c b/src/server/tcl_server.c
index 16cc55e29..929fbee0c 100644
--- a/src/server/tcl_server.c
+++ b/src/server/tcl_server.c
@@ -230,12 +230,22 @@ static int tcl_input(struct connection *connection)
#undef ESTR
} else {
tclc->tc_line[tclc->tc_lineoffset-1] = '\0';
- command_run_line(connection->cmd_ctx, tclc->tc_line);
+ retval = command_run_line(connection->cmd_ctx, tclc->tc_line);
+
+ if (retval == ERROR_COMMAND_CLOSE_CONNECTION) {
+ /* "shutdown" or "exit" executed.
+ * Send an empty response - just the response termination character.
+ */
+ tcl_output(connection, "\x1a", 1);
+ return ERROR_SERVER_REMOTE_CLOSED;
+ }
+
result = Jim_GetString(Jim_GetResult(interp), &reslen);
retval = tcl_output(connection, result, reslen);
if (retval != ERROR_OK)
return retval;
- /* Always output ctrl-z as end of line to allow multiline results */
+
+ /* Signal the end of response by a termination character (ctrl-z) */
tcl_output(connection, "\x1a", 1);
}
@@ -284,6 +294,15 @@ int tcl_init(void)
return add_service(&tcl_service_driver, tcl_port, CONNECTION_LIMIT_UNLIMITED, NULL);
}
+bool tcl_is_from_tcl_session(struct command_context *cmd_ctx)
+{
+ if (!cmd_ctx->output_handler_priv)
+ return false;
+
+ struct connection *conn = (struct connection *)cmd_ctx->output_handler_priv;
+ return strcmp(conn->service->name, "tcl") == 0;
+}
+
COMMAND_HANDLER(handle_tcl_port_command)
{
return CALL_COMMAND_HANDLER(server_pipe_command, &tcl_port);
@@ -297,7 +316,7 @@ COMMAND_HANDLER(handle_tcl_notifications_command)
if (CMD_CTX->output_handler_priv)
connection = CMD_CTX->output_handler_priv;
- if (connection && !strcmp(connection->service->name, "tcl")) {
+ if (connection && tcl_is_from_tcl_session(CMD_CTX)) {
tclc = connection->priv;
return CALL_COMMAND_HANDLER(handle_command_parse_bool, &tclc->tc_notify, "Target Notification output ");
} else {
@@ -314,7 +333,7 @@ COMMAND_HANDLER(handle_tcl_trace_command)
if (CMD_CTX->output_handler_priv)
connection = CMD_CTX->output_handler_priv;
- if (connection && !strcmp(connection->service->name, "tcl")) {
+ if (connection && tcl_is_from_tcl_session(CMD_CTX)) {
tclc = connection->priv;
return CALL_COMMAND_HANDLER(handle_command_parse_bool, &tclc->tc_trace, "Target trace output ");
} else {
diff --git a/src/server/tcl_server.h b/src/server/tcl_server.h
index bee562ce8..f92656f9c 100644
--- a/src/server/tcl_server.h
+++ b/src/server/tcl_server.h
@@ -12,5 +12,6 @@
int tcl_init(void);
int tcl_register_commands(struct command_context *cmd_ctx);
void tcl_service_free(void);
+bool tcl_is_from_tcl_session(struct command_context *ctx);
#endif /* OPENOCD_SERVER_TCL_SERVER_H */
diff --git a/src/server/telnet_server.c b/src/server/telnet_server.c
index 3634a2a59..ea7f38fb8 100644
--- a/src/server/telnet_server.c
+++ b/src/server/telnet_server.c
@@ -519,6 +519,7 @@ static int telnet_exec_line(struct connection *connection)
t_con->prompt_visible = true;
if (retval == ERROR_COMMAND_CLOSE_CONNECTION)
+ /* "shutdown" or "exit" executed. */
return ERROR_SERVER_REMOTE_CLOSED;
/* the prompt is always placed at the line beginning */
@@ -967,14 +968,14 @@ int telnet_init(char *banner)
return ERROR_OK;
}
-COMMAND_HANDLER(handle_telnet_port_command)
+bool telnet_is_from_telnet_session(struct command_context *cmd_ctx)
{
- return CALL_COMMAND_HANDLER(server_pipe_command, &telnet_port);
+ return cmd_ctx->output_handler == telnet_output;
}
-COMMAND_HANDLER(handle_exit_command)
+COMMAND_HANDLER(handle_telnet_port_command)
{
- return ERROR_COMMAND_CLOSE_CONNECTION;
+ return CALL_COMMAND_HANDLER(server_pipe_command, &telnet_port);
}
static const struct command_registration telnet_subcommand_handlers[] = {
@@ -991,13 +992,6 @@ static const struct command_registration telnet_subcommand_handlers[] = {
};
static const struct command_registration telnet_command_handlers[] = {
- {
- .name = "exit",
- .handler = handle_exit_command,
- .mode = COMMAND_ANY,
- .usage = "",
- .help = "exit telnet session",
- },
{
.name = "telnet",
.chain = telnet_subcommand_handlers,
diff --git a/src/server/telnet_server.h b/src/server/telnet_server.h
index 313b529f0..a905b4199 100644
--- a/src/server/telnet_server.h
+++ b/src/server/telnet_server.h
@@ -54,5 +54,6 @@ struct telnet_service {
int telnet_init(char *banner);
int telnet_register_commands(struct command_context *command_context);
void telnet_service_free(void);
+bool telnet_is_from_telnet_session(struct command_context *cmd_ctx);
#endif /* OPENOCD_SERVER_TELNET_SERVER_H */
-----------------------------------------------------------------------
Summary of changes:
doc/openocd.texi | 7 ++++++-
src/server/server.c | 24 ++++++++++++++++++++++++
src/server/tcl_server.c | 27 +++++++++++++++++++++++----
src/server/tcl_server.h | 1 +
src/server/telnet_server.c | 16 +++++-----------
src/server/telnet_server.h | 1 +
6 files changed, 60 insertions(+), 16 deletions(-)
hooks/post-receive
--
Main OpenOCD repository
|