Commit | Line | Data |
---|---|---|
121ce6e5 DJ |
1 | /* Host support routines for MinGW, for GDB, the GNU debugger. |
2 | ||
61baf725 | 3 | Copyright (C) 2006-2017 Free Software Foundation, Inc. |
121ce6e5 DJ |
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 | |
a9762ec7 | 9 | the Free Software Foundation; either version 3 of the License, or |
121ce6e5 DJ |
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 | |
a9762ec7 | 18 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
121ce6e5 DJ |
19 | |
20 | #include "defs.h" | |
d9ac0664 | 21 | #include "main.h" |
0ea3f30e | 22 | #include "serial.h" |
b803fb0f | 23 | #include "event-loop.h" |
121ce6e5 | 24 | |
0ea3f30e | 25 | #include "gdb_select.h" |
b803fb0f | 26 | #include "readline/readline.h" |
121ce6e5 DJ |
27 | |
28 | #include <windows.h> | |
29 | ||
d9ac0664 EZ |
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 | ||
33 | char * | |
34 | windows_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 | ||
0ea3f30e DJ |
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 | ||
50 | int | |
51 | gdb_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; | |
4577549b DJ |
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; | |
0ea3f30e DJ |
64 | int fd; |
65 | int num_ready; | |
4577549b | 66 | size_t indx; |
0ea3f30e DJ |
67 | |
68 | num_ready = 0; | |
69 | num_handles = 0; | |
4577549b | 70 | num_scbs = 0; |
0ea3f30e DJ |
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 | ||
98739726 DJ |
81 | if ((!readfds || !FD_ISSET (fd, readfds)) |
82 | && (!exceptfds || !FD_ISSET (fd, exceptfds))) | |
0ea3f30e | 83 | continue; |
0ea3f30e DJ |
84 | |
85 | scb = serial_for_fd (fd); | |
86 | if (scb) | |
4577549b DJ |
87 | { |
88 | serial_wait_handle (scb, &read, &except); | |
89 | scbs[num_scbs++] = scb; | |
90 | } | |
0ea3f30e DJ |
91 | |
92 | if (read == NULL) | |
4577549b | 93 | read = (HANDLE) _get_osfhandle (fd); |
0ea3f30e DJ |
94 | if (except == NULL) |
95 | { | |
96 | if (!never_handle) | |
97 | never_handle = CreateEvent (0, FALSE, FALSE, 0); | |
98 | ||
99 | except = never_handle; | |
100 | } | |
101 | ||
98739726 | 102 | if (readfds && FD_ISSET (fd, readfds)) |
0ea3f30e DJ |
103 | { |
104 | gdb_assert (num_handles < MAXIMUM_WAIT_OBJECTS); | |
105 | handles[num_handles++] = read; | |
106 | } | |
107 | ||
98739726 | 108 | if (exceptfds && FD_ISSET (fd, exceptfds)) |
0ea3f30e DJ |
109 | { |
110 | gdb_assert (num_handles < MAXIMUM_WAIT_OBJECTS); | |
111 | handles[num_handles++] = except; | |
112 | } | |
113 | } | |
0ea3f30e | 114 | |
585a46a2 | 115 | gdb_assert (num_handles <= MAXIMUM_WAIT_OBJECTS); |
0ea3f30e DJ |
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)); | |
4577549b DJ |
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]); | |
0ea3f30e DJ |
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; | |
c3e2b812 | 142 | |
98739726 DJ |
143 | if ((!readfds || !FD_ISSET (fd, readfds)) |
144 | && (!exceptfds || !FD_ISSET (fd, exceptfds))) | |
c3e2b812 | 145 | continue; |
0ea3f30e | 146 | |
98739726 | 147 | if (readfds && FD_ISSET (fd, readfds)) |
0ea3f30e DJ |
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 | ||
98739726 | 158 | if (exceptfds && FD_ISSET (fd, exceptfds)) |
0ea3f30e DJ |
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 | ||
b803fb0f DJ |
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 | ||
0ea3f30e DJ |
178 | return num_ready; |
179 | } |