X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fserver%2Fserver.c;h=7e90d89fd2d6af7d1a3cc89b80a70186e84a6c6e;hp=96f06b3feff65095bde1d1697a1c85b8ca806b55;hb=19f219f731f29503c8e4d432935d3ea558cc1659;hpb=210ff6028480df93f483131d6c6ca1f7f372aa2a diff --git a/src/server/server.c b/src/server/server.c index 96f06b3fef..7e90d89fd2 100644 --- a/src/server/server.c +++ b/src/server/server.c @@ -21,7 +21,7 @@ * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -31,6 +31,7 @@ #include "server.h" #include #include +#include #include "openocd.h" #include "tcl_server.h" #include "telnet_server.h" @@ -43,9 +44,16 @@ 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 */ +static int last_signal; + +/* set the polling period to 100ms */ +static int polling_period = 100; + static int add_connection(struct service *service, struct command_context *cmd_ctx) { socklen_t address_size; @@ -80,11 +88,12 @@ static int add_connection(struct service *service, struct command_context *cmd_c (char *)&flag, /* the cast is historical cruft */ sizeof(int)); /* length of option value */ - LOG_INFO("accepting '%s' connection from %s", service->name, service->port); + LOG_INFO("accepting '%s' connection on tcp/%s", service->name, service->port); retval = service->new_connection(c); if (retval != ERROR_OK) { close_socket(c->fd); LOG_ERROR("attempted '%s' connection rejected", service->name); + command_done(c->cmd_ctx); free(c); return retval; } @@ -104,6 +113,7 @@ static int add_connection(struct service *service, struct command_context *cmd_c retval = service->new_connection(c); if (retval != ERROR_OK) { LOG_ERROR("attempted '%s' connection rejected", service->name); + command_done(c->cmd_ctx); free(c); return retval; } @@ -124,6 +134,7 @@ static int add_connection(struct service *service, struct command_context *cmd_c retval = service->new_connection(c); if (retval != ERROR_OK) { LOG_ERROR("attempted '%s' connection rejected", service->name); + command_done(c->cmd_ctx); free(c); return retval; } @@ -300,14 +311,14 @@ static int remove_services(void) struct service *next = c->next; if (c->name) - free((void *)c->name); + free(c->name); if (c->type == CONNECTION_PIPE) { if (c->fd != -1) close(c->fd); } if (c->port) - free((void *)c->port); + free(c->port); if (c->priv) free(c->priv); @@ -377,8 +388,8 @@ int server_loop(struct command_context *command_context) tv.tv_usec = 0; retval = socket_select(fd_max + 1, &read_fds, NULL, NULL, &tv); } else { - /* Every 100ms */ - tv.tv_usec = 100000; + /* Every 100ms, can be changed with "poll_period" command */ + tv.tv_usec = polling_period * 1000; /* Only while we're sleeping we'll let others run */ openocd_sleep_prelude(); kept_alive(); @@ -462,9 +473,10 @@ int server_loop(struct command_context *command_context) retval = service->input(c); if (retval != ERROR_OK) { struct connection *next = c->next; - if (service->type == CONNECTION_PIPE) { + if (service->type == CONNECTION_PIPE || + service->type == CONNECTION_STDINOUT) { /* if connection uses a pipe then - *shutdown openocd on error */ + * shutdown openocd on error */ shutdown_openocd = 1; } remove_connection(service, c); @@ -488,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 @@ -497,12 +509,15 @@ BOOL WINAPI ControlHandler(DWORD dwCtrlType) shutdown_openocd = 1; return TRUE; } +#endif void sig_handler(int sig) { + /* store only first signal that hits us */ + if (!last_signal) + last_signal = sig; shutdown_openocd = 1; } -#endif int server_preinit(void) { @@ -524,11 +539,11 @@ int server_preinit(void) /* register ctrl-c handler */ SetConsoleCtrlHandler(ControlHandler, TRUE); + signal(SIGBREAK, sig_handler); +#endif signal(SIGINT, sig_handler); signal(SIGTERM, sig_handler); - signal(SIGBREAK, sig_handler); signal(SIGABRT, sig_handler); -#endif return ERROR_OK; } @@ -545,13 +560,26 @@ int server_init(struct command_context *cmd_ctx) int server_quit(void) { remove_services(); + target_quit(); #ifdef _WIN32 WSACleanup(); SetConsoleCtrlHandler(ControlHandler, FALSE); -#endif return ERROR_OK; +#endif + + /* return signal number so we can kill ourselves */ + return last_signal; +} + +void exit_on_signal(int sig) +{ +#ifndef _WIN32 + /* bring back default system handler and kill yourself */ + signal(sig, SIG_DFL); + kill(getpid(), sig); +#endif } int connection_write(struct connection *connection, const void *data, int len) @@ -581,6 +609,25 @@ 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; +} + +COMMAND_HANDLER(handle_poll_period_command) +{ + if (CMD_ARGC == 0) + LOG_WARNING("You need to set a period value"); + else + COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], polling_period); + + LOG_INFO("set servers polling period to %ums", polling_period); + return ERROR_OK; } @@ -592,6 +639,13 @@ static const struct command_registration server_command_handlers[] = { .usage = "", .help = "shut the server down", }, + { + .name = "poll_period", + .handler = &handle_poll_period_command, + .mode = COMMAND_ANY, + .usage = "", + .help = "set the servers polling period", + }, COMMAND_REGISTRATION_DONE }; @@ -605,10 +659,14 @@ int server_register_commands(struct command_context *cmd_ctx) if (ERROR_OK != retval) return retval; + retval = jsp_register_commands(cmd_ctx); + if (ERROR_OK != retval) + return retval; + return register_commands(cmd_ctx, NULL, server_command_handlers); } -SERVER_PORT_COMMAND() +COMMAND_HELPER(server_port_command, unsigned short *out) { switch (CMD_ARGC) { case 0: @@ -627,7 +685,7 @@ SERVER_PORT_COMMAND() return ERROR_OK; } -SERVER_PIPE_COMMAND() +COMMAND_HELPER(server_pipe_command, char **out) { switch (CMD_ARGC) { case 0: @@ -639,9 +697,8 @@ SERVER_PIPE_COMMAND() LOG_WARNING("unable to change server port after init"); return ERROR_COMMAND_ARGUMENT_INVALID; } - const char *t = strdup(CMD_ARGV[0]); - free((void *)*out); - *out = t; + free(*out); + *out = strdup(CMD_ARGV[0]); break; } default: