server/server: Remove all exit() calls 23/3223/6
authorMarc Schink <openocd-dev@marcschink.de>
Sun, 24 Jan 2016 19:58:24 +0000 (20:58 +0100)
committerFreddie Chopin <freddie.chopin@gmail.com>
Tue, 25 Apr 2017 15:56:35 +0000 (16:56 +0100)
With this patch OpenOCD shuts down properly when errors occur in the
server instead of just calling exit().

Change-Id: I2ae1a6153dafc88667951cab9152941cb487be85
Signed-off-by: Marc Schink <openocd-dev@marcschink.de>
Reviewed-on: http://openocd.zylin.com/3223
Reviewed-by: Tomas Vanek <vanekt@fbl.cz>
Tested-by: jenkins
src/openocd.c
src/server/server.c
src/server/telnet_server.c

index 94fab3a..83329b5 100644 (file)
@@ -297,8 +297,10 @@ static int openocd_thread(int argc, char *argv[], struct command_context *cmd_ct
 
        if (init_at_startup) {
                ret = command_run_line(cmd_ctx, "init");
-               if (ERROR_OK != ret)
+               if (ERROR_OK != ret) {
+                       server_quit();
                        return ERROR_FAIL;
+               }
        }
 
        ret = server_loop(cmd_ctx);
index f6889a0..8009d40 100644 (file)
@@ -132,7 +132,9 @@ static int add_connection(struct service *service, struct command_context *cmd_c
                free(out_file);
                if (c->fd_out == -1) {
                        LOG_ERROR("could not open %s", service->port);
-                       exit(1);
+                       command_done(c->cmd_ctx);
+                       free(c);
+                       return ERROR_FAIL;
                }
 
                LOG_INFO("accepting '%s' connection from pipe %s", service->name, service->port);
@@ -191,7 +193,13 @@ static int remove_connection(struct service *service, struct connection *connect
        return ERROR_OK;
 }
 
-/* FIX! make service return error instead of invoking exit() */
+static void free_service(struct service *c)
+{
+       free(c->name);
+       free(c->port);
+       free(c);
+}
+
 int add_service(char *name,
        const char *port,
        int max_connections,
@@ -235,7 +243,8 @@ int add_service(char *name,
                c->fd = socket(AF_INET, SOCK_STREAM, 0);
                if (c->fd == -1) {
                        LOG_ERROR("error creating socket: %s", strerror(errno));
-                       exit(-1);
+                       free_service(c);
+                       return ERROR_FAIL;
                }
 
                setsockopt(c->fd,
@@ -255,7 +264,9 @@ int add_service(char *name,
                        hp = gethostbyname(bindto_name);
                        if (hp == NULL) {
                                LOG_ERROR("couldn't resolve bindto address: %s", bindto_name);
-                               exit(-1);
+                               close_socket(c->fd);
+                               free_service(c);
+                               return ERROR_FAIL;
                        }
                        memcpy(&c->sin.sin_addr, hp->h_addr_list[0], hp->h_length);
                }
@@ -263,7 +274,9 @@ int add_service(char *name,
 
                if (bind(c->fd, (struct sockaddr *)&c->sin, sizeof(c->sin)) == -1) {
                        LOG_ERROR("couldn't bind %s to socket: %s", name, strerror(errno));
-                       exit(-1);
+                       close_socket(c->fd);
+                       free_service(c);
+                       return ERROR_FAIL;
                }
 
 #ifndef _WIN32
@@ -281,7 +294,9 @@ int add_service(char *name,
 
                if (listen(c->fd, 1) == -1) {
                        LOG_ERROR("couldn't listen on socket: %s", strerror(errno));
-                       exit(-1);
+                       close_socket(c->fd);
+                       free_service(c);
+                       return ERROR_FAIL;
                }
        } else if (c->type == CONNECTION_STDINOUT) {
                c->fd = fileno(stdin);
@@ -302,13 +317,15 @@ int add_service(char *name,
                /* we currenty do not support named pipes under win32
                 * so exit openocd for now */
                LOG_ERROR("Named pipes currently not supported under this os");
-               exit(1);
+               free_service(c);
+               return ERROR_FAIL;
 #else
                /* Pipe we're reading from */
                c->fd = open(c->port, O_RDONLY | O_NONBLOCK);
                if (c->fd == -1) {
                        LOG_ERROR("could not open %s", c->port);
-                       exit(1);
+                       free_service(c);
+                       return ERROR_FAIL;
                }
 #endif
        }
@@ -425,7 +442,7 @@ int server_loop(struct command_context *command_context)
                                FD_ZERO(&read_fds);
                        else {
                                LOG_ERROR("error during select: %s", strerror(errno));
-                               exit(-1);
+                               return ERROR_FAIL;
                        }
 #else
 
@@ -433,7 +450,7 @@ int server_loop(struct command_context *command_context)
                                FD_ZERO(&read_fds);
                        else {
                                LOG_ERROR("error during select: %s", strerror(errno));
-                               exit(-1);
+                               return ERROR_FAIL;
                        }
 #endif
                }
@@ -552,7 +569,7 @@ int server_preinit(void)
 
        if (WSAStartup(wVersionRequested, &wsaData) != 0) {
                LOG_ERROR("Failed to Open Winsock");
-               exit(-1);
+               return ERROR_FAIL;
        }
 
        /* register ctrl-c handler */
@@ -570,10 +587,18 @@ int server_preinit(void)
 int server_init(struct command_context *cmd_ctx)
 {
        int ret = tcl_init();
-       if (ERROR_OK != ret)
+
+       if (ret != ERROR_OK)
                return ret;
 
-       return telnet_init("Open On-Chip Debugger");
+       ret = telnet_init("Open On-Chip Debugger");
+
+       if (ret != ERROR_OK) {
+               remove_services();
+               return ret;
+       }
+
+       return ERROR_OK;
 }
 
 int server_quit(void)
index 0f5769a..e5eb4bb 100644 (file)
@@ -624,9 +624,8 @@ int telnet_init(char *banner)
                return ERROR_OK;
        }
 
-       struct telnet_service *telnet_service;
-
-       telnet_service = malloc(sizeof(struct telnet_service));
+       struct telnet_service *telnet_service =
+               malloc(sizeof(struct telnet_service));
 
        if (!telnet_service) {
                LOG_ERROR("Failed to allocate telnet service.");
@@ -635,13 +634,16 @@ int telnet_init(char *banner)
 
        telnet_service->banner = banner;
 
-       return add_service("telnet",
-               telnet_port,
-               CONNECTION_LIMIT_UNLIMITED,
-               telnet_new_connection,
-               telnet_input,
-               telnet_connection_closed,
+       int ret = add_service("telnet", telnet_port, CONNECTION_LIMIT_UNLIMITED,
+               telnet_new_connection, telnet_input, telnet_connection_closed,
                telnet_service);
+
+       if (ret != ERROR_OK) {
+               free(telnet_service);
+               return ret;
+       }
+
+       return ERROR_OK;
 }
 
 /* daemon configuration command telnet_port */