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 94fab3a94e891ab5e9596325e6437a46e068207f..83329b519233c48b9857157932aaf34e8ecb237d 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 (init_at_startup) {
                ret = command_run_line(cmd_ctx, "init");
-               if (ERROR_OK != ret)
+               if (ERROR_OK != ret) {
+                       server_quit();
                        return ERROR_FAIL;
                        return ERROR_FAIL;
+               }
        }
 
        ret = server_loop(cmd_ctx);
        }
 
        ret = server_loop(cmd_ctx);
index f6889a01a77f99fe003e79238037d6be07487b3d..8009d408feacac451e0a1b960c1ae0516ef8f7f2 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);
                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);
                }
 
                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;
 }
 
        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,
 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));
                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,
                }
 
                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);
                        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);
                }
                        }
                        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));
 
                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
                }
 
 #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));
 
                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);
                }
        } 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");
                /* 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);
 #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
        }
                }
 #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));
                                FD_ZERO(&read_fds);
                        else {
                                LOG_ERROR("error during select: %s", strerror(errno));
-                               exit(-1);
+                               return ERROR_FAIL;
                        }
 #else
 
                        }
 #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));
                                FD_ZERO(&read_fds);
                        else {
                                LOG_ERROR("error during select: %s", strerror(errno));
-                               exit(-1);
+                               return ERROR_FAIL;
                        }
 #endif
                }
                        }
 #endif
                }
@@ -552,7 +569,7 @@ int server_preinit(void)
 
        if (WSAStartup(wVersionRequested, &wsaData) != 0) {
                LOG_ERROR("Failed to Open Winsock");
 
        if (WSAStartup(wVersionRequested, &wsaData) != 0) {
                LOG_ERROR("Failed to Open Winsock");
-               exit(-1);
+               return ERROR_FAIL;
        }
 
        /* register ctrl-c handler */
        }
 
        /* register ctrl-c handler */
@@ -570,10 +587,18 @@ int server_preinit(void)
 int server_init(struct command_context *cmd_ctx)
 {
        int ret = tcl_init();
 int server_init(struct command_context *cmd_ctx)
 {
        int ret = tcl_init();
-       if (ERROR_OK != ret)
+
+       if (ret != ERROR_OK)
                return ret;
 
                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)
 }
 
 int server_quit(void)
index 0f5769a20d9b7744c0e460aca390bb5a2d4a8592..e5eb4bb2368ab64fd065a7443ac7be5547bb2148 100644 (file)
@@ -624,9 +624,8 @@ int telnet_init(char *banner)
                return ERROR_OK;
        }
 
                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.");
 
        if (!telnet_service) {
                LOG_ERROR("Failed to allocate telnet service.");
@@ -635,13 +634,16 @@ int telnet_init(char *banner)
 
        telnet_service->banner = 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);
                telnet_service);
+
+       if (ret != ERROR_OK) {
+               free(telnet_service);
+               return ret;
+       }
+
+       return ERROR_OK;
 }
 
 /* daemon configuration command telnet_port */
 }
 
 /* daemon configuration command telnet_port */

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)