tcl/interface: add SPDX tag
[fw/openocd] / src / server / server.c
index 23a15ef9a37d6b2071d080e2f151e8a153633351..c7cafb78994b0da4f69df6ec1e6b9a4d0e978acd 100644 (file)
@@ -27,6 +27,7 @@
 #endif
 
 #include "server.h"
+#include <helper/time_support.h>
 #include <target/target.h>
 #include <target/target_request.h>
 #include <target/openrisc/jsp_server.h>
@@ -204,13 +205,8 @@ static void free_service(struct service *c)
        free(c);
 }
 
-int add_service(char *name,
-       const char *port,
-       int max_connections,
-       new_connection_handler_t new_connection_handler,
-       input_handler_t input_handler,
-       connection_closed_handler_t connection_closed_handler,
-       void *priv)
+int add_service(const struct service_driver *driver, const char *port,
+               int max_connections, void *priv)
 {
        struct service *c, **p;
        struct hostent *hp;
@@ -218,14 +214,16 @@ int add_service(char *name,
 
        c = malloc(sizeof(struct service));
 
-       c->name = strdup(name);
+       c->name = strdup(driver->name);
        c->port = strdup(port);
        c->max_connections = 1; /* Only TCP/IP ports can support more than one connection */
        c->fd = -1;
        c->connections = NULL;
-       c->new_connection = new_connection_handler;
-       c->input = input_handler;
-       c->connection_closed = connection_closed_handler;
+       c->new_connection_during_keep_alive = driver->new_connection_during_keep_alive_handler;
+       c->new_connection = driver->new_connection_handler;
+       c->input = driver->input_handler;
+       c->connection_closed = driver->connection_closed_handler;
+       c->keep_client_alive = driver->keep_client_alive_handler;
        c->priv = priv;
        c->next = NULL;
        long portnumber;
@@ -262,11 +260,11 @@ int add_service(char *name,
                memset(&c->sin, 0, sizeof(c->sin));
                c->sin.sin_family = AF_INET;
 
-               if (bindto_name == NULL)
+               if (!bindto_name)
                        c->sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
                else {
                        hp = gethostbyname(bindto_name);
-                       if (hp == NULL) {
+                       if (!hp) {
                                LOG_ERROR("couldn't resolve bindto address: %s", bindto_name);
                                close_socket(c->fd);
                                free_service(c);
@@ -277,7 +275,7 @@ int add_service(char *name,
                c->sin.sin_port = htons(c->portnumber);
 
                if (bind(c->fd, (struct sockaddr *)&c->sin, sizeof(c->sin)) == -1) {
-                       LOG_ERROR("couldn't bind %s to socket on port %d: %s", name, c->portnumber, strerror(errno));
+                       LOG_ERROR("couldn't bind %s to socket on port %d: %s", c->name, c->portnumber, strerror(errno));
                        close_socket(c->fd);
                        free_service(c);
                        return ERROR_FAIL;
@@ -308,7 +306,7 @@ int add_service(char *name,
                socklen_t addr_in_size = sizeof(addr_in);
                if (getsockname(c->fd, (struct sockaddr *)&addr_in, &addr_in_size) == 0)
                        LOG_INFO("Listening on port %hu for %s connections",
-                                ntohs(addr_in.sin_port), name);
+                                ntohs(addr_in.sin_port), c->name);
        } else if (c->type == CONNECTION_STDINOUT) {
                c->fd = fileno(stdin);
 
@@ -325,7 +323,7 @@ int add_service(char *name,
 #endif
        } else if (c->type == CONNECTION_PIPE) {
 #ifdef _WIN32
-               /* we currenty do not support named pipes under win32
+               /* we currently do not support named pipes under win32
                 * so exit openocd for now */
                LOG_ERROR("Named pipes currently not supported under this os");
                free_service(c);
@@ -403,19 +401,14 @@ static int remove_services(void)
 
                remove_connections(c);
 
-               if (c->name)
-                       free(c->name);
+               free(c->name);
 
                if (c->type == CONNECTION_PIPE) {
                        if (c->fd != -1)
                                close(c->fd);
                }
-               if (c->port)
-                       free(c->port);
-
-               if (c->priv)
-                       free(c->priv);
-
+               free(c->port);
+               free(c->priv);
                /* delete service */
                free(c);
 
@@ -428,6 +421,14 @@ static int remove_services(void)
        return ERROR_OK;
 }
 
+void server_keep_clients_alive(void)
+{
+       for (struct service *s = services; s; s = s->next)
+               if (s->keep_client_alive)
+                       for (struct connection *c = s->connections; c; c = c->next)
+                               s->keep_client_alive(c);
+}
+
 int server_loop(struct command_context *command_context)
 {
        struct service *service;
@@ -441,6 +442,8 @@ int server_loop(struct command_context *command_context)
        /* used in accept() */
        int retval;
 
+       int64_t next_event = timeval_ms() + polling_period;
+
 #ifndef _WIN32
        if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
                LOG_ERROR("couldn't set SIGPIPE to SIG_IGN");
@@ -482,12 +485,14 @@ int server_loop(struct command_context *command_context)
                        retval = socket_select(fd_max + 1, &read_fds, NULL, NULL, &tv);
                } else {
                        /* Every 100ms, can be changed with "poll_period" command */
-                       tv.tv_usec = polling_period * 1000;
+                       int timeout_ms = next_event - timeval_ms();
+                       if (timeout_ms < 0)
+                               timeout_ms = 0;
+                       else if (timeout_ms > polling_period)
+                               timeout_ms = polling_period;
+                       tv.tv_usec = timeout_ms * 1000;
                        /* Only while we're sleeping we'll let others run */
-                       openocd_sleep_prelude();
-                       kept_alive();
                        retval = socket_select(fd_max + 1, &read_fds, NULL, NULL, &tv);
-                       openocd_sleep_postlude();
                }
 
                if (retval == -1) {
@@ -515,7 +520,8 @@ int server_loop(struct command_context *command_context)
                if (retval == 0) {
                        /* We only execute these callbacks when there was nothing to do or we timed
                         *out */
-                       target_call_timer_callbacks();
+                       target_call_timer_callbacks_now();
+                       next_event = target_timer_next_event();
                        process_jim_events(command_context);
 
                        FD_ZERO(&read_fds);     /* eCos leaves read_fds unchanged in this case!  */
@@ -600,7 +606,7 @@ int server_loop(struct command_context *command_context)
        return shutdown_openocd == SHUTDOWN_WITH_ERROR_CODE ? ERROR_FAIL : ERROR_OK;
 }
 
-void sig_handler(int sig)
+static void sig_handler(int sig)
 {
        /* store only first signal that hits us */
        if (shutdown_openocd == CONTINUE_MAIN_LOOP) {
@@ -613,7 +619,7 @@ void sig_handler(int sig)
 
 
 #ifdef _WIN32
-BOOL WINAPI ControlHandler(DWORD dwCtrlType)
+BOOL WINAPI control_handler(DWORD ctrl_type)
 {
        shutdown_openocd = SHUTDOWN_WITH_SIGNAL_CODE;
        return TRUE;
@@ -638,12 +644,12 @@ int server_host_os_entry(void)
         * This is an issue if you call init in your config script */
 
 #ifdef _WIN32
-       WORD wVersionRequested;
-       WSADATA wsaData;
+       WORD version_requested;
+       WSADATA wsadata;
 
-       wVersionRequested = MAKEWORD(2, 2);
+       version_requested = MAKEWORD(2, 2);
 
-       if (WSAStartup(wVersionRequested, &wsaData) != 0) {
+       if (WSAStartup(version_requested, &wsadata) != 0) {
                LOG_ERROR("Failed to Open Winsock");
                return ERROR_FAIL;
        }
@@ -663,7 +669,7 @@ int server_preinit(void)
 {
 #ifdef _WIN32
        /* register ctrl-c handler */
-       SetConsoleCtrlHandler(ControlHandler, TRUE);
+       SetConsoleCtrlHandler(control_handler, TRUE);
 
        signal(SIGBREAK, sig_handler);
        signal(SIGINT, sig_handler);
@@ -702,7 +708,7 @@ int server_quit(void)
        target_quit();
 
 #ifdef _WIN32
-       SetConsoleCtrlHandler(ControlHandler, FALSE);
+       SetConsoleCtrlHandler(control_handler, FALSE);
 
        return ERROR_OK;
 #endif
@@ -756,6 +762,8 @@ COMMAND_HANDLER(handle_shutdown_command)
 
        shutdown_openocd = SHUTDOWN_REQUESTED;
 
+       command_run_line(CMD_CTX, "_run_pre_shutdown_commands");
+
        if (CMD_ARGC == 1) {
                if (!strcmp(CMD_ARGV[0], "error")) {
                        shutdown_openocd = SHUTDOWN_WITH_ERROR_CODE;
@@ -823,15 +831,15 @@ static const struct command_registration server_command_handlers[] = {
 int server_register_commands(struct command_context *cmd_ctx)
 {
        int retval = telnet_register_commands(cmd_ctx);
-       if (ERROR_OK != retval)
+       if (retval != ERROR_OK)
                return retval;
 
        retval = tcl_register_commands(cmd_ctx);
-       if (ERROR_OK != retval)
+       if (retval != ERROR_OK)
                return retval;
 
        retval = jsp_register_commands(cmd_ctx);
-       if (ERROR_OK != retval)
+       if (retval != ERROR_OK)
                return retval;
 
        return register_commands(cmd_ctx, NULL, server_command_handlers);