aboutsummaryrefslogtreecommitdiff
path: root/gdb/mingw-hdep.c
diff options
context:
space:
mode:
authorDaniel Jacobowitz <drow@false.org>2006-02-10 22:01:43 +0000
committerDaniel Jacobowitz <drow@false.org>2006-02-10 22:01:43 +0000
commit0ea3f30e219bd42259f09f68bcd605bf4ed4a1ea (patch)
tree07c791175cea3abee634fa9ccec99e18031ed5cd /gdb/mingw-hdep.c
parent121ce6e53dd5751c6938ab86cbec2742702d06eb (diff)
downloadgdb-0ea3f30e219bd42259f09f68bcd605bf4ed4a1ea.zip
gdb-0ea3f30e219bd42259f09f68bcd605bf4ed4a1ea.tar.gz
gdb-0ea3f30e219bd42259f09f68bcd605bf4ed4a1ea.tar.bz2
* NEWS: Mention native Windows support.
* Makefile.in (gdb_select_h, ser_tcp_h): New. (ALLDEPFILES): Add ser-mingw.c. (event-loop.o, inflow.o, mingw-hdep.o, posix-hdep.o, ser-base.o) (ser-tcp.o, ser-unix.o): Update. (ser-mingw.o): New rule. * configure: Regenerated. * configure.ac: Add ser-mingw.o for mingw32. * ser-mingw.c: New file. * event-loop.c: Include "gdb_select.h". (gdb_select): Remove, moved to mingw-hdep.c and posix-hdep.c. * ser-base.c: Include "gdb_select.h". (ser_base_wait_for): Use gdb_select. * serial.c (serial_for_fd): New function. (serial_fdopen): Try "terminal" before "hardwire". Initialize the allocated struct serial. (serial_wait_handle): New function. * serial.h (serial_for_fd, serial_wait_handle): New prototypes. (struct serial_ops) [USE_WIN32API]: Add wait_handle. * gdb_select.h: New file. * ser-tcp.c: Include "ser-tcp.h". Remove unused "ser-unix.h" include. (net_close, net_read_prim, net_write_prim): Make global. (net_open): Likewise. Pass an exception set to select. Whitespace fix. Document why we can not use gdb_select. (_initialize_ser_tcp) [USE_WIN32API]: Do not register TCP support here. * ser-tcp.h: New file. * inflow.c (gdb_has_a_terminal): Don't initialize stdin_serial here. (handle_sigio): Use gdb_select. (initialize_stdin_serial): New function. * terminal.h (initialize_stdin_serial): New prototype. * top.c (gdb_init): Call initialize_stdin_serial. * mingw-hdep.c (gdb_select): New function, moved from gdb_select in event-loop.c. Add exception condition support. Use serial_for_fd and serial_wait_handle. Fix timeout handling. * posix-hdep.c: Include "gdb_select.h". (gdb_select): New function. * remote-st.c (connect_command): Use gdb_select. * ser-unix.c: Include "gdb_select.h". (hardwire_send_break, wait_for): Use gdb_select.
Diffstat (limited to 'gdb/mingw-hdep.c')
-rw-r--r--gdb/mingw-hdep.c124
1 files changed, 124 insertions, 0 deletions
diff --git a/gdb/mingw-hdep.c b/gdb/mingw-hdep.c
index 1318cfd..79b23dc 100644
--- a/gdb/mingw-hdep.c
+++ b/gdb/mingw-hdep.c
@@ -21,7 +21,10 @@
Boston, MA 02110-1301, USA. */
#include "defs.h"
+#include "serial.h"
+#include "gdb_assert.h"
+#include "gdb_select.h"
#include "gdb_string.h"
#include <windows.h>
@@ -69,3 +72,124 @@ safe_strerror (int errnum)
return buffer;
}
+
+/* Wrapper for select. On Windows systems, where the select interface
+ only works for sockets, this uses the GDB serial abstraction to
+ handle sockets, consoles, pipes, and serial ports.
+
+ The arguments to this function are the same as the traditional
+ arguments to select on POSIX platforms. */
+
+int
+gdb_select (int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
+ struct timeval *timeout)
+{
+ static HANDLE never_handle;
+ HANDLE handles[MAXIMUM_WAIT_OBJECTS];
+ HANDLE h;
+ DWORD event;
+ DWORD num_handles;
+ int fd;
+ int num_ready;
+ int indx;
+
+ num_ready = 0;
+ num_handles = 0;
+ for (fd = 0; fd < n; ++fd)
+ {
+ HANDLE read = NULL, except = NULL;
+ struct serial *scb;
+
+ /* There is no support yet for WRITEFDS. At present, this isn't
+ used by GDB -- but we do not want to silently ignore WRITEFDS
+ if something starts using it. */
+ gdb_assert (!writefds || !FD_ISSET (fd, writefds));
+
+ if (!FD_ISSET (fd, readfds)
+ && !FD_ISSET (fd, exceptfds))
+ continue;
+ h = (HANDLE) _get_osfhandle (fd);
+
+ scb = serial_for_fd (fd);
+ if (scb)
+ serial_wait_handle (scb, &read, &except);
+
+ if (read == NULL)
+ read = h;
+ if (except == NULL)
+ {
+ if (!never_handle)
+ never_handle = CreateEvent (0, FALSE, FALSE, 0);
+
+ except = never_handle;
+ }
+
+ if (FD_ISSET (fd, readfds))
+ {
+ gdb_assert (num_handles < MAXIMUM_WAIT_OBJECTS);
+ handles[num_handles++] = read;
+ }
+
+ if (FD_ISSET (fd, exceptfds))
+ {
+ gdb_assert (num_handles < MAXIMUM_WAIT_OBJECTS);
+ handles[num_handles++] = except;
+ }
+ }
+ /* If we don't need to wait for any handles, we are done. */
+ if (!num_handles)
+ {
+ if (timeout)
+ Sleep (timeout->tv_sec * 1000 + timeout->tv_usec / 1000);
+
+ return 0;
+ }
+
+ event = WaitForMultipleObjects (num_handles,
+ handles,
+ FALSE,
+ timeout
+ ? (timeout->tv_sec * 1000
+ + timeout->tv_usec / 1000)
+ : INFINITE);
+ /* EVENT can only be a value in the WAIT_ABANDONED_0 range if the
+ HANDLES included an abandoned mutex. Since GDB doesn't use
+ mutexes, that should never occur. */
+ gdb_assert (!(WAIT_ABANDONED_0 <= event
+ && event < WAIT_ABANDONED_0 + num_handles));
+ if (event == WAIT_FAILED)
+ return -1;
+ if (event == WAIT_TIMEOUT)
+ return 0;
+ /* Run through the READFDS, clearing bits corresponding to descriptors
+ for which input is unavailable. */
+ h = handles[event - WAIT_OBJECT_0];
+ for (fd = 0, indx = 0; fd < n; ++fd)
+ {
+ HANDLE fd_h;
+
+ if (FD_ISSET (fd, readfds))
+ {
+ fd_h = handles[indx++];
+ /* This handle might be ready, even though it wasn't the handle
+ returned by WaitForMultipleObjects. */
+ if (fd_h != h && WaitForSingleObject (fd_h, 0) != WAIT_OBJECT_0)
+ FD_CLR (fd, readfds);
+ else
+ num_ready++;
+ }
+
+ if (FD_ISSET (fd, exceptfds))
+ {
+ fd_h = handles[indx++];
+ /* This handle might be ready, even though it wasn't the handle
+ returned by WaitForMultipleObjects. */
+ if (fd_h != h && WaitForSingleObject (fd_h, 0) != WAIT_OBJECT_0)
+ FD_CLR (fd, exceptfds);
+ else
+ num_ready++;
+ }
+ }
+
+ return num_ready;
+}