mingw-hdep.c revision 1.7
1/* Host support routines for MinGW, for GDB, the GNU debugger.
2
3   Copyright (C) 2006-2017 Free Software Foundation, Inc.
4
5   This file is part of GDB.
6
7   This program is free software; you can redistribute it and/or modify
8   it under the terms of the GNU General Public License as published by
9   the Free Software Foundation; either version 3 of the License, or
10   (at your option) any later version.
11
12   This program is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   GNU General Public License for more details.
16
17   You should have received a copy of the GNU General Public License
18   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
20#include "defs.h"
21#include "main.h"
22#include "serial.h"
23#include "event-loop.h"
24
25#include "gdb_select.h"
26#include "readline/readline.h"
27
28#include <windows.h>
29
30/* Return an absolute file name of the running GDB, if possible, or
31   ARGV0 if not.  The return value is in malloc'ed storage.  */
32
33char *
34windows_get_absolute_argv0 (const char *argv0)
35{
36  char full_name[PATH_MAX];
37
38  if (GetModuleFileName (NULL, full_name, PATH_MAX))
39    return xstrdup (full_name);
40  return xstrdup (argv0);
41}
42
43/* Wrapper for select.  On Windows systems, where the select interface
44   only works for sockets, this uses the GDB serial abstraction to
45   handle sockets, consoles, pipes, and serial ports.
46
47   The arguments to this function are the same as the traditional
48   arguments to select on POSIX platforms.  */
49
50int
51gdb_select (int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
52	    struct timeval *timeout)
53{
54  static HANDLE never_handle;
55  HANDLE handles[MAXIMUM_WAIT_OBJECTS];
56  HANDLE h;
57  DWORD event;
58  DWORD num_handles;
59  /* SCBS contains serial control objects corresponding to file
60     descriptors in READFDS and WRITEFDS.  */
61  struct serial *scbs[MAXIMUM_WAIT_OBJECTS];
62  /* The number of valid entries in SCBS.  */
63  size_t num_scbs;
64  int fd;
65  int num_ready;
66  size_t indx;
67
68  num_ready = 0;
69  num_handles = 0;
70  num_scbs = 0;
71  for (fd = 0; fd < n; ++fd)
72    {
73      HANDLE read = NULL, except = NULL;
74      struct serial *scb;
75
76      /* There is no support yet for WRITEFDS.  At present, this isn't
77	 used by GDB -- but we do not want to silently ignore WRITEFDS
78	 if something starts using it.  */
79      gdb_assert (!writefds || !FD_ISSET (fd, writefds));
80
81      if ((!readfds || !FD_ISSET (fd, readfds))
82	  && (!exceptfds || !FD_ISSET (fd, exceptfds)))
83	continue;
84
85      scb = serial_for_fd (fd);
86      if (scb)
87	{
88	  serial_wait_handle (scb, &read, &except);
89	  scbs[num_scbs++] = scb;
90	}
91
92      if (read == NULL)
93	read = (HANDLE) _get_osfhandle (fd);
94      if (except == NULL)
95	{
96	  if (!never_handle)
97	    never_handle = CreateEvent (0, FALSE, FALSE, 0);
98
99	  except = never_handle;
100	}
101
102      if (readfds && FD_ISSET (fd, readfds))
103	{
104	  gdb_assert (num_handles < MAXIMUM_WAIT_OBJECTS);
105	  handles[num_handles++] = read;
106	}
107
108      if (exceptfds && FD_ISSET (fd, exceptfds))
109	{
110	  gdb_assert (num_handles < MAXIMUM_WAIT_OBJECTS);
111	  handles[num_handles++] = except;
112	}
113    }
114
115  gdb_assert (num_handles <= MAXIMUM_WAIT_OBJECTS);
116
117  event = WaitForMultipleObjects (num_handles,
118				  handles,
119				  FALSE,
120				  timeout
121				  ? (timeout->tv_sec * 1000
122				     + timeout->tv_usec / 1000)
123				  : INFINITE);
124  /* EVENT can only be a value in the WAIT_ABANDONED_0 range if the
125     HANDLES included an abandoned mutex.  Since GDB doesn't use
126     mutexes, that should never occur.  */
127  gdb_assert (!(WAIT_ABANDONED_0 <= event
128		&& event < WAIT_ABANDONED_0 + num_handles));
129  /* We no longer need the helper threads to check for activity.  */
130  for (indx = 0; indx < num_scbs; ++indx)
131    serial_done_wait_handle (scbs[indx]);
132  if (event == WAIT_FAILED)
133    return -1;
134  if (event == WAIT_TIMEOUT)
135    return 0;
136  /* Run through the READFDS, clearing bits corresponding to descriptors
137     for which input is unavailable.  */
138  h = handles[event - WAIT_OBJECT_0];
139  for (fd = 0, indx = 0; fd < n; ++fd)
140    {
141      HANDLE fd_h;
142
143      if ((!readfds || !FD_ISSET (fd, readfds))
144	  && (!exceptfds || !FD_ISSET (fd, exceptfds)))
145	continue;
146
147      if (readfds && FD_ISSET (fd, readfds))
148	{
149	  fd_h = handles[indx++];
150	  /* This handle might be ready, even though it wasn't the handle
151	     returned by WaitForMultipleObjects.  */
152	  if (fd_h != h && WaitForSingleObject (fd_h, 0) != WAIT_OBJECT_0)
153	    FD_CLR (fd, readfds);
154	  else
155	    num_ready++;
156	}
157
158      if (exceptfds && FD_ISSET (fd, exceptfds))
159	{
160	  fd_h = handles[indx++];
161	  /* This handle might be ready, even though it wasn't the handle
162	     returned by WaitForMultipleObjects.  */
163	  if (fd_h != h && WaitForSingleObject (fd_h, 0) != WAIT_OBJECT_0)
164	    FD_CLR (fd, exceptfds);
165	  else
166	    num_ready++;
167	}
168    }
169
170  /* With multi-threaded SIGINT handling, there is a race between the
171     readline signal handler and GDB.  It may still be in
172     rl_prep_terminal in another thread.  Do not return until it is
173     done; we can check the state here because we never longjmp from
174     signal handlers on Windows.  */
175  while (RL_ISSTATE (RL_STATE_SIGHANDLER))
176    Sleep (1);
177
178  return num_ready;
179}
180