diff options
author | drath <drath@b42882b7-edfa-0310-969c-e2dbd0fdcd60> | 2006-07-17 14:13:27 +0000 |
---|---|---|
committer | drath <drath@b42882b7-edfa-0310-969c-e2dbd0fdcd60> | 2006-07-17 14:13:27 +0000 |
commit | 82d2633b5f550115e9e7c7d0520babb6680aa38f (patch) | |
tree | fa9895a6117d4a238be1b76293edcc7de11a88c2 /src/server/server.c | |
parent | 1960973baf8022b4525e3ac94aed8dace7f9b478 (diff) |
- Added support for native MinGW builds (thanks to Spencer Oliver and Michael Fischer) - you still need to install GiveIO (not part of OpenOCD)
- Added state-move support to ftd2xx and bitbang JTAG drivers (required for XScale, possibly useful for other targets, too)
- various fixes
git-svn-id: svn://svn.berlios.de/openocd/trunk@78 b42882b7-edfa-0310-969c-e2dbd0fdcd60
Diffstat (limited to 'src/server/server.c')
-rw-r--r-- | src/server/server.c | 99 |
1 files changed, 91 insertions, 8 deletions
diff --git a/src/server/server.c b/src/server/server.c index 628c4925..5d7df1af 100644 --- a/src/server/server.c +++ b/src/server/server.c @@ -17,6 +17,12 @@ * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "replacements.h" + #include "server.h" #include "log.h" @@ -29,7 +35,6 @@ #include <errno.h> #include <unistd.h> #include <sys/types.h> -#include <sys/socket.h> #include <fcntl.h> #include <signal.h> @@ -63,7 +68,7 @@ int add_connection(service_t *service, command_context_t *cmd_ctx) } else { - close(c->fd); + close_socket(c->fd); INFO("attempted '%s' connection rejected", service->name); free(c); } @@ -97,7 +102,7 @@ int remove_connection(service_t *service, connection_t *connection) { service->connections = next; service->connection_closed(c); - close(c->fd); + close_socket(c->fd); command_done(c->cmd_ctx); @@ -119,7 +124,6 @@ int add_service(char *name, enum connection_type type, unsigned short port, int { service_t *c, *p; int so_reuseaddr_option = 1; - int oldopts; c = malloc(sizeof(service_t)); @@ -141,10 +145,9 @@ int add_service(char *name, enum connection_type type, unsigned short port, int exit(-1); } - setsockopt(c->fd, SOL_SOCKET, SO_REUSEADDR, &so_reuseaddr_option, sizeof(int)); + setsockopt(c->fd, SOL_SOCKET, SO_REUSEADDR, (void*)&so_reuseaddr_option, sizeof(int)); - oldopts = fcntl(c->fd, F_GETFL, 0); - fcntl(c->fd, F_SETFL, oldopts | O_NONBLOCK); + socket_nonblock(c->fd); memset(&c->sin, 0, sizeof(c->sin)); c->sin.sin_family = AF_INET; @@ -205,6 +208,31 @@ int remove_service(unsigned short port) return ERROR_OK; } +int remove_services() +{ + service_t *c = services; + + /* loop service */ + while(c) + { + service_t *next = c->next; + + if (c->name) + free(c->name); + + if (c->priv) + free(c->priv); + + /* delete service */ + free(c); + + /* remember the last service for unlinking */ + c = next; + } + + return ERROR_OK; +} + int server_loop(command_context_t *command_context) { service_t *service; @@ -217,8 +245,10 @@ int server_loop(command_context_t *command_context) /* used in accept() */ int retval; +#ifndef _WIN32 if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) ERROR("couldn't set SIGPIPE to SIG_IGN"); +#endif /* do regular tasks after at most 10ms */ tv.tv_sec = 0; @@ -256,11 +286,26 @@ int server_loop(command_context_t *command_context) } } +#ifndef _WIN32 /* add STDIN to read_fds */ FD_SET(fileno(stdin), &read_fds); +#endif if ((retval = select(fd_max + 1, &read_fds, NULL, NULL, &tv)) == -1) { +#ifdef _WIN32 + + errno = WSAGetLastError(); + + if (errno == WSAEINTR) + FD_ZERO(&read_fds); + else + { + ERROR("error during select: %d", strerror(errno)); + exit(-1); + } +#else + if (errno == EINTR) FD_ZERO(&read_fds); else @@ -268,6 +313,7 @@ int server_loop(command_context_t *command_context) ERROR("error during select: %s", strerror(errno)); exit(-1); } +#endif } target_call_timer_callbacks(); @@ -300,7 +346,7 @@ int server_loop(command_context_t *command_context) unsigned int address_size = sizeof(sin); int tmp_fd; tmp_fd = accept(service->fd, (struct sockaddr *)&service->sin, &address_size); - close(tmp_fd); + close_socket(tmp_fd); INFO("rejected '%s' connection, no more connections allowed", service->name); } } @@ -328,6 +374,7 @@ int server_loop(command_context_t *command_context) } } +#ifndef _WIN32 if (FD_ISSET(fileno(stdin), &read_fds)) { if (getc(stdin) == 'x') @@ -335,17 +382,53 @@ int server_loop(command_context_t *command_context) shutdown_openocd = 1; } } +#endif } return ERROR_OK; } +#ifdef _WIN32 +BOOL WINAPI ControlHandler(DWORD dwCtrlType) +{ + shutdown_openocd = 1; + return TRUE; +} +#endif + int server_init() { +#ifdef _WIN32 + WORD wVersionRequested; + WSADATA wsaData; + + wVersionRequested = MAKEWORD( 2, 2 ); + + if (WSAStartup(wVersionRequested, &wsaData) != 0) + { + ERROR("Failed to Open Winsock"); + exit(-1); + } + + SetConsoleCtrlHandler( ControlHandler, TRUE ); +#endif + return ERROR_OK; } +int server_close() +{ + remove_services(); + +#ifdef _WIN32 + WSACleanup(); + SetConsoleCtrlHandler( ControlHandler, FALSE ); +#endif + + return ERROR_OK; +} + int server_register_commands(command_context_t *context) { register_command(context, NULL, "shutdown", handle_shutdown_command, |