* fixed malloc corruption in target->debug_reason
[fw/openocd] / src / server / server.c
index ac5e17e56981a4fc8835929b85b69259fd5fba0b..ae13b129d036669554578c6a197b7c98dddbab98 100644 (file)
@@ -47,7 +47,7 @@ int handle_shutdown_command(struct command_context_s *cmd_ctx, char *cmd, char *
 int add_connection(service_t *service, command_context_t *cmd_ctx)
 {
        unsigned int address_size;
-       connection_t *c, *p;
+       connection_t *c, **p;
        int retval;
        
        c = malloc(sizeof(connection_t));
@@ -71,18 +71,12 @@ int add_connection(service_t *service, command_context_t *cmd_ctx)
                close_socket(c->fd);
                INFO("attempted '%s' connection rejected", service->name);
                free(c);
+               return retval;
        }
        
-       if (service->connections)
-       {
-               for (p = service->connections; p && p->next; p = p->next);
-               if (p)
-                       p->next = c;
-       }
-       else
-       {
-               service->connections = c;
-       }
+       /* add to the end of linked list */
+       for (p = &service->connections; *p; p = &(*p)->next);
+       *p = c;
        
        service->max_connections--;
        
@@ -91,30 +85,28 @@ int add_connection(service_t *service, command_context_t *cmd_ctx)
 
 int remove_connection(service_t *service, connection_t *connection)
 {
-       connection_t *c = service->connections;
+       connection_t **p = &service->connections;
+       connection_t *c;
        
        /* find connection */
-       while(c)
-       {
-               connection_t *next = c->next;
-               
+       while((c = *p))
+       {               
                if (c->fd == connection->fd)
                {       
-                       service->connections = next;
                        service->connection_closed(c);
                        close_socket(c->fd);
-                       
                        command_done(c->cmd_ctx);
                        
                        /* delete connection */
+                       *p = c->next;
                        free(c);
                        
                        service->max_connections++;
                        break;
                }
                
-               /* remember the last connection for unlinking */
-               c = next;
+               /* redirect p to next list pointer */
+               p = &(*p)->next;                
        }
        
        return ERROR_OK;
@@ -122,7 +114,7 @@ int remove_connection(service_t *service, connection_t *connection)
 
 int add_service(char *name, enum connection_type type, unsigned short 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)
 {
-       service_t *c, *p;
+       service_t *c, **p;
        int so_reuseaddr_option = 1;
        
        c = malloc(sizeof(service_t));
@@ -166,29 +158,21 @@ int add_service(char *name, enum connection_type type, unsigned short port, int
                exit(-1);
        }
        
-       if (services)
-       {
-               for (p = services; p && p->next; p = p->next);
-               if (p)
-                       p->next = c;
-       }
-       else
-       {
-               services = c;
-       }
+       /* add to the end of linked list */
+       for (p = &services; *p; p = &(*p)->next);
+       *p = c;
        
        return ERROR_OK;
 }
 
 int remove_service(unsigned short port)
 {
-       service_t *c = services;
+       service_t **p = &services;
+       service_t *c;
        
        /* find service */
-       while(c)
-       {
-               service_t *next = c->next;
-               
+       while((c = *p))
+       {               
                if (c->port == port)
                {       
                        if (c->name)
@@ -198,11 +182,12 @@ int remove_service(unsigned short port)
                                free(c->priv);
                        
                        /* delete service */
+                       *p = c->next;
                        free(c);
                }
-               
-               /* remember the last service for unlinking */
-               c = next;
+
+               /* redirect p to next list pointer */
+               p = &(*p)->next;
        }
        
        return ERROR_OK;
@@ -230,6 +215,8 @@ int remove_services()
                c = next;
        }
 
+       services = NULL;
+       
        return ERROR_OK;
 }
 
@@ -291,7 +278,9 @@ int server_loop(command_context_t *command_context)
                FD_SET(fileno(stdin), &read_fds);
 #endif
 
-               if ((retval = select(fd_max + 1, &read_fds, NULL, NULL, &tv)) == -1)
+               retval = select(fd_max + 1, &read_fds, NULL, NULL, &tv);
+               
+               if (retval == -1)
                {
 #ifdef _WIN32
 
@@ -307,7 +296,9 @@ int server_loop(command_context_t *command_context)
 #else
 
                        if (errno == EINTR)
+                       {
                                FD_ZERO(&read_fds);
+                       }
                        else
                        {
                                ERROR("error during select: %s", strerror(errno));
@@ -323,13 +314,7 @@ int server_loop(command_context_t *command_context)
                        /* do regular tasks after at most 100ms */
                        tv.tv_sec = 0;
                        tv.tv_usec = 10000;
-                               
-#if 0
-                       if (shutdown_openocd)
-                               return ERROR_COMMAND_CLOSE_CONNECTION;
-                       
-                       handle_target();
-#endif
+                       FD_ZERO(&read_fds); /* eCos leaves read_fds unchanged in this case!  */
                }
                
                for (service = services; service; service = service->next)
@@ -339,7 +324,9 @@ int server_loop(command_context_t *command_context)
                                && (FD_ISSET(service->fd, &read_fds))) 
                        {
                                if (service->max_connections > 0)
+                               {
                                        add_connection(service, command_context);
+                               }
                                else
                                {
                                        struct sockaddr_in sin;
@@ -382,6 +369,13 @@ int server_loop(command_context_t *command_context)
                                shutdown_openocd = 1;
                        }
                }
+#else
+               MSG msg;
+               while (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
+               {
+                       if (msg.message == WM_QUIT)
+                               shutdown_openocd = 1;
+               }
 #endif
        }
        
@@ -394,6 +388,10 @@ BOOL WINAPI ControlHandler(DWORD dwCtrlType)
     shutdown_openocd = 1;
     return TRUE;
 }
+
+void sig_handler(int sig) {
+    shutdown_openocd = 1;
+}
 #endif
 
 int server_init()
@@ -411,6 +409,11 @@ int server_init()
        }
 
        SetConsoleCtrlHandler( ControlHandler, TRUE );
+
+       signal(SIGINT, sig_handler);
+       signal(SIGTERM, sig_handler);
+       signal(SIGBREAK, sig_handler);
+       signal(SIGABRT, sig_handler);
 #endif
 
        
@@ -445,3 +448,4 @@ int handle_shutdown_command(struct command_context_s *cmd_ctx, char *cmd, char *
        return ERROR_COMMAND_CLOSE_CONNECTION;
 }
 
+