* config/tc-z8k.c (md_assemble): Fix buffer overrun in operand[]
[deliverable/binutils-gdb.git] / gdb / ser-base.c
CommitLineData
3eb25fda
MM
1/* Generic serial interface functions.
2
3 Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
4 2003, 2004, 2005 Free Software Foundation, Inc.
5
6 This file is part of GDB.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
22
23#include "defs.h"
24#include "serial.h"
25#include "ser-unix.h"
26#include "event-loop.h"
b4505029
MM
27#ifdef USE_WIN32API
28#include <winsock2.h>
29#endif
3eb25fda
MM
30
31static timer_handler_func push_event;
32static handler_func fd_event;
33
34/* Event handling for ASYNC serial code.
35
36 At any time the SERIAL device either: has an empty FIFO and is
37 waiting on a FD event; or has a non-empty FIFO/error condition and
38 is constantly scheduling timer events.
39
40 ASYNC only stops pestering its client when it is de-async'ed or it
41 is told to go away. */
42
43/* Value of scb->async_state: */
44enum {
45 /* >= 0 (TIMER_SCHEDULED) */
46 /* The ID of the currently scheduled timer event. This state is
47 rarely encountered. Timer events are one-off so as soon as the
48 event is delivered the state is shanged to NOTHING_SCHEDULED. */
49 FD_SCHEDULED = -1,
50 /* The fd_event() handler is scheduled. It is called when ever the
51 file descriptor becomes ready. */
52 NOTHING_SCHEDULED = -2
53 /* Either no task is scheduled (just going into ASYNC mode) or a
54 timer event has just gone off and the current state has been
55 forced into nothing scheduled. */
56};
57
58/* Identify and schedule the next ASYNC task based on scb->async_state
59 and scb->buf* (the input FIFO). A state machine is used to avoid
60 the need to make redundant calls into the event-loop - the next
61 scheduled task is only changed when needed. */
62
63void
64reschedule (struct serial *scb)
65{
66 if (serial_is_async_p (scb))
67 {
68 int next_state;
69 switch (scb->async_state)
70 {
71 case FD_SCHEDULED:
72 if (scb->bufcnt == 0)
73 next_state = FD_SCHEDULED;
74 else
75 {
76 delete_file_handler (scb->fd);
77 next_state = create_timer (0, push_event, scb);
78 }
79 break;
80 case NOTHING_SCHEDULED:
81 if (scb->bufcnt == 0)
82 {
83 add_file_handler (scb->fd, fd_event, scb);
84 next_state = FD_SCHEDULED;
85 }
86 else
87 {
88 next_state = create_timer (0, push_event, scb);
89 }
90 break;
91 default: /* TIMER SCHEDULED */
92 if (scb->bufcnt == 0)
93 {
94 delete_timer (scb->async_state);
95 add_file_handler (scb->fd, fd_event, scb);
96 next_state = FD_SCHEDULED;
97 }
98 else
99 next_state = scb->async_state;
100 break;
101 }
102 if (serial_debug_p (scb))
103 {
104 switch (next_state)
105 {
106 case FD_SCHEDULED:
107 if (scb->async_state != FD_SCHEDULED)
108 fprintf_unfiltered (gdb_stdlog, "[fd%d->fd-scheduled]\n",
109 scb->fd);
110 break;
111 default: /* TIMER SCHEDULED */
112 if (scb->async_state == FD_SCHEDULED)
113 fprintf_unfiltered (gdb_stdlog, "[fd%d->timer-scheduled]\n",
114 scb->fd);
115 break;
116 }
117 }
118 scb->async_state = next_state;
119 }
120}
121
122/* FD_EVENT: This is scheduled when the input FIFO is empty (and there
123 is no pending error). As soon as data arrives, it is read into the
124 input FIFO and the client notified. The client should then drain
125 the FIFO using readchar(). If the FIFO isn't immediatly emptied,
126 push_event() is used to nag the client until it is. */
127
128static void
129fd_event (int error, void *context)
130{
131 struct serial *scb = context;
132 if (error != 0)
133 {
134 scb->bufcnt = SERIAL_ERROR;
135 }
136 else if (scb->bufcnt == 0)
137 {
138 /* Prime the input FIFO. The readchar() function is used to
139 pull characters out of the buffer. See also
140 generic_readchar(). */
141 int nr;
b4505029 142 nr = scb->ops->read_prim (scb, BUFSIZ);
3eb25fda
MM
143 if (nr == 0)
144 {
145 scb->bufcnt = SERIAL_EOF;
146 }
147 else if (nr > 0)
148 {
149 scb->bufcnt = nr;
150 scb->bufp = scb->buf;
151 }
152 else
153 {
154 scb->bufcnt = SERIAL_ERROR;
155 }
156 }
157 scb->async_handler (scb, scb->async_context);
158 reschedule (scb);
159}
160
161/* PUSH_EVENT: The input FIFO is non-empty (or there is a pending
162 error). Nag the client until all the data has been read. In the
163 case of errors, the client will need to close or de-async the
164 device before naging stops. */
165
166static void
167push_event (void *context)
168{
169 struct serial *scb = context;
170 scb->async_state = NOTHING_SCHEDULED; /* Timers are one-off */
171 scb->async_handler (scb, scb->async_context);
172 /* re-schedule */
173 reschedule (scb);
174}
175
b4505029
MM
176/* Wait for input on scb, with timeout seconds. Returns 0 on success,
177 otherwise SERIAL_TIMEOUT or SERIAL_ERROR. */
178
179static int
180ser_base_wait_for (struct serial *scb, int timeout)
181{
182 while (1)
183 {
184 int numfds;
185 struct timeval tv;
186 fd_set readfds, exceptfds;
187
188 /* NOTE: Some OS's can scramble the READFDS when the select()
189 call fails (ex the kernel with Red Hat 5.2). Initialize all
190 arguments before each call. */
191
192 tv.tv_sec = timeout;
193 tv.tv_usec = 0;
194
195 FD_ZERO (&readfds);
196 FD_ZERO (&exceptfds);
197 FD_SET (scb->fd, &readfds);
198 FD_SET (scb->fd, &exceptfds);
199
200 if (timeout >= 0)
201 numfds = select (scb->fd + 1, &readfds, 0, &exceptfds, &tv);
202 else
203 numfds = select (scb->fd + 1, &readfds, 0, &exceptfds, 0);
204
205 if (numfds <= 0)
206 {
207 if (numfds == 0)
208 return SERIAL_TIMEOUT;
209 else if (errno == EINTR)
210 continue;
211 else
212 return SERIAL_ERROR; /* Got an error from select or poll */
213 }
214
215 return 0;
216 }
217}
218
219/* Read a character with user-specified timeout. TIMEOUT is number of seconds
220 to wait, or -1 to wait forever. Use timeout of 0 to effect a poll. Returns
221 char if successful. Returns -2 if timeout expired, EOF if line dropped
222 dead, or -3 for any other error (see errno in that case). */
223
224static int
225do_ser_base_readchar (struct serial *scb, int timeout)
226{
227 int status;
228 int delta;
229
230 /* We have to be able to keep the GUI alive here, so we break the
231 original timeout into steps of 1 second, running the "keep the
232 GUI alive" hook each time through the loop.
233
234 Also, timeout = 0 means to poll, so we just set the delta to 0,
235 so we will only go through the loop once. */
236
237 delta = (timeout == 0 ? 0 : 1);
238 while (1)
239 {
240 /* N.B. The UI may destroy our world (for instance by calling
241 remote_stop,) in which case we want to get out of here as
242 quickly as possible. It is not safe to touch scb, since
243 someone else might have freed it. The
244 deprecated_ui_loop_hook signals that we should exit by
245 returning 1. */
246
247 if (deprecated_ui_loop_hook)
248 {
249 if (deprecated_ui_loop_hook (0))
250 return SERIAL_TIMEOUT;
251 }
252
253 status = ser_base_wait_for (scb, delta);
254 if (timeout > 0)
255 timeout -= delta;
256
257 /* If we got a character or an error back from wait_for, then we can
258 break from the loop before the timeout is completed. */
259 if (status != SERIAL_TIMEOUT)
260 break;
261
262 /* If we have exhausted the original timeout, then generate
263 a SERIAL_TIMEOUT, and pass it out of the loop. */
264 else if (timeout == 0)
265 {
266 status = SERIAL_TIMEOUT;
267 break;
268 }
269 }
270
271 if (status < 0)
272 return status;
273
274 status = scb->ops->read_prim (scb, BUFSIZ);
275
276 if (status <= 0)
277 {
278 if (status == 0)
279 /* 0 chars means timeout. (We may need to distinguish between EOF
280 & timeouts someday.) */
281 return SERIAL_TIMEOUT;
282 else
283 /* Got an error from read. */
284 return SERIAL_ERROR;
285 }
286
287 scb->bufcnt = status;
288 scb->bufcnt--;
289 scb->bufp = scb->buf;
290 return *scb->bufp++;
291}
292
293/* Perform operations common to both old and new readchar. */
294
295/* Return the next character from the input FIFO. If the FIFO is
296 empty, call the SERIAL specific routine to try and read in more
297 characters.
298
299 Initially data from the input FIFO is returned (fd_event()
300 pre-reads the input into that FIFO. Once that has been emptied,
301 further data is obtained by polling the input FD using the device
302 specific readchar() function. Note: reschedule() is called after
303 every read. This is because there is no guarentee that the lower
304 level fd_event() poll_event() code (which also calls reschedule())
305 will be called. */
306
307int
308generic_readchar (struct serial *scb, int timeout,
309 int (do_readchar) (struct serial *scb, int timeout))
310{
311 int ch;
312 if (scb->bufcnt > 0)
313 {
314 ch = *scb->bufp;
315 scb->bufcnt--;
316 scb->bufp++;
317 }
318 else if (scb->bufcnt < 0)
319 {
320 /* Some errors/eof are are sticky. */
321 ch = scb->bufcnt;
322 }
323 else
324 {
325 ch = do_readchar (scb, timeout);
326 if (ch < 0)
327 {
328 switch ((enum serial_rc) ch)
329 {
330 case SERIAL_EOF:
331 case SERIAL_ERROR:
332 /* Make the error/eof stick. */
333 scb->bufcnt = ch;
334 break;
335 case SERIAL_TIMEOUT:
336 scb->bufcnt = 0;
337 break;
338 }
339 }
340 }
341 reschedule (scb);
342 return ch;
343}
344
345int
346ser_base_readchar (struct serial *scb, int timeout)
347{
348 return generic_readchar (scb, timeout, do_ser_base_readchar);
349}
350
3eb25fda 351int
dd5da072 352ser_base_write (struct serial *scb, const char *str, int len)
3eb25fda
MM
353{
354 int cc;
355
356 while (len > 0)
357 {
b4505029 358 cc = scb->ops->write_prim (scb, str, len);
3eb25fda
MM
359
360 if (cc < 0)
361 return 1;
362 len -= cc;
363 str += cc;
364 }
365 return 0;
366}
367
368int
dd5da072 369ser_base_flush_output (struct serial *scb)
3eb25fda
MM
370{
371 return 0;
372}
373
374int
dd5da072 375ser_base_flush_input (struct serial *scb)
3eb25fda
MM
376{
377 if (scb->bufcnt >= 0)
378 {
379 scb->bufcnt = 0;
380 scb->bufp = scb->buf;
381 return 0;
382 }
383 else
384 return SERIAL_ERROR;
385}
386
387int
dd5da072 388ser_base_send_break (struct serial *scb)
3eb25fda
MM
389{
390 return 0;
391}
392
393int
dd5da072 394ser_base_drain_output (struct serial *scb)
3eb25fda
MM
395{
396 return 0;
397}
398
399void
dd5da072 400ser_base_raw (struct serial *scb)
3eb25fda
MM
401{
402 return; /* Always in raw mode */
403}
404
405serial_ttystate
dd5da072 406ser_base_get_tty_state (struct serial *scb)
3eb25fda
MM
407{
408 /* allocate a dummy */
409 return (serial_ttystate) XMALLOC (int);
410}
411
412int
dd5da072 413ser_base_set_tty_state (struct serial *scb, serial_ttystate ttystate)
3eb25fda
MM
414{
415 return 0;
416}
417
418int
dd5da072
MM
419ser_base_noflush_set_tty_state (struct serial *scb,
420 serial_ttystate new_ttystate,
421 serial_ttystate old_ttystate)
3eb25fda
MM
422{
423 return 0;
424}
425
426void
dd5da072
MM
427ser_base_print_tty_state (struct serial *scb,
428 serial_ttystate ttystate,
429 struct ui_file *stream)
3eb25fda
MM
430{
431 /* Nothing to print. */
432 return;
433}
434
435int
dd5da072 436ser_base_setbaudrate (struct serial *scb, int rate)
3eb25fda
MM
437{
438 return 0; /* Never fails! */
439}
440
441int
dd5da072 442ser_base_setstopbits (struct serial *scb, int num)
3eb25fda
MM
443{
444 return 0; /* Never fails! */
445}
446
447/* Put the SERIAL device into/out-of ASYNC mode. */
448
449void
dd5da072 450ser_base_async (struct serial *scb,
3eb25fda
MM
451 int async_p)
452{
453 if (async_p)
454 {
455 /* Force a re-schedule. */
456 scb->async_state = NOTHING_SCHEDULED;
457 if (serial_debug_p (scb))
458 fprintf_unfiltered (gdb_stdlog, "[fd%d->asynchronous]\n",
459 scb->fd);
460 reschedule (scb);
461 }
462 else
463 {
464 if (serial_debug_p (scb))
465 fprintf_unfiltered (gdb_stdlog, "[fd%d->synchronous]\n",
466 scb->fd);
467 /* De-schedule whatever tasks are currently scheduled. */
468 switch (scb->async_state)
469 {
470 case FD_SCHEDULED:
471 delete_file_handler (scb->fd);
472 break;
473 case NOTHING_SCHEDULED:
474 break;
475 default: /* TIMER SCHEDULED */
476 delete_timer (scb->async_state);
477 break;
478 }
479 }
480}
This page took 0.046825 seconds and 4 git commands to generate.