Index: src/helper/log.c
===================================================================
--- src/helper/log.c	(revision 1229)
+++ src/helper/log.c	(working copy)
@@ -31,6 +31,7 @@
 #include "configuration.h"
 #include "time_support.h"
 #include "command.h"
+#include "server.h"
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -108,9 +109,11 @@
 #endif
 					string);
 		}
-		else
+		else if(server_use_pipes == 0)
 		{
-			if (strcmp(string, "\n")!=0)
+			/* if we are using gdb through pipes then we do not want any output
+			 * to the pipe otherwise we get repeated strings */
+			if (strcmp(string, "\n") != 0)
 			{
 				/* print human readable output - but skip empty lines */
 				fprintf(log_output, "%s%s",
@@ -203,6 +206,18 @@
 	if (debug_level > 3)
 		debug_level = 3;
 
+	if (debug_level >= LOG_LVL_DEBUG && server_use_pipes == 1)
+	{
+		/* if we are enabling debug info then we need to write to a log file
+		 * otherwise the pipe will get full and cause issues with gdb */
+		FILE* file = fopen("openocd.log", "w");
+		if (file)
+		{
+			log_output = file;
+			LOG_WARNING("enabling log output as we are using pipes");
+		}
+	}
+	
 	return ERROR_OK;
 }
 
Index: src/helper/Makefile.am
===================================================================
--- src/helper/Makefile.am	(revision 1229)
+++ src/helper/Makefile.am	(working copy)
@@ -1,4 +1,4 @@
-INCLUDES = -I$(top_srcdir)/src $(all_includes) -I$(top_srcdir)/src/target
+INCLUDES = -I$(top_srcdir)/src $(all_includes) -I$(top_srcdir)/src/target -I$(top_srcdir)/src/server
 METASOURCES = AUTO
 AM_CPPFLAGS = -DPKGDATADIR=\"$(pkgdatadir)\" -DPKGLIBDIR=\"$(pkglibdir)\" @CPPFLAGS@
 noinst_LIBRARIES = libhelper.a
Index: src/helper/options.c
===================================================================
--- src/helper/options.c	(revision 1229)
+++ src/helper/options.c	(working copy)
@@ -24,10 +24,13 @@
 #include "config.h"
 #endif
 
+#include "replacements.h"
+
 #include "types.h"
 #include "command.h"
 #include "configuration.h"
 #include "log.h"
+#include "server.h"
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -43,8 +46,9 @@
 	{"debug",	optional_argument,	0,		'd'},
 	{"file", 	required_argument,	0,		'f'},
 	{"search",	required_argument,	0,		's'},
-	{"log_output",	required_argument,	0,		'l'},
+	{"log_output",	required_argument,	0,	'l'},
 	{"command",	required_argument,	0,		'c'},
+	{"pipe",	no_argument,		0,		'p'},
 	{0, 0, 0, 0}
 };
 
@@ -95,7 +99,7 @@
 		/* getopt_long stores the option index here. */
 		int option_index = 0;
 		
-		c = getopt_long(argc, argv, "hvd::l:f:s:c:", long_options, &option_index);
+		c = getopt_long(argc, argv, "hvd::l:f:s:c:p", long_options, &option_index);
 		
 		/* Detect the end of the options. */
 		if (c == -1)
@@ -140,7 +144,20 @@
 					add_config_command(optarg);
 				}	
 				break;
-				
+			case 'p':	/* --pipe | -p */
+#if BUILD_ECOSBOARD == 1
+				/* pipes unsupported on hosted platforms */
+				LOG_WARNING("pipes not supported on this platform");
+#else
+#ifdef IS_MINGW
+				/* pipes currently unsupported on win32 */
+				LOG_WARNING("pipes currently unsupported on win32");
+				exit(1);
+#else
+				server_use_pipes = 1;
+#endif
+#endif
+				break;
 		}
 	}
 
@@ -154,6 +171,7 @@
 		LOG_OUTPUT("--debug      | -d\tset debug level <0-3>\n");
 		LOG_OUTPUT("--log_output | -l\tredirect log output to file <name>\n");
 		LOG_OUTPUT("--command    | -c\trun <command>\n");
