server: read/write now goes through connection fn's
[fw/openocd] / src / server / server.c
index 7e57228b091155f084ba47dcfa0c20a93280e4c8..1c556638afff7722d464c6b8ab78824580b0ce03 100644 (file)
@@ -2,7 +2,7 @@
  *   Copyright (C) 2005 by Dominic Rath                                    *
  *   Dominic.Rath@gmx.de                                                   *
  *                                                                         *
- *   Copyright (C) 2007,2008 Øyvind Harboe                                 *
+ *   Copyright (C) 2007-2010 Øyvind Harboe                                 *
  *   oyvind.harboe@zylin.com                                               *
  *                                                                         *
  *   Copyright (C) 2008 by Spencer Oliver                                  *
@@ -57,6 +57,7 @@ static int add_connection(struct service *service, struct command_context *cmd_c
 
        c = malloc(sizeof(struct connection));
        c->fd = -1;
+       c->fd_out = -1;
        memset(&c->sin, 0, sizeof(c->sin));
        c->cmd_ctx = copy_command_context(cmd_ctx);
        c->service = service;
@@ -69,6 +70,7 @@ static int add_connection(struct service *service, struct command_context *cmd_c
                address_size = sizeof(c->sin);
 
                c->fd = accept(service->fd, (struct sockaddr *)&service->sin, &address_size);
+               c->fd_out = c->fd;
 
                /* This increases performance dramatically for e.g. GDB load which
                 * does not have a sliding window protocol. */
@@ -78,7 +80,7 @@ static int add_connection(struct service *service, struct command_context *cmd_c
                                (char *)&flag,          /* the cast is historical cruft */
                                sizeof(int));           /* length of option value */
 
-               LOG_INFO("accepting '%s' connection from %i", service->name, c->sin.sin_port);
+               LOG_INFO("accepting '%s' connection from %i", service->name, service->port);
                if ((retval = service->new_connection(c)) != ERROR_OK)
                {
                        close_socket(c->fd);
@@ -90,6 +92,10 @@ static int add_connection(struct service *service, struct command_context *cmd_c
        else if (service->type == CONNECTION_PIPE)
        {
                c->fd = service->fd;
+               c->fd_out = fileno(stdout);
+
+               /* do not check for new connections again on stdin */
+               service->fd = -1;
 
                /* do not check for new connections again on stdin */
                service->fd = -1;
@@ -205,8 +211,7 @@ int add_service(char *name, enum connection_type type, unsigned short port, int
        }
        else if (type == CONNECTION_PIPE)
        {
-               /* use stdin */
-               c->fd = STDIN_FILENO;
+               c->fd = fileno(stdin);
 
 #ifdef _WIN32
                /* for win32 set stdin/stdout to binary mode */
@@ -264,7 +269,7 @@ int server_loop(struct command_context *command_context)
 {
        struct service *service;
 
-       bool poll = true;
+       bool poll_ok = true;
 
        /* used in select() */
        fd_set read_fds;
@@ -310,19 +315,9 @@ int server_loop(struct command_context *command_context)
                        }
                }
 
-#ifndef _WIN32
-#if BUILD_ECOSBOARD == 0
-               if (server_use_pipes == 0)
-               {
-                       /* add STDIN to read_fds */
-                       FD_SET(fileno(stdin), &read_fds);
-               }
-#endif
-#endif
-
                struct timeval tv;
                tv.tv_sec = 0;
-               if (poll)
+               if (poll_ok)
                {
                        /* we're just polling this iteration, this is faster on embedded
                         * hosts */
@@ -375,11 +370,11 @@ int server_loop(struct command_context *command_context)
                        FD_ZERO(&read_fds); /* eCos leaves read_fds unchanged in this case!  */
 
                        /* We timed out/there was nothing to do, timeout rather than poll next time */
-                       poll = false;
+                       poll_ok = false;
                } else
                {
                        /* There was something to do, next time we'll just poll */
-                       poll = true;
+                       poll_ok = true;
                }
 
                for (service = services; service; service = service->next)
@@ -394,7 +389,7 @@ int server_loop(struct command_context *command_context)
                                }
                                else
                                {
-                                       if (service->type != CONNECTION_PIPE)
+                                       if (service->type == CONNECTION_TCP)
                                        {
                                                struct sockaddr_in sin;
                                                socklen_t address_size = sizeof(sin);
@@ -434,21 +429,7 @@ int server_loop(struct command_context *command_context)
                        }
                }
 
-#ifndef _WIN32
-#if BUILD_ECOSBOARD == 0
-               /* check for data on stdin if not using pipes */
-               if (server_use_pipes == 0)
-               {
-                       if (FD_ISSET(fileno(stdin), &read_fds))
-                       {
-                               if (getc(stdin) == 'x')
-                               {
-                                       shutdown_openocd = 1;
-                               }
-                       }
-               }
-#endif
-#else
+#ifdef _WIN32
                MSG msg;
                while (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
                {
@@ -532,6 +513,33 @@ int server_quit(void)
        return ERROR_OK;
 }
 
+int connection_write(struct connection *connection, const void *data, int len)
+{
+       if (len == 0)
+       {
+               /* successful no-op. Sockets and pipes behave differently here... */
+               return 0;
+       }
+       if (connection->service->type == CONNECTION_TCP)
+       {
+               return write_socket(connection->fd_out, data, len);
+       } else
+       {
+               return write(connection->fd_out, data, len);
+       }
+}
+
+int connection_read(struct connection *connection, void *data, int len)
+{
+       if (connection->service->type == CONNECTION_TCP)
+       {
+               return read_socket(connection->fd, data, len);
+       } else
+       {
+               return read(connection->fd, data, len);
+       }
+}
+
 /* tell the server we want to shut down */
 COMMAND_HANDLER(handle_shutdown_command)
 {