#include <stdio.h>
 
+#ifdef _WIN32
+#include <io.h>
+#endif
+
 /* replacements for gettimeofday */
 #ifndef HAVE_GETTIMEOFDAY
 
        return (char *) memcpy (new, s, len);
 }
 #endif
+
+#ifdef _WIN32
+int win_select(int max_fd, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *tv)
+{
+       DWORD ms_total, limit;
+       HANDLE handles[MAXIMUM_WAIT_OBJECTS];
+       int handle_slot_to_fd[MAXIMUM_WAIT_OBJECTS];
+       int n_handles = 0, i;
+       fd_set sock_read, sock_write, sock_except;
+       fd_set aread, awrite, aexcept;
+       int sock_max_fd = -1;
+       struct timeval tvslice;
+       int retcode;
+
+#define SAFE_FD_ISSET(fd, set) (set != NULL && FD_ISSET(fd, set))
+
+       /* calculate how long we need to wait in milliseconds */
+       if (tv == NULL) {
+               ms_total = INFINITE;
+       } else {
+               ms_total = tv->tv_sec * 1000;
+               ms_total += tv->tv_usec / 1000;
+       }
+
+       FD_ZERO(&sock_read);
+       FD_ZERO(&sock_write);
+       FD_ZERO(&sock_except);
+
+       /* build an array of handles for non-sockets */
+       for (i = 0; i < max_fd; i++) {
+               if (SAFE_FD_ISSET(i, rfds) || SAFE_FD_ISSET(i, wfds) || SAFE_FD_ISSET(i, efds)) {
+                       handles[n_handles] = (HANDLE)_get_osfhandle(i);
+                       if (handles[n_handles] == INVALID_HANDLE_VALUE) {
+                               /* socket */
+                               if (SAFE_FD_ISSET(i, rfds)) {
+                                       FD_SET(i, &sock_read);
+                               }
+                               if (SAFE_FD_ISSET(i, wfds)) {
+                                       FD_SET(i, &sock_write);
+                               }
+                               if (SAFE_FD_ISSET(i, efds)) {
+                                       FD_SET(i, &sock_except);
+                               }
+                               if (i > sock_max_fd) {
+                                       sock_max_fd = i;
+                               }
+                       } else {
+                               handle_slot_to_fd[n_handles] = i;
+                               n_handles++;
+                       }
+               }
+       }
+
+       if (n_handles == 0) {
+               /* plain sockets only - let winsock handle the whole thing */
+               return select(max_fd, rfds, wfds, efds, tv);
+       }
+
+       /* mixture of handles and sockets; lets multiplex between
+        * winsock and waiting on the handles */
+
+       FD_ZERO(&aread);
+       FD_ZERO(&awrite);
+       FD_ZERO(&aexcept);
+       
+       limit = GetTickCount() + ms_total;
+       do {
+               retcode = 0;
+       
+               if (sock_max_fd >= 0) {
+                       /* overwrite the zero'd sets here; the select call
+                        * will clear those that are not active */
+                       aread = sock_read;
+                       awrite = sock_write;
+                       aexcept = sock_except;
+
+                       tvslice.tv_sec = 0;
+                       tvslice.tv_usec = 100000;
+
+                       retcode = select(sock_max_fd+1, &aread, &awrite, &aexcept, &tvslice);
+               }
+               if (n_handles > 0) {
+                       /* check handles */
+                       DWORD wret;
+
+                       wret = MsgWaitForMultipleObjects(n_handles, handles, FALSE, retcode > 0 ? 0 : 100, QS_ALLEVENTS);
+
+                       if (wret == WAIT_TIMEOUT) {
+                               /* set retcode to 0; this is the default.
+                                * select() may have set it to something else,
+                                * in which case we leave it alone, so this branch
+                                * does nothing */
+                               ;
+                       } else if (wret == WAIT_FAILED) {
+                               if (retcode == 0) {
+                                       retcode = -1;
+                               }
+                       } else {
+                               if (retcode < 0) {
+                                       retcode = 0;
+                               }
+                               for (i = 0; i < n_handles; i++) {
+                                       if (WAIT_OBJECT_0 == WaitForSingleObject(handles[i], 0)) {
+                                               if (SAFE_FD_ISSET(handle_slot_to_fd[i], rfds)) {
+                                                       DWORD dwBytes;
+                                                       
+                                                       if (PeekNamedPipe((HANDLE)_get_osfhandle(handle_slot_to_fd[i]), NULL, 0, NULL, &dwBytes, NULL))
+                                                       {
+                                                               /* check to see if gdb pipe has data available */
+                                                               if (dwBytes)
+                                                               {
+                                                                       FD_SET(handle_slot_to_fd[i], &aread);
+                                                                       retcode++;
+                                                               }
+                                                       }
+                                                       else
+                                                       {
+                                                               FD_SET(handle_slot_to_fd[i], &aread);
+                                                               retcode++;
+                                                       }
+                                               }
+                                               if (SAFE_FD_ISSET(handle_slot_to_fd[i], wfds)) {
+                                                       FD_SET(handle_slot_to_fd[i], &awrite);
+                                                       retcode++;
+                                               }
+                                               if (SAFE_FD_ISSET(handle_slot_to_fd[i], efds)) {
+                                                       FD_SET(handle_slot_to_fd[i], &aexcept);
+                                                       retcode++;
+                                               }
+                                       }
+                               }
+                       }
+               }
+       } while (retcode == 0 && (ms_total == INFINITE || GetTickCount() < limit));
+
+       if (rfds) {
+               *rfds = aread;
+       }
+       if (wfds) {
+               *wfds = awrite;
+       }
+       if (efds) {
+               *efds = aexcept;
+       }
+
+       return retcode;
+}
+#endif
 
        }
        else if (service->type == CONNECTION_PIPE)
        {
-#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_WARNING("cannot change stdout mode to binary");
                if (_setmode(_fileno(stdin), _O_BINARY) < 0)
                        LOG_WARNING("cannot change stdin mode to binary");
+               if (_setmode(_fileno(stderr), _O_BINARY) < 0)
+                       LOG_WARNING("cannot change stderr mode to binary");
 #else
                socket_nonblock(c->fd);
 #endif
                kept_alive();
                
                /* Only while we're sleeping we'll let others run */
-               retval = select(fd_max + 1, &read_fds, NULL, NULL, &tv);
+               retval = socket_select(fd_max + 1, &read_fds, NULL, NULL, &tv);
                openocd_sleep_postlude();
 
                if (retval == -1)
        WORD wVersionRequested;
        WSADATA wsaData;
 
-       wVersionRequested = MAKEWORD( 2, 2 );
+       wVersionRequested = MAKEWORD(2, 2);
 
        if (WSAStartup(wVersionRequested, &wsaData) != 0)
        {
                exit(-1);
        }
 
-       SetConsoleCtrlHandler( ControlHandler, TRUE );
+       if (server_use_pipes == 0)
+       {
+               /* register ctrl-c handler */
+               SetConsoleCtrlHandler(ControlHandler, TRUE);
+       }
+       else
+       {
+               /* we are using pipes so ignore ctrl-c */
+               SetConsoleCtrlHandler(NULL, TRUE);
+       }
 
        signal(SIGINT, sig_handler);
        signal(SIGTERM, sig_handler);