(@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}
proc program_error {description exit} {
if {$exit == 1} {
- echo $description
- shutdown
+ echo $description
+ shutdown error
}
error $description
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;
}
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;
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;
}
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
} 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
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);
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
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 */
#endif
}
- return ERROR_OK;
+ return shutdown_openocd != 2 ? ERROR_OK : ERROR_FAIL;
}
#ifdef _WIN32
shutdown_openocd = 1;
+ if (CMD_ARGC == 1) {
+ if (!strcmp(CMD_ARGV[0], "error")) {
+ shutdown_openocd = 2;
+ return ERROR_FAIL;
+ }
+ }
+
return ERROR_COMMAND_CLOSE_CONNECTION;
}