1 /***************************************************************************
2 * Copyright (C) 2006 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * Copyright (C) 2007,2008 Øyvind Harboe *
6 * oyvind.harboe@zylin.com *
8 * Copyright (C) 2008 by Spencer Oliver *
9 * spen@spen-soft.co.uk *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * GNU General Public License for more details. *
21 * You should have received a copy of the GNU General Public License *
22 * along with this program; if not, write to the *
23 * Free Software Foundation, Inc., *
24 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
25 ***************************************************************************/
26 /* DANGER!!!! These must be defined *BEFORE* replacements.h and the malloc() macro!!!! */
33 * will alloc memory and clear it
35 void *clear_malloc(size_t size
)
37 void *t
= malloc(size
);
40 memset(t
, 0x00, size
);
45 void *fill_malloc(size_t size
)
47 void *t
= malloc(size
);
50 /* We want to initialize memory to some known bad state. */
51 /* 0 and 0xff yields 0 and -1 as integers, which often */
52 /* have meaningful values. 0x5555... is not often a valid */
53 /* integer and is quite easily spotted in the debugger */
54 /* also it is almost certainly an invalid address */
55 memset(t
, 0x55, size
);
60 #define IN_REPLACEMENTS_C
72 /* replacements for gettimeofday */
73 #ifndef HAVE_GETTIMEOFDAY
79 #define EPOCHFILETIME (116444736000000000i64)
81 #define EPOCHFILETIME (116444736000000000LL)
84 int gettimeofday(struct timeval
*tv
, struct timezone
*tz
)
93 GetSystemTimeAsFileTime(&ft
);
94 li
.LowPart
= ft
.dwLowDateTime
;
95 li
.HighPart
= ft
.dwHighDateTime
;
96 t
= li
.QuadPart
; /* In 100-nanosecond intervals */
97 t
-= EPOCHFILETIME
; /* Offset to the Epoch time */
98 t
/= 10; /* In microseconds */
99 tv
->tv_sec
= (long)(t
/ 1000000);
100 tv
->tv_usec
= (long)(t
% 1000000);
110 tz
->tz_minuteswest
= _timezone
/ 60;
111 tz
->tz_dsttime
= _daylight
;
118 #endif /* HAVE_GETTIMEOFDAY */
121 size_t strnlen(const char *s
, size_t maxlen
)
123 const char *end
= (const char *)memchr(s
, '\0', maxlen
);
124 return end
? (size_t) (end
- s
) : maxlen
;
129 char* strndup(const char *s
, size_t n
)
131 size_t len
= strnlen (s
, n
);
132 char *new = (char *) malloc (len
+ 1);
138 return (char *) memcpy (new, s
, len
);
143 int win_select(int max_fd
, fd_set
*rfds
, fd_set
*wfds
, fd_set
*efds
, struct timeval
*tv
)
145 DWORD ms_total
, limit
;
146 HANDLE handles
[MAXIMUM_WAIT_OBJECTS
];
147 int handle_slot_to_fd
[MAXIMUM_WAIT_OBJECTS
];
148 int n_handles
= 0, i
;
149 fd_set sock_read
, sock_write
, sock_except
;
150 fd_set aread
, awrite
, aexcept
;
151 int sock_max_fd
= -1;
152 struct timeval tvslice
;
155 #define SAFE_FD_ISSET(fd, set) (set != NULL && FD_ISSET(fd, set))
157 /* calculate how long we need to wait in milliseconds */
161 ms_total
= tv
->tv_sec
* 1000;
162 ms_total
+= tv
->tv_usec
/ 1000;
166 FD_ZERO(&sock_write
);
167 FD_ZERO(&sock_except
);
169 /* build an array of handles for non-sockets */
170 for (i
= 0; i
< max_fd
; i
++) {
171 if (SAFE_FD_ISSET(i
, rfds
) || SAFE_FD_ISSET(i
, wfds
) || SAFE_FD_ISSET(i
, efds
)) {
172 intptr_t handle
= (intptr_t) _get_osfhandle(i
);
173 handles
[n_handles
] = (HANDLE
)handle
;
174 if (handles
[n_handles
] == INVALID_HANDLE_VALUE
) {
176 if (SAFE_FD_ISSET(i
, rfds
)) {
177 FD_SET(i
, &sock_read
);
179 if (SAFE_FD_ISSET(i
, wfds
)) {
180 FD_SET(i
, &sock_write
);
182 if (SAFE_FD_ISSET(i
, efds
)) {
183 FD_SET(i
, &sock_except
);
185 if (i
> sock_max_fd
) {
189 handle_slot_to_fd
[n_handles
] = i
;
195 if (n_handles
== 0) {
196 /* plain sockets only - let winsock handle the whole thing */
197 return select(max_fd
, rfds
, wfds
, efds
, tv
);
200 /* mixture of handles and sockets; lets multiplex between
201 * winsock and waiting on the handles */
207 limit
= GetTickCount() + ms_total
;
211 if (sock_max_fd
>= 0) {
212 /* overwrite the zero'd sets here; the select call
213 * will clear those that are not active */
216 aexcept
= sock_except
;
219 tvslice
.tv_usec
= 100000;
221 retcode
= select(sock_max_fd
+ 1, &aread
, &awrite
, &aexcept
, &tvslice
);
227 wret
= MsgWaitForMultipleObjects(n_handles
, handles
, FALSE
, retcode
> 0 ? 0 : 100, QS_ALLEVENTS
);
229 if (wret
== WAIT_TIMEOUT
) {
230 /* set retcode to 0; this is the default.
231 * select() may have set it to something else,
232 * in which case we leave it alone, so this branch
235 } else if (wret
== WAIT_FAILED
) {
243 for (i
= 0; i
< n_handles
; i
++) {
244 if (WAIT_OBJECT_0
== WaitForSingleObject(handles
[i
], 0)) {
245 if (SAFE_FD_ISSET(handle_slot_to_fd
[i
], rfds
)) {
247 intptr_t handle
= (intptr_t) _get_osfhandle(handle_slot_to_fd
[i
]);
249 if (PeekNamedPipe((HANDLE
)handle
, NULL
, 0, NULL
, &dwBytes
, NULL
))
251 /* check to see if gdb pipe has data available */
254 FD_SET(handle_slot_to_fd
[i
], &aread
);
260 FD_SET(handle_slot_to_fd
[i
], &aread
);
264 if (SAFE_FD_ISSET(handle_slot_to_fd
[i
], wfds
)) {
265 FD_SET(handle_slot_to_fd
[i
], &awrite
);
268 if (SAFE_FD_ISSET(handle_slot_to_fd
[i
], efds
)) {
269 FD_SET(handle_slot_to_fd
[i
], &aexcept
);
276 } while (retcode
== 0 && (ms_total
== INFINITE
|| GetTickCount() < limit
));