- add gdb pipe support to native win32 (--pipe option)
git-svn-id: svn://svn.berlios.de/openocd/trunk@1294 b42882b7-edfa-0310-969c-e2dbd0fdcd60
This commit is contained in:
parent
f4d82deb36
commit
ab87627c5c
|
@ -557,7 +557,6 @@ the @option{-s <search>} switch. The current directory and the OpenOCD
|
||||||
target library is in the search path by default.
|
target library is in the search path by default.
|
||||||
|
|
||||||
For details on the @option{-p} option. @xref{Connecting to GDB}.
|
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
|
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
|
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
|
#if BUILD_ECOSBOARD == 1
|
||||||
/* pipes unsupported on hosted platforms */
|
/* pipes unsupported on hosted platforms */
|
||||||
LOG_WARNING("pipes not supported on this platform");
|
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
|
#else
|
||||||
server_use_pipes = 1;
|
server_use_pipes = 1;
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,6 +68,10 @@ void *fill_malloc(size_t size)
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <io.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/* replacements for gettimeofday */
|
/* replacements for gettimeofday */
|
||||||
#ifndef HAVE_GETTIMEOFDAY
|
#ifndef HAVE_GETTIMEOFDAY
|
||||||
|
|
||||||
|
@ -137,3 +141,151 @@ char* strndup(const char *s, size_t n)
|
||||||
return (char *) memcpy (new, s, len);
|
return (char *) memcpy (new, s, len);
|
||||||
}
|
}
|
||||||
#endif
|
#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 */
|
#endif /* IS_MINGW */
|
||||||
|
|
||||||
|
int win_select(int max_fd, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *tv);
|
||||||
|
|
||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
/* generic socket functions for Windows and Posix */
|
/* generic socket functions for Windows and Posix */
|
||||||
|
@ -221,6 +224,15 @@ static __inline void socket_nonblock(int fd)
|
||||||
#endif
|
#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
|
#ifndef HAVE_ELF_H
|
||||||
|
|
||||||
typedef struct
|
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_sec = timeout_s;
|
||||||
tv.tv_usec = 0;
|
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
|
/* This can typically be because a "monitor" command took too long
|
||||||
* before printing any progress messages
|
* 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)
|
else if (service->type == CONNECTION_PIPE)
|
||||||
{
|
{
|
||||||
#ifndef _WIN32
|
|
||||||
c->fd = service->fd;
|
c->fd = service->fd;
|
||||||
|
|
||||||
/* do not check for new connections again on stdin */
|
/* do not check for new connections again on stdin */
|
||||||
service->fd = -1;
|
service->fd = -1;
|
||||||
#endif
|
|
||||||
LOG_INFO("accepting '%s' connection from pipe", service->name);
|
LOG_INFO("accepting '%s' connection from pipe", service->name);
|
||||||
if ((retval = service->new_connection(c)) != ERROR_OK)
|
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");
|
LOG_WARNING("cannot change stdout mode to binary");
|
||||||
if (_setmode(_fileno(stdin), _O_BINARY) < 0)
|
if (_setmode(_fileno(stdin), _O_BINARY) < 0)
|
||||||
LOG_WARNING("cannot change stdin mode to binary");
|
LOG_WARNING("cannot change stdin mode to binary");
|
||||||
|
if (_setmode(_fileno(stderr), _O_BINARY) < 0)
|
||||||
|
LOG_WARNING("cannot change stderr mode to binary");
|
||||||
#else
|
#else
|
||||||
socket_nonblock(c->fd);
|
socket_nonblock(c->fd);
|
||||||
#endif
|
#endif
|
||||||
|
@ -365,7 +366,7 @@ int server_loop(command_context_t *command_context)
|
||||||
kept_alive();
|
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);
|
retval = socket_select(fd_max + 1, &read_fds, NULL, NULL, &tv);
|
||||||
openocd_sleep_postlude();
|
openocd_sleep_postlude();
|
||||||
|
|
||||||
if (retval == -1)
|
if (retval == -1)
|
||||||
|
@ -503,7 +504,7 @@ int server_init(void)
|
||||||
WORD wVersionRequested;
|
WORD wVersionRequested;
|
||||||
WSADATA wsaData;
|
WSADATA wsaData;
|
||||||
|
|
||||||
wVersionRequested = MAKEWORD( 2, 2 );
|
wVersionRequested = MAKEWORD(2, 2);
|
||||||
|
|
||||||
if (WSAStartup(wVersionRequested, &wsaData) != 0)
|
if (WSAStartup(wVersionRequested, &wsaData) != 0)
|
||||||
{
|
{
|
||||||
|
@ -511,7 +512,16 @@ int server_init(void)
|
||||||
exit(-1);
|
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(SIGINT, sig_handler);
|
||||||
signal(SIGTERM, sig_handler);
|
signal(SIGTERM, sig_handler);
|
||||||
|
|
Loading…
Reference in New Issue