git-svn-id: svn://svn.berlios.de/openocd/trunk@1294 b42882b7-edfa-0310-969c-e2dbd0fdcd60tags/v0.1.0
@@ -557,7 +557,6 @@ the @option{-s <search>} switch. The current directory and the OpenOCD | |||
target library is in the search path by default. | |||
For details on the @option{-p} option. @xref{Connecting to GDB}. | |||
Option @option{-p} is not currently supported under native win32. | |||
Note! OpenOCD will launch the GDB & telnet server even if it can not | |||
establish a connection with the target. In general, it is possible for | |||
@@ -148,14 +148,8 @@ int parse_cmdline_args(struct command_context_s *cmd_ctx, int argc, char *argv[] | |||
#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; | |||
} | |||
@@ -68,6 +68,10 @@ void *fill_malloc(size_t size) | |||
#include <stdio.h> | |||
#ifdef _WIN32 | |||
#include <io.h> | |||
#endif | |||
/* replacements for gettimeofday */ | |||
#ifndef HAVE_GETTIMEOFDAY | |||
@@ -137,3 +141,151 @@ char* strndup(const char *s, size_t n) | |||
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 |
@@ -180,6 +180,9 @@ static __inline void outb(unsigned char value, unsigned short int port) | |||
} | |||
#endif /* IS_MINGW */ | |||
int win_select(int max_fd, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *tv); | |||
#endif /* _WIN32 */ | |||
/* generic socket functions for Windows and Posix */ | |||
@@ -221,6 +224,15 @@ static __inline void socket_nonblock(int fd) | |||
#endif | |||
} | |||
static __inline int socket_select(int max_fd, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *tv) | |||
{ | |||
#ifdef _WIN32 | |||
return win_select(max_fd, rfds, wfds, efds, tv); | |||
#else | |||
return select(max_fd, rfds, wfds, efds, tv); | |||
#endif | |||
} | |||
#ifndef HAVE_ELF_H | |||
typedef struct | |||
@@ -126,7 +126,7 @@ int check_pending(connection_t *connection, int timeout_s, int *got_data) | |||
tv.tv_sec = timeout_s; | |||
tv.tv_usec = 0; | |||
if (select(connection->fd + 1, &read_fds, NULL, NULL, &tv) == 0) | |||
if (socket_select(connection->fd + 1, &read_fds, NULL, NULL, &tv) == 0) | |||
{ | |||
/* This can typically be because a "monitor" command took too long | |||
* before printing any progress messages | |||
@@ -97,12 +97,11 @@ int add_connection(service_t *service, command_context_t *cmd_ctx) | |||
} | |||
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) | |||
{ | |||
@@ -223,6 +222,8 @@ int add_service(char *name, enum connection_type type, unsigned short port, int | |||
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 | |||
@@ -365,7 +366,7 @@ int server_loop(command_context_t *command_context) | |||
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) | |||
@@ -503,7 +504,7 @@ int server_init(void) | |||
WORD wVersionRequested; | |||
WSADATA wsaData; | |||
wVersionRequested = MAKEWORD( 2, 2 ); | |||
wVersionRequested = MAKEWORD(2, 2); | |||
if (WSAStartup(wVersionRequested, &wsaData) != 0) | |||
{ | |||
@@ -511,7 +512,16 @@ int server_init(void) | |||
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); | |||