X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fserver%2Fserver.c;h=8c4fd7d2978ad41c152cc9ee4298fb47e2378102;hp=5d7df1af11491a766d4826f35d7c88ef30bdb09e;hb=d47e1b8f362379d8a2307f49e2b42115a3f40524;hpb=82d2633b5f550115e9e7c7d0520babb6680aa38f diff --git a/src/server/server.c b/src/server/server.c index 5d7df1af11..8c4fd7d297 100644 --- a/src/server/server.c +++ b/src/server/server.c @@ -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)); @@ -62,27 +62,22 @@ int add_connection(service_t *service, command_context_t *cmd_ctx) address_size = sizeof(c->sin); c->fd = accept(service->fd, (struct sockaddr *)&service->sin, &address_size); + + LOG_INFO("accepting '%s' connection from %i", service->name, c->sin.sin_port); if ((retval = service->new_connection(c)) == ERROR_OK) { - INFO("accepted '%s' connection from %i", service->name, c->sin.sin_port); } else { close_socket(c->fd); - INFO("attempted '%s' connection rejected", service->name); + LOG_ERROR("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 +86,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 +115,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)); @@ -141,7 +134,7 @@ int add_service(char *name, enum connection_type type, unsigned short port, int if ((c->fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { - ERROR("error creating socket: %s", strerror(errno)); + LOG_ERROR("error creating socket: %s", strerror(errno)); exit(-1); } @@ -156,39 +149,31 @@ int add_service(char *name, enum connection_type type, unsigned short port, int if (bind(c->fd, (struct sockaddr *)&c->sin, sizeof(c->sin)) == -1) { - ERROR("couldn't bind to socket: %s", strerror(errno)); + LOG_ERROR("couldn't bind to socket: %s", strerror(errno)); exit(-1); } if (listen(c->fd, 1) == -1) { - ERROR("couldn't listen on socket: %s", strerror(errno)); + LOG_ERROR("couldn't listen on socket: %s", strerror(errno)); 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 +183,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 +216,8 @@ int remove_services() c = next; } + services = NULL; + return ERROR_OK; } @@ -247,7 +235,7 @@ int server_loop(command_context_t *command_context) #ifndef _WIN32 if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) - ERROR("couldn't set SIGPIPE to SIG_IGN"); + LOG_ERROR("couldn't set SIGPIPE to SIG_IGN"); #endif /* do regular tasks after at most 10ms */ @@ -291,7 +279,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 @@ -301,16 +291,18 @@ int server_loop(command_context_t *command_context) FD_ZERO(&read_fds); else { - ERROR("error during select: %d", strerror(errno)); + LOG_ERROR("error during select: %s", strerror(errno)); exit(-1); } #else if (errno == EINTR) + { FD_ZERO(&read_fds); + } else { - ERROR("error during select: %s", strerror(errno)); + LOG_ERROR("error during select: %s", strerror(errno)); exit(-1); } #endif @@ -323,13 +315,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 +325,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; @@ -347,7 +335,7 @@ int server_loop(command_context_t *command_context) int tmp_fd; tmp_fd = accept(service->fd, (struct sockaddr *)&service->sin, &address_size); close_socket(tmp_fd); - INFO("rejected '%s' connection, no more connections allowed", service->name); + LOG_INFO("rejected '%s' connection, no more connections allowed", service->name); } } @@ -364,7 +352,7 @@ int server_loop(command_context_t *command_context) { connection_t *next = c->next; remove_connection(service, c); - INFO("dropped '%s' connection", service->name); + LOG_INFO("dropped '%s' connection", service->name); c = next; continue; } @@ -382,6 +370,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 +389,10 @@ BOOL WINAPI ControlHandler(DWORD dwCtrlType) shutdown_openocd = 1; return TRUE; } + +void sig_handler(int sig) { + shutdown_openocd = 1; +} #endif int server_init() @@ -406,18 +405,23 @@ int server_init() if (WSAStartup(wVersionRequested, &wsaData) != 0) { - ERROR("Failed to Open Winsock"); + LOG_ERROR("Failed to Open Winsock"); exit(-1); } SetConsoleCtrlHandler( ControlHandler, TRUE ); + + signal(SIGINT, sig_handler); + signal(SIGTERM, sig_handler); + signal(SIGBREAK, sig_handler); + signal(SIGABRT, sig_handler); #endif return ERROR_OK; } -int server_close() +int server_quit() { remove_services(); @@ -445,3 +449,4 @@ int handle_shutdown_command(struct command_context_s *cmd_ctx, char *cmd, char * return ERROR_COMMAND_CLOSE_CONNECTION; } +