aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/openocd.texi6
-rw-r--r--src/flash/startup.tcl4
-rw-r--r--src/helper/command.c36
-rw-r--r--src/helper/startup.tcl6
-rw-r--r--src/openocd.c14
-rw-r--r--src/server/server.c12
6 files changed, 48 insertions, 30 deletions
diff --git a/doc/openocd.texi b/doc/openocd.texi
index 4bec637f..e418e050 100644
--- a/doc/openocd.texi
+++ b/doc/openocd.texi
@@ -6486,8 +6486,10 @@ Useful in connection with script files
(@command{script} command and @command{target_name} configuration).
@end deffn
-@deffn Command shutdown
-Close the OpenOCD daemon, disconnecting all clients (GDB, telnet, other).
+@deffn Command shutdown [@option{error}]
+Close the OpenOCD daemon, disconnecting all clients (GDB, telnet,
+other). If option @option{error} is used, OpenOCD will return a
+non-zero exit code to the parent process.
@end deffn
@anchor{debuglevel}
diff --git a/src/flash/startup.tcl b/src/flash/startup.tcl
index 7a96a3e3..fbb8d8ee 100644
--- a/src/flash/startup.tcl
+++ b/src/flash/startup.tcl
@@ -8,8 +8,8 @@
proc program_error {description exit} {
if {$exit == 1} {
- echo $description
- shutdown
+ echo $description
+ shutdown error
}
error $description
diff --git a/src/helper/command.c b/src/helper/command.c
index 9d19cff4..a0aa9e85 100644
--- a/src/helper/command.c
+++ b/src/helper/command.c
@@ -121,7 +121,7 @@ static int command_retval_set(Jim_Interp *interp, int retval)
if (return_retval != NULL)
*return_retval = retval;
- return (retval == ERROR_OK) ? JIM_OK : JIM_ERR;
+ return (retval == ERROR_OK) ? JIM_OK : retval;
}
extern struct command_context *global_cmd_ctx;
@@ -659,24 +659,7 @@ int command_run_line(struct command_context *context, char *line)
}
Jim_DeleteAssocData(interp, "context");
}
- if (retcode == JIM_ERR) {
- if (retval == ERROR_COMMAND_CLOSE_CONNECTION) {
- /* Shutdown request is not an error */
- return ERROR_OK;
- } else {
- /* We do not print the connection closed error message */
- Jim_MakeErrorMessage(interp);
- LOG_USER("%s", Jim_GetString(Jim_GetResult(interp), NULL));
- }
- if (retval == ERROR_OK) {
- /* It wasn't a low level OpenOCD command that failed */
- return ERROR_FAIL;
- }
- return retval;
- } else if (retcode == JIM_EXIT) {
- /* ignore.
- * exit(Jim_GetExitCode(interp)); */
- } else {
+ if (retcode == JIM_OK) {
const char *result;
int reslen;
@@ -696,7 +679,22 @@ int command_run_line(struct command_context *context, char *line)
LOG_USER_N("\n");
}
retval = ERROR_OK;
+ } else if (retcode == JIM_EXIT) {
+ /* ignore.
+ * exit(Jim_GetExitCode(interp)); */
+ } else if (retcode == ERROR_COMMAND_CLOSE_CONNECTION) {
+ return retcode;
+ } else {
+ Jim_MakeErrorMessage(interp);
+ LOG_USER("%s", Jim_GetString(Jim_GetResult(interp), NULL));
+
+ if (retval == ERROR_OK) {
+ /* It wasn't a low level OpenOCD command that failed */
+ return ERROR_FAIL;
+ }
+ return retval;
}
+
return retval;
}
diff --git a/src/helper/startup.tcl b/src/helper/startup.tcl
index 926d26b6..4ca2cabc 100644
--- a/src/helper/startup.tcl
+++ b/src/helper/startup.tcl
@@ -16,10 +16,12 @@ proc exit {} {
proc ocd_bouncer {name args} {
set cmd [format "ocd_%s" $name]
set type [eval ocd_command type $cmd $args]
+ set errcode error
if {$type == "native"} {
return [eval $cmd $args]
} else {if {$type == "simple"} {
- if {[catch {eval $cmd $args}] == 0} {
+ set errcode [catch {eval $cmd $args}]
+ if {$errcode == 0} {
return ""
} else {
# 'classic' commands output error message as part of progress output
@@ -32,7 +34,7 @@ proc ocd_bouncer {name args} {
} else {
set errmsg [format "invalid subcommand \"%s\"" $args]
}}}
- return -code error $errmsg
+ return -code $errcode $errmsg
}
# Try flipping / and \ to find file if the filename does not
diff --git a/src/openocd.c b/src/openocd.c
index b0dd21ab..4d4dc2c8 100644
--- a/src/openocd.c
+++ b/src/openocd.c
@@ -283,7 +283,9 @@ static int openocd_thread(int argc, char *argv[], struct command_context *cmd_ct
return ERROR_FAIL;
ret = parse_config_file(cmd_ctx);
- if (ret != ERROR_OK)
+ if (ret == ERROR_COMMAND_CLOSE_CONNECTION)
+ return ERROR_OK;
+ else if (ret != ERROR_OK)
return ERROR_FAIL;
ret = server_init(cmd_ctx);
@@ -296,9 +298,15 @@ static int openocd_thread(int argc, char *argv[], struct command_context *cmd_ct
return ERROR_FAIL;
}
- server_loop(cmd_ctx);
+ ret = server_loop(cmd_ctx);
+
+ int last_signal = server_quit();
+ if (last_signal != ERROR_OK)
+ return last_signal;
- return server_quit();
+ if (ret != ERROR_OK)
+ return ERROR_FAIL;
+ return ERROR_OK;
}
/* normally this is the main() function entry, but if OpenOCD is linked
diff --git a/src/server/server.c b/src/server/server.c
index 73d8b5b6..7e90d89f 100644
--- a/src/server/server.c
+++ b/src/server/server.c
@@ -44,7 +44,8 @@
static struct service *services;
-/* shutdown_openocd == 1: exit the main event loop, and quit the debugger */
+/* shutdown_openocd == 1: exit the main event loop, and quit the
+ * debugger; 2: quit with non-zero return code */
static int shutdown_openocd;
/* store received signal to exit application by killing ourselves */
@@ -499,7 +500,7 @@ int server_loop(struct command_context *command_context)
#endif
}
- return ERROR_OK;
+ return shutdown_openocd != 2 ? ERROR_OK : ERROR_FAIL;
}
#ifdef _WIN32
@@ -608,6 +609,13 @@ COMMAND_HANDLER(handle_shutdown_command)
shutdown_openocd = 1;
+ if (CMD_ARGC == 1) {
+ if (!strcmp(CMD_ARGV[0], "error")) {
+ shutdown_openocd = 2;
+ return ERROR_FAIL;
+ }
+ }
+
return ERROR_COMMAND_CLOSE_CONNECTION;
}