+		LOG_OUTPUT("--pipe       | -p\tuse pipes for gdb communication\n");
 		exit(-1);
 	}	
 
@@ -161,8 +179,7 @@
 	{
 		/* Nothing to do, version gets printed automatically. */
 		exit(-1);
-	}	
-
-
+	}
+	
 	return ERROR_OK;
 }
Index: src/server/gdb_server.c
===================================================================
--- src/server/gdb_server.c	(revision 1229)
+++ src/server/gdb_server.c	(working copy)
@@ -169,10 +169,18 @@
 
 	for (;;)
 	{
-		retval=check_pending(connection, 1, NULL);
-		if (retval!=ERROR_OK)
-			return retval;
-		gdb_con->buf_cnt = read_socket(connection->fd, gdb_con->buffer, GDB_BUFFER_SIZE);
+		if (connection->service->type == CONNECTION_PIPE)
+		{
+			gdb_con->buf_cnt = read(connection->fd, gdb_con->buffer, GDB_BUFFER_SIZE);
+		}
+		else
+		{
+			retval = check_pending(connection, 1, NULL);
+			if (retval != ERROR_OK)
+				return retval;
+			gdb_con->buf_cnt = read_socket(connection->fd, gdb_con->buffer, GDB_BUFFER_SIZE);
+		}
+		
 		if (gdb_con->buf_cnt > 0)
 		{
 			break;
@@ -268,11 +276,22 @@
 	gdb_connection_t *gdb_con = connection->priv;
 	if (gdb_con->closed)
 		return ERROR_SERVER_REMOTE_CLOSED;
-
-	if (write_socket(connection->fd, data, len) == len)
+	
+	if (connection->service->type == CONNECTION_PIPE)
 	{
-		return ERROR_OK;
+		/* write to stdout */
+		if (write(STDOUT_FILENO, data, len) == len)
+		{
+			return ERROR_OK;
+		}
 	}
+	else
+	{
+		if (write_socket(connection->fd, data, len) == len)
+		{
+			return ERROR_OK;
+		}
+	}
 	gdb_con->closed = 1;
 	return ERROR_SERVER_REMOTE_CLOSED;
 }
@@ -2160,10 +2179,10 @@
 	if (retval == ERROR_SERVER_REMOTE_CLOSED)
 		return retval;
 
-	/* logging does not propagate the error, yet can set th gdb_con->closed flag */
+	/* logging does not propagate the error, yet can set the gdb_con->closed flag */
 	if (gdb_con->closed)
 		return ERROR_SERVER_REMOTE_CLOSED;
-
+	
 	/* we'll recover from any other errors(e.g. temporary timeouts, etc.) */
 	return ERROR_OK;
 }
@@ -2179,34 +2198,37 @@
 		return ERROR_OK;
 	}
 
-	if (gdb_port == 0)
+	if (gdb_port == 0 && server_use_pipes == 0)
 	{
 		LOG_WARNING("no gdb port specified, using default port 3333");
 		gdb_port = 3333;
 	}
 
-	while (target)
+	if (server_use_pipes)
 	{
-		char service_name[8];
-
-		snprintf(service_name, 8, "gdb-%2.2i", target->target_number);
-
+		/* only a single gdb connection when using a pipe */
+		
 		gdb_service = malloc(sizeof(gdb_service_t));
 		gdb_service->target = target;
 
-		add_service("gdb", CONNECTION_GDB,
-			    gdb_port + target->target_number,
-			    1, gdb_new_connection, gdb_input,
-			    gdb_connection_closed,
-			    gdb_service);
+		add_service("gdb", CONNECTION_PIPE, 0, 1, gdb_new_connection, gdb_input, gdb_connection_closed, gdb_service);
 
-		LOG_DEBUG("gdb service for target %s at port %i",
-			  target->type->name,
-			  gdb_port + target->target_number);
+		LOG_DEBUG("gdb service for target %s at port %i", target->type->name, gdb_port + target->target_number);
+	}
+	else
+	{
+		while (target)
+		{
+			gdb_service = malloc(sizeof(gdb_service_t));
+			gdb_service->target = target;
 
-		target = target->next;
+			add_service("gdb", CONNECTION_TCP, gdb_port + target->target_number, 1, gdb_new_connection, gdb_input, gdb_connection_closed, gdb_service);
+			
+			LOG_DEBUG("gdb service for target %s at port %i", target->type->name, gdb_port + target->target_number);
+			target = target->next;
+		}
 	}
