OpenOCD
replacements.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 /***************************************************************************
4  * Copyright (C) 2006 by Dominic Rath *
5  * Dominic.Rath@gmx.de *
6  * *
7  * Copyright (C) 2007,2008 Øyvind Harboe *
8  * oyvind.harboe@zylin.com *
9  * *
10  * Copyright (C) 2008 by Spencer Oliver *
11  * spen@spen-soft.co.uk *
12  ***************************************************************************/
13 
14 #ifdef HAVE_CONFIG_H
15 #include "config.h"
16 #endif
17 
18 /* define IN_REPLACEMENTS_C before include replacements.h */
19 #define IN_REPLACEMENTS_C
20 #include "replacements.h"
21 
22 #include <stdlib.h>
23 #include <string.h>
24 
25 /*
26  * clear_malloc
27  *
28  * will alloc memory and clear it
29  */
30 void *clear_malloc(size_t size)
31 {
32  void *t = malloc(size);
33  if (t)
34  memset(t, 0x00, size);
35  return t;
36 }
37 
38 void *fill_malloc(size_t size)
39 {
40  void *t = malloc(size);
41  if (t) {
42  /* We want to initialize memory to some known bad state.
43  * 0 and 0xff yields 0 and -1 as integers, which often
44  * have meaningful values. 0x5555... is not often a valid
45  * integer and is quite easily spotted in the debugger
46  * also it is almost certainly an invalid address */
47  memset(t, 0x55, size);
48  }
49  return t;
50 }
51 
52 #ifdef HAVE_STRINGS_H
53 #include <strings.h>
54 #endif
55 
56 #ifdef _WIN32
57 #include <io.h>
58 #include <winsock2.h>
59 #endif
60 
61 /* replacements for gettimeofday */
62 #ifndef HAVE_GETTIMEOFDAY
63 
64 /* Windows */
65 #ifdef _WIN32
66 
67 #ifndef __GNUC__
68 #define EPOCHFILETIME (116444736000000000i64)
69 #else
70 #define EPOCHFILETIME (116444736000000000LL)
71 #endif
72 
73 int gettimeofday(struct timeval *tv, struct timezone *tz)
74 {
75  FILETIME ft;
76  LARGE_INTEGER li;
77  __int64 t;
78  static int tzflag;
79 
80  if (tv) {
81  GetSystemTimeAsFileTime(&ft);
82  li.LowPart = ft.dwLowDateTime;
83  li.HighPart = ft.dwHighDateTime;
84  t = li.QuadPart; /* In 100-nanosecond intervals */
85  t -= EPOCHFILETIME; /* Offset to the Epoch time */
86  t /= 10; /* In microseconds */
87  tv->tv_sec = (long)(t / 1000000);
88  tv->tv_usec = (long)(t % 1000000);
89  }
90 
91  if (tz) {
92  if (!tzflag) {
93  _tzset();
94  tzflag++;
95  }
96  tz->tz_minuteswest = _timezone / 60;
97  tz->tz_dsttime = _daylight;
98  }
99 
100  return 0;
101 }
102 #endif /* _WIN32 */
103 
104 #endif /* HAVE_GETTIMEOFDAY */
105 
106 #ifndef HAVE_STRNLEN
107 size_t strnlen(const char *s, size_t maxlen)
108 {
109  const char *end = (const char *)memchr(s, '\0', maxlen);
110  return end ? (size_t) (end - s) : maxlen;
111 }
112 #endif
113 
114 #ifndef HAVE_STRNDUP
115 char *strndup(const char *s, size_t n)
116 {
117  size_t len = strnlen(s, n);
118  char *new = malloc(len + 1);
119 
120  if (!new)
121  return NULL;
122 
123  new[len] = '\0';
124  return (char *) memcpy(new, s, len);
125 }
126 #endif
127 
128 #ifdef _WIN32
129 int win_select(int max_fd, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *tv)
130 {
131  DWORD ms_total, limit;
132  HANDLE handles[MAXIMUM_WAIT_OBJECTS];
133  int handle_slot_to_fd[MAXIMUM_WAIT_OBJECTS];
134  int n_handles = 0, i;
135  fd_set sock_read, sock_write, sock_except;
136  fd_set aread, awrite, aexcept;
137  int sock_max_fd = -1;
138  struct timeval tvslice;
139  int retcode;
140 
141 #define SAFE_FD_ISSET(fd, set) (set && FD_ISSET(fd, set))
142 
143  /* calculate how long we need to wait in milliseconds */
144  if (!tv)
145  ms_total = INFINITE;
146  else {
147  ms_total = tv->tv_sec * 1000;
148  ms_total += tv->tv_usec / 1000;
149  }
150 
151  FD_ZERO(&sock_read);
152  FD_ZERO(&sock_write);
153  FD_ZERO(&sock_except);
154 
155  /* build an array of handles for non-sockets */
156  for (i = 0; i < max_fd; i++) {
157  if (SAFE_FD_ISSET(i, rfds) || SAFE_FD_ISSET(i, wfds) || SAFE_FD_ISSET(i, efds)) {
158  intptr_t handle = (intptr_t) _get_osfhandle(i);
159  handles[n_handles] = (HANDLE)handle;
160  if (handles[n_handles] == INVALID_HANDLE_VALUE) {
161  /* socket */
162  if (SAFE_FD_ISSET(i, rfds))
163  FD_SET(i, &sock_read);
164  if (SAFE_FD_ISSET(i, wfds))
165  FD_SET(i, &sock_write);
166  if (SAFE_FD_ISSET(i, efds))
167  FD_SET(i, &sock_except);
168  if (i > sock_max_fd)
169  sock_max_fd = i;
170  } else {
171  handle_slot_to_fd[n_handles] = i;
172  n_handles++;
173  }
174  }
175  }
176 
177  if (n_handles == 0) {
178  /* plain sockets only - let winsock handle the whole thing */
179  return select(max_fd, rfds, wfds, efds, tv);
180  }
181 
182  /* mixture of handles and sockets; lets multiplex between
183  * winsock and waiting on the handles */
184 
185  FD_ZERO(&aread);
186  FD_ZERO(&awrite);
187  FD_ZERO(&aexcept);
188 
189  limit = GetTickCount() + ms_total;
190  do {
191  retcode = 0;
192 
193  if (sock_max_fd >= 0) {
194  /* overwrite the zero'd sets here; the select call
195  * will clear those that are not active */
196  aread = sock_read;
197  awrite = sock_write;
198  aexcept = sock_except;
199 
200  tvslice.tv_sec = 0;
201  tvslice.tv_usec = 1000;
202 
203  retcode = select(sock_max_fd + 1, &aread, &awrite, &aexcept, &tvslice);
204  }
205 
206  if (n_handles > 0) {
207  /* check handles */
208  DWORD wret;
209 
210  wret = MsgWaitForMultipleObjects(n_handles,
211  handles,
212  FALSE,
213  retcode > 0 ? 0 : 1,
214  QS_ALLEVENTS);
215 
216  if (wret == WAIT_TIMEOUT) {
217  /* set retcode to 0; this is the default.
218  * select() may have set it to something else,
219  * in which case we leave it alone, so this branch
220  * does nothing */
221  ;
222  } else if (wret == WAIT_FAILED) {
223  if (retcode == 0)
224  retcode = -1;
225  } else {
226  if (retcode < 0)
227  retcode = 0;
228  for (i = 0; i < n_handles; i++) {
229  if (WaitForSingleObject(handles[i], 0) == WAIT_OBJECT_0) {
230  if (SAFE_FD_ISSET(handle_slot_to_fd[i], rfds)) {
231  DWORD bytes;
232  intptr_t handle = (intptr_t) _get_osfhandle(
233  handle_slot_to_fd[i]);
234 
235  if (PeekNamedPipe((HANDLE)handle, NULL, 0,
236  NULL, &bytes, NULL)) {
237  /* check to see if gdb pipe has data available */
238  if (bytes) {
239  FD_SET(handle_slot_to_fd[i], &aread);
240  retcode++;
241  }
242  } else {
243  FD_SET(handle_slot_to_fd[i], &aread);
244  retcode++;
245  }
246  }
247  if (SAFE_FD_ISSET(handle_slot_to_fd[i], wfds)) {
248  FD_SET(handle_slot_to_fd[i], &awrite);
249  retcode++;
250  }
251  if (SAFE_FD_ISSET(handle_slot_to_fd[i], efds)) {
252  FD_SET(handle_slot_to_fd[i], &aexcept);
253  retcode++;
254  }
255  }
256  }
257  }
258  }
259  } while (retcode == 0 && (ms_total == INFINITE || GetTickCount() < limit));
260 
261  if (rfds)
262  *rfds = aread;
263  if (wfds)
264  *wfds = awrite;
265  if (efds)
266  *efds = aexcept;
267 
268  return retcode;
269 }
270 #endif
char * strndup(const char *s, size_t n)
Definition: replacements.c:115
void * clear_malloc(size_t size)
Definition: replacements.c:30
void * fill_malloc(size_t size)
Definition: replacements.c:38
size_t strnlen(const char *s, size_t maxlen)
Definition: replacements.c:107
int gettimeofday(struct timeval *tv, struct timezone *tz)
size_t size
Size of the control block search area.
Definition: rtt/rtt.c:30
long tv_sec
Definition: replacements.h:46
long tv_usec
Definition: replacements.h:47
#define NULL
Definition: usb.h:16
#define DWORD
Definition: x86_32_common.h:33