-
+	
 	return ERROR_OK;
 }
 
@@ -2354,7 +2376,6 @@
 	return ERROR_OK;
 }
 
-
 int gdb_register_commands(command_context_t *command_context)
 {
 	register_command(command_context, NULL, "gdb_port", handle_gdb_port_command,
Index: src/server/server.c
===================================================================
--- src/server/server.c	(revision 1229)
+++ src/server/server.c	(working copy)
@@ -53,6 +53,9 @@
 static int shutdown_openocd = 0;
 int handle_shutdown_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
 
+/* set when using pipes rather than tcp */
+int server_use_pipes = 0;
+
 int add_connection(service_t *service, command_context_t *cmd_ctx)
 {
 	unsigned int address_size;
@@ -69,28 +72,44 @@
 	c->priv = NULL;
 	c->next = NULL;
 
-	address_size = sizeof(c->sin);
-	
-	c->fd = accept(service->fd, (struct sockaddr *)&service->sin, &address_size);
-	
-	/* This increases performance dramatically for e.g. GDB load which
-	 * does not have a sliding window protocol. */
-	retval=setsockopt(c->fd,	/* socket affected */
-			IPPROTO_TCP,		/* set option at TCP level */
-			TCP_NODELAY,		/* name of option */
-			(char *)&flag,		/* the cast is historical cruft */
-			sizeof(int));		/* length of option value */
+	if (service->type == CONNECTION_TCP)
+	{
+		address_size = sizeof(c->sin);
 		
-	LOG_INFO("accepting '%s' connection from %i", service->name, c->sin.sin_port);
-	if ((retval = service->new_connection(c)) == ERROR_OK)
-	{
+		c->fd = accept(service->fd, (struct sockaddr *)&service->sin, &address_size);
+		
+		/* This increases performance dramatically for e.g. GDB load which
+		 * does not have a sliding window protocol. */
+		retval=setsockopt(c->fd,	/* socket affected */
+				IPPROTO_TCP,		/* set option at TCP level */
+				TCP_NODELAY,		/* name of option */
+				(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);
+		if ((retval = service->new_connection(c)) != ERROR_OK)
+		{
+			close_socket(c->fd);
+			LOG_ERROR("attempted '%s' connection rejected", service->name);
+			free(c);
+			return retval;
+		}
 	}
-	else
+	else if (service->type == CONNECTION_PIPE)
 	{
-		close_socket(c->fd);
-		LOG_ERROR("attempted '%s' connection rejected", service->name);
-		free(c);
-		return retval;
+#ifndef _WIN32
+		c->fd = service->fd;
+		
+		/* do not check for new connections again on stdin */
+		service->fd = -1;
+#endif
+		LOG_INFO("accepting '%s' connection from pipe", service->name);
+		if ((retval = service->new_connection(c)) != ERROR_OK)
+		{
+			LOG_ERROR("attempted '%s' connection rejected", service->name);
+			free(c);
+			return retval;
+		}
 	}
 	
 	/* add to the end of linked list */
@@ -113,7 +132,8 @@
 		if (c->fd == connection->fd)
 		{	
 			service->connection_closed(c);
-			close_socket(c->fd);
+			if (service->type == CONNECTION_TCP)
+				close_socket(c->fd);
 			command_done(c->cmd_ctx);
 			
 			/* delete connection */
@@ -150,45 +170,68 @@
 	c->priv = priv;
 	c->next = NULL;
 	
-	if ((c->fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
+	if (type == CONNECTION_TCP)
 	{
-		LOG_ERROR("error creating socket: %s", strerror(errno));
-		exit(-1);
-	}
-	
-	setsockopt(c->fd, SOL_SOCKET, SO_REUSEADDR, (void*)&so_reuseaddr_option, sizeof(int));
-	
-	socket_nonblock(c->fd);
-	
-	memset(&c->sin, 0, sizeof(c->sin));
-	c->sin.sin_family = AF_INET;
-	c->sin.sin_addr.s_addr = INADDR_ANY;
-	c->sin.sin_port = htons(port);
-	
-	if (bind(c->fd, (struct sockaddr *)&c->sin, sizeof(c->sin)) == -1)
-	{
-		LOG_ERROR("couldn't bind to socket: %s", strerror(errno));
-		exit(-1);
-	}
-	
+		if ((c->fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
+		{
+			LOG_ERROR("error creating socket: %s", strerror(errno));
+			exit(-1);
+		}
+		
+		setsockopt(c->fd, SOL_SOCKET, SO_REUSEADDR, (void*)&so_reuseaddr_option, sizeof(int));
+		
+		socket_nonblock(c->fd);
+		
+		memset(&c->sin, 0, sizeof(c->sin));
+		c->sin.sin_family = AF_INET;
+		c->sin.sin_addr.s_addr = INADDR_ANY;
+		c->sin.sin_port = htons(port);
+		
+		if (bind(c->fd, (struct sockaddr *)&c->sin, sizeof(c->sin)) == -1)
+		{
+			LOG_ERROR("couldn't bind to socket: %s", strerror(errno));
+			exit(-1);
+		}
+		
 #ifndef _WIN32
-	int segsize=65536;
-	setsockopt(c->fd, IPPROTO_TCP, TCP_MAXSEG,  &segsize, sizeof(int));
+		int segsize=65536;
+		setsockopt(c->fd, IPPROTO_TCP, TCP_MAXSEG,  &segsize, sizeof(int));
 #endif
-	int window_size = 128 * 1024;	
-
-	/* These setsockopt()s must happen before the listen() */
+		int window_size = 128 * 1024;	
 	
-	setsockopt(c->fd, SOL_SOCKET, SO_SNDBUF,
-		(char *)&window_size, sizeof(window_size));
-	setsockopt(c->fd, SOL_SOCKET, SO_RCVBUF,
-		(char *)&window_size, sizeof(window_size));
-	
-	if (listen(c->fd, 1) == -1)
+		/* These setsockopt()s must happen before the listen() */
+		
+		setsockopt(c->fd, SOL_SOCKET, SO_SNDBUF,
+			(char *)&window_size, sizeof(window_size));
+		setsockopt(c->fd, SOL_SOCKET, SO_RCVBUF,
+			(char *)&window_size, sizeof(window_size));
+		
+		if (listen(c->fd, 1) == -1)
+		{
+			LOG_ERROR("couldn't listen on socket: %s", strerror(errno));
+			exit(-1);
+		}
+	}
+	else if (type == CONNECTION_PIPE)
 	{
-		LOG_ERROR("couldn't listen on socket: %s", strerror(errno));
-		exit(-1);
+		/* use stdin */
+		c->fd = STDIN_FILENO;
+		
+#ifdef _WIN32
+		/* for win32 set stdin/stdout to binary mode */
+		if (_setmode(_fileno(stdout), _O_BINARY) < 0)
+			LOG_WARNING("cannot change stdout mode to binary");
+		if (_setmode(_fileno(stdin), _O_BINARY) < 0)
+			LOG_WARNING("cannot change stdin mode to binary");
+#else
+		socket_nonblock(c->fd);
+#endif
 	}
+	else
+	{
+		LOG_ERROR("unknown connection type: %d", type);
+		exit(1);
+	}
 	
 	/* add to the end of linked list */
 	for (p = &services; *p; p = &(*p)->next);
@@ -310,14 +353,18 @@
 		
 #ifndef _WIN32
 #if BUILD_ECOSBOARD == 0
-		/* add STDIN to read_fds */
-		FD_SET(fileno(stdin), &read_fds);
+		if (server_use_pipes == 0)
+		{
+			/* add STDIN to read_fds */
+			FD_SET(fileno(stdin), &read_fds);
+		}
 #endif
 #endif
 
 		openocd_sleep_prelude();
 		kept_alive();
-		// Only while we're sleeping we'll let others run
+		
+		/* Only while we're sleeping we'll let others run */
 		retval = select(fd_max + 1, &read_fds, NULL, NULL, &tv);
 		openocd_sleep_postlude();
 
@@ -371,11 +418,14 @@
 				}
 				else
 				{
-					struct sockaddr_in sin;
-					unsigned int address_size = sizeof(sin);
-					int tmp_fd;
-					tmp_fd = accept(service->fd, (struct sockaddr *)&service->sin, &address_size);
-					close_socket(tmp_fd);
+					if (service->type != CONNECTION_PIPE)
+					{
+						struct sockaddr_in sin;
+						unsigned int address_size = sizeof(sin);
+						int tmp_fd;
+						tmp_fd = accept(service->fd, (struct sockaddr *)&service->sin, &address_size);
+						close_socket(tmp_fd);
+					}
 					LOG_INFO("rejected '%s' connection, no more connections allowed", service->name);
 				}
 			}
@@ -389,11 +439,16 @@
 				{
 					if ((FD_ISSET(c->fd, &read_fds)) || c->input_pending)
 					{
-						if (service->input(c) != ERROR_OK)
+						if ((retval = service->input(c)) != ERROR_OK)
 						{
 							connection_t *next = c->next;
+							if (service->type == CONNECTION_PIPE)
+							{
+								/* if connection uses a pipe then shutdown openocd on error */
+								shutdown_openocd = 1;
+							}
 							remove_connection(service, c);
-							LOG_INFO("dropped '%s' connection", service->name);
+							LOG_INFO("dropped '%s' connection - error %d", service->name, retval);
 							c = next;
 							continue;
 						}
@@ -405,11 +460,15 @@
 		
 #ifndef _WIN32
 #if BUILD_ECOSBOARD == 0
-		if (FD_ISSET(fileno(stdin), &read_fds))
+		/* check for data on stdin if not using pipes */
+		if (server_use_pipes == 0)
 		{
-			if (getc(stdin) == 'x')
+			if (FD_ISSET(fileno(stdin), &read_fds))
 			{
-				shutdown_openocd = 1;
+				if (getc(stdin) == 'x')
+				{
+					shutdown_openocd = 1;
+				}
 			}
 		}
 #endif
@@ -459,7 +518,6 @@
 	signal(SIGBREAK, sig_handler);
 	signal(SIGABRT, sig_handler);
 #endif
-
 	
 	return ERROR_OK;
 }
@@ -491,5 +549,3 @@
 
 	return ERROR_COMMAND_CLOSE_CONNECTION;
 }
-
-
Index: src/server/server.h
===================================================================
--- src/server/server.h	(revision 1229)
+++ src/server/server.h	(working copy)
@@ -34,9 +34,8 @@
 
 enum connection_type
 {
-	CONNECTION_GDB,
-	CONNECTION_TELNET,
-	CONNECTION_TCL,
+	CONNECTION_TCP,
+	CONNECTION_PIPE
 };
 
 typedef struct connection_s
@@ -76,6 +75,8 @@
 extern int server_loop(command_context_t *command_context);
 extern int server_register_commands(command_context_t *context);
 
+extern int server_use_pipes;
+
 #define ERROR_SERVER_REMOTE_CLOSED	(-400)
 #define ERROR_CONNECTION_REJECTED	(-401)
 
Index: src/server/tcl_server.c
===================================================================
--- src/server/tcl_server.c	(revision 1229)
+++ src/server/tcl_server.c	(working copy)
@@ -179,7 +179,7 @@
 		tcl_port = 6666;
 	}
 
-	retval = add_service("tcl", CONNECTION_TCL, tcl_port, 1, tcl_new_connection, tcl_input, tcl_closed, NULL);
+	retval = add_service("tcl", CONNECTION_TCP, tcl_port, 1, tcl_new_connection, tcl_input, tcl_closed, NULL);
 	return retval;
 }
 
Index: src/server/telnet_server.c
===================================================================
--- src/server/telnet_server.c	(revision 1229)
+++ src/server/telnet_server.c	(working copy)
@@ -617,7 +617,7 @@
 
 	telnet_service->banner = banner;
 
-	add_service("telnet", CONNECTION_TELNET, telnet_port, 1, telnet_new_connection, telnet_input, telnet_connection_closed, telnet_service);
+	add_service("telnet", CONNECTION_TCP, telnet_port, 1, telnet_new_connection, telnet_input, telnet_connection_closed, telnet_service);
 
 	return ERROR_OK;
 }

