15796c8dcSSimon Schubert /* Generic serial interface functions.
25796c8dcSSimon Schubert
3*ef5ccd6cSJohn Marino Copyright (C) 1992-2013 Free Software Foundation, Inc.
45796c8dcSSimon Schubert
55796c8dcSSimon Schubert This file is part of GDB.
65796c8dcSSimon Schubert
75796c8dcSSimon Schubert This program is free software; you can redistribute it and/or modify
85796c8dcSSimon Schubert it under the terms of the GNU General Public License as published by
95796c8dcSSimon Schubert the Free Software Foundation; either version 3 of the License, or
105796c8dcSSimon Schubert (at your option) any later version.
115796c8dcSSimon Schubert
125796c8dcSSimon Schubert This program is distributed in the hope that it will be useful,
135796c8dcSSimon Schubert but WITHOUT ANY WARRANTY; without even the implied warranty of
145796c8dcSSimon Schubert MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
155796c8dcSSimon Schubert GNU General Public License for more details.
165796c8dcSSimon Schubert
175796c8dcSSimon Schubert You should have received a copy of the GNU General Public License
185796c8dcSSimon Schubert along with this program. If not, see <http://www.gnu.org/licenses/>. */
195796c8dcSSimon Schubert
205796c8dcSSimon Schubert #include "defs.h"
215796c8dcSSimon Schubert #include "serial.h"
225796c8dcSSimon Schubert #include "ser-base.h"
235796c8dcSSimon Schubert #include "event-loop.h"
245796c8dcSSimon Schubert
255796c8dcSSimon Schubert #include "gdb_select.h"
265796c8dcSSimon Schubert #include "gdb_string.h"
27*ef5ccd6cSJohn Marino #include "gdb_assert.h"
285796c8dcSSimon Schubert #include <sys/time.h>
295796c8dcSSimon Schubert #ifdef USE_WIN32API
305796c8dcSSimon Schubert #include <winsock2.h>
315796c8dcSSimon Schubert #endif
325796c8dcSSimon Schubert
335796c8dcSSimon Schubert
345796c8dcSSimon Schubert static timer_handler_func push_event;
355796c8dcSSimon Schubert static handler_func fd_event;
365796c8dcSSimon Schubert
375796c8dcSSimon Schubert /* Event handling for ASYNC serial code.
385796c8dcSSimon Schubert
395796c8dcSSimon Schubert At any time the SERIAL device either: has an empty FIFO and is
405796c8dcSSimon Schubert waiting on a FD event; or has a non-empty FIFO/error condition and
415796c8dcSSimon Schubert is constantly scheduling timer events.
425796c8dcSSimon Schubert
435796c8dcSSimon Schubert ASYNC only stops pestering its client when it is de-async'ed or it
445796c8dcSSimon Schubert is told to go away. */
455796c8dcSSimon Schubert
465796c8dcSSimon Schubert /* Value of scb->async_state: */
475796c8dcSSimon Schubert enum {
485796c8dcSSimon Schubert /* >= 0 (TIMER_SCHEDULED) */
495796c8dcSSimon Schubert /* The ID of the currently scheduled timer event. This state is
505796c8dcSSimon Schubert rarely encountered. Timer events are one-off so as soon as the
515796c8dcSSimon Schubert event is delivered the state is shanged to NOTHING_SCHEDULED. */
525796c8dcSSimon Schubert FD_SCHEDULED = -1,
535796c8dcSSimon Schubert /* The fd_event() handler is scheduled. It is called when ever the
545796c8dcSSimon Schubert file descriptor becomes ready. */
555796c8dcSSimon Schubert NOTHING_SCHEDULED = -2
565796c8dcSSimon Schubert /* Either no task is scheduled (just going into ASYNC mode) or a
575796c8dcSSimon Schubert timer event has just gone off and the current state has been
585796c8dcSSimon Schubert forced into nothing scheduled. */
595796c8dcSSimon Schubert };
605796c8dcSSimon Schubert
615796c8dcSSimon Schubert /* Identify and schedule the next ASYNC task based on scb->async_state
625796c8dcSSimon Schubert and scb->buf* (the input FIFO). A state machine is used to avoid
635796c8dcSSimon Schubert the need to make redundant calls into the event-loop - the next
645796c8dcSSimon Schubert scheduled task is only changed when needed. */
655796c8dcSSimon Schubert
66cf7f2e2dSJohn Marino static void
reschedule(struct serial * scb)675796c8dcSSimon Schubert reschedule (struct serial *scb)
685796c8dcSSimon Schubert {
695796c8dcSSimon Schubert if (serial_is_async_p (scb))
705796c8dcSSimon Schubert {
715796c8dcSSimon Schubert int next_state;
72cf7f2e2dSJohn Marino
735796c8dcSSimon Schubert switch (scb->async_state)
745796c8dcSSimon Schubert {
755796c8dcSSimon Schubert case FD_SCHEDULED:
765796c8dcSSimon Schubert if (scb->bufcnt == 0)
775796c8dcSSimon Schubert next_state = FD_SCHEDULED;
785796c8dcSSimon Schubert else
795796c8dcSSimon Schubert {
805796c8dcSSimon Schubert delete_file_handler (scb->fd);
815796c8dcSSimon Schubert next_state = create_timer (0, push_event, scb);
825796c8dcSSimon Schubert }
835796c8dcSSimon Schubert break;
845796c8dcSSimon Schubert case NOTHING_SCHEDULED:
855796c8dcSSimon Schubert if (scb->bufcnt == 0)
865796c8dcSSimon Schubert {
875796c8dcSSimon Schubert add_file_handler (scb->fd, fd_event, scb);
885796c8dcSSimon Schubert next_state = FD_SCHEDULED;
895796c8dcSSimon Schubert }
905796c8dcSSimon Schubert else
915796c8dcSSimon Schubert {
925796c8dcSSimon Schubert next_state = create_timer (0, push_event, scb);
935796c8dcSSimon Schubert }
945796c8dcSSimon Schubert break;
955796c8dcSSimon Schubert default: /* TIMER SCHEDULED */
965796c8dcSSimon Schubert if (scb->bufcnt == 0)
975796c8dcSSimon Schubert {
985796c8dcSSimon Schubert delete_timer (scb->async_state);
995796c8dcSSimon Schubert add_file_handler (scb->fd, fd_event, scb);
1005796c8dcSSimon Schubert next_state = FD_SCHEDULED;
1015796c8dcSSimon Schubert }
1025796c8dcSSimon Schubert else
1035796c8dcSSimon Schubert next_state = scb->async_state;
1045796c8dcSSimon Schubert break;
1055796c8dcSSimon Schubert }
1065796c8dcSSimon Schubert if (serial_debug_p (scb))
1075796c8dcSSimon Schubert {
1085796c8dcSSimon Schubert switch (next_state)
1095796c8dcSSimon Schubert {
1105796c8dcSSimon Schubert case FD_SCHEDULED:
1115796c8dcSSimon Schubert if (scb->async_state != FD_SCHEDULED)
1125796c8dcSSimon Schubert fprintf_unfiltered (gdb_stdlog, "[fd%d->fd-scheduled]\n",
1135796c8dcSSimon Schubert scb->fd);
1145796c8dcSSimon Schubert break;
1155796c8dcSSimon Schubert default: /* TIMER SCHEDULED */
1165796c8dcSSimon Schubert if (scb->async_state == FD_SCHEDULED)
1175796c8dcSSimon Schubert fprintf_unfiltered (gdb_stdlog, "[fd%d->timer-scheduled]\n",
1185796c8dcSSimon Schubert scb->fd);
1195796c8dcSSimon Schubert break;
1205796c8dcSSimon Schubert }
1215796c8dcSSimon Schubert }
1225796c8dcSSimon Schubert scb->async_state = next_state;
1235796c8dcSSimon Schubert }
1245796c8dcSSimon Schubert }
1255796c8dcSSimon Schubert
126*ef5ccd6cSJohn Marino /* Run the SCB's async handle, and reschedule, if the handler doesn't
127*ef5ccd6cSJohn Marino close SCB. */
128*ef5ccd6cSJohn Marino
129*ef5ccd6cSJohn Marino static void
run_async_handler_and_reschedule(struct serial * scb)130*ef5ccd6cSJohn Marino run_async_handler_and_reschedule (struct serial *scb)
131*ef5ccd6cSJohn Marino {
132*ef5ccd6cSJohn Marino int is_open;
133*ef5ccd6cSJohn Marino
134*ef5ccd6cSJohn Marino /* Take a reference, so a serial_close call within the handler
135*ef5ccd6cSJohn Marino doesn't make SCB a dangling pointer. */
136*ef5ccd6cSJohn Marino serial_ref (scb);
137*ef5ccd6cSJohn Marino
138*ef5ccd6cSJohn Marino /* Run the handler. */
139*ef5ccd6cSJohn Marino scb->async_handler (scb, scb->async_context);
140*ef5ccd6cSJohn Marino
141*ef5ccd6cSJohn Marino is_open = serial_is_open (scb);
142*ef5ccd6cSJohn Marino serial_unref (scb);
143*ef5ccd6cSJohn Marino
144*ef5ccd6cSJohn Marino /* Get ready for more, if not already closed. */
145*ef5ccd6cSJohn Marino if (is_open)
146*ef5ccd6cSJohn Marino reschedule (scb);
147*ef5ccd6cSJohn Marino }
148*ef5ccd6cSJohn Marino
1495796c8dcSSimon Schubert /* FD_EVENT: This is scheduled when the input FIFO is empty (and there
1505796c8dcSSimon Schubert is no pending error). As soon as data arrives, it is read into the
1515796c8dcSSimon Schubert input FIFO and the client notified. The client should then drain
1525796c8dcSSimon Schubert the FIFO using readchar(). If the FIFO isn't immediatly emptied,
1535796c8dcSSimon Schubert push_event() is used to nag the client until it is. */
1545796c8dcSSimon Schubert
1555796c8dcSSimon Schubert static void
fd_event(int error,void * context)1565796c8dcSSimon Schubert fd_event (int error, void *context)
1575796c8dcSSimon Schubert {
1585796c8dcSSimon Schubert struct serial *scb = context;
1595796c8dcSSimon Schubert if (error != 0)
1605796c8dcSSimon Schubert {
1615796c8dcSSimon Schubert scb->bufcnt = SERIAL_ERROR;
1625796c8dcSSimon Schubert }
1635796c8dcSSimon Schubert else if (scb->bufcnt == 0)
1645796c8dcSSimon Schubert {
1655796c8dcSSimon Schubert /* Prime the input FIFO. The readchar() function is used to
1665796c8dcSSimon Schubert pull characters out of the buffer. See also
1675796c8dcSSimon Schubert generic_readchar(). */
1685796c8dcSSimon Schubert int nr;
1695796c8dcSSimon Schubert nr = scb->ops->read_prim (scb, BUFSIZ);
1705796c8dcSSimon Schubert if (nr == 0)
1715796c8dcSSimon Schubert {
1725796c8dcSSimon Schubert scb->bufcnt = SERIAL_EOF;
1735796c8dcSSimon Schubert }
1745796c8dcSSimon Schubert else if (nr > 0)
1755796c8dcSSimon Schubert {
1765796c8dcSSimon Schubert scb->bufcnt = nr;
1775796c8dcSSimon Schubert scb->bufp = scb->buf;
1785796c8dcSSimon Schubert }
1795796c8dcSSimon Schubert else
1805796c8dcSSimon Schubert {
1815796c8dcSSimon Schubert scb->bufcnt = SERIAL_ERROR;
1825796c8dcSSimon Schubert }
1835796c8dcSSimon Schubert }
184*ef5ccd6cSJohn Marino run_async_handler_and_reschedule (scb);
1855796c8dcSSimon Schubert }
1865796c8dcSSimon Schubert
1875796c8dcSSimon Schubert /* PUSH_EVENT: The input FIFO is non-empty (or there is a pending
1885796c8dcSSimon Schubert error). Nag the client until all the data has been read. In the
1895796c8dcSSimon Schubert case of errors, the client will need to close or de-async the
1905796c8dcSSimon Schubert device before naging stops. */
1915796c8dcSSimon Schubert
1925796c8dcSSimon Schubert static void
push_event(void * context)1935796c8dcSSimon Schubert push_event (void *context)
1945796c8dcSSimon Schubert {
1955796c8dcSSimon Schubert struct serial *scb = context;
196cf7f2e2dSJohn Marino
1975796c8dcSSimon Schubert scb->async_state = NOTHING_SCHEDULED; /* Timers are one-off */
198*ef5ccd6cSJohn Marino run_async_handler_and_reschedule (scb);
1995796c8dcSSimon Schubert }
2005796c8dcSSimon Schubert
2015796c8dcSSimon Schubert /* Wait for input on scb, with timeout seconds. Returns 0 on success,
2025796c8dcSSimon Schubert otherwise SERIAL_TIMEOUT or SERIAL_ERROR. */
2035796c8dcSSimon Schubert
2045796c8dcSSimon Schubert static int
ser_base_wait_for(struct serial * scb,int timeout)2055796c8dcSSimon Schubert ser_base_wait_for (struct serial *scb, int timeout)
2065796c8dcSSimon Schubert {
2075796c8dcSSimon Schubert while (1)
2085796c8dcSSimon Schubert {
2095796c8dcSSimon Schubert int numfds;
2105796c8dcSSimon Schubert struct timeval tv;
2115796c8dcSSimon Schubert fd_set readfds, exceptfds;
2125796c8dcSSimon Schubert
2135796c8dcSSimon Schubert /* NOTE: Some OS's can scramble the READFDS when the select()
2145796c8dcSSimon Schubert call fails (ex the kernel with Red Hat 5.2). Initialize all
2155796c8dcSSimon Schubert arguments before each call. */
2165796c8dcSSimon Schubert
2175796c8dcSSimon Schubert tv.tv_sec = timeout;
2185796c8dcSSimon Schubert tv.tv_usec = 0;
2195796c8dcSSimon Schubert
2205796c8dcSSimon Schubert FD_ZERO (&readfds);
2215796c8dcSSimon Schubert FD_ZERO (&exceptfds);
2225796c8dcSSimon Schubert FD_SET (scb->fd, &readfds);
2235796c8dcSSimon Schubert FD_SET (scb->fd, &exceptfds);
2245796c8dcSSimon Schubert
2255796c8dcSSimon Schubert if (timeout >= 0)
2265796c8dcSSimon Schubert numfds = gdb_select (scb->fd + 1, &readfds, 0, &exceptfds, &tv);
2275796c8dcSSimon Schubert else
2285796c8dcSSimon Schubert numfds = gdb_select (scb->fd + 1, &readfds, 0, &exceptfds, 0);
2295796c8dcSSimon Schubert
2305796c8dcSSimon Schubert if (numfds <= 0)
2315796c8dcSSimon Schubert {
2325796c8dcSSimon Schubert if (numfds == 0)
2335796c8dcSSimon Schubert return SERIAL_TIMEOUT;
2345796c8dcSSimon Schubert else if (errno == EINTR)
2355796c8dcSSimon Schubert continue;
2365796c8dcSSimon Schubert else
237c50c785cSJohn Marino return SERIAL_ERROR; /* Got an error from select or
238c50c785cSJohn Marino poll. */
2395796c8dcSSimon Schubert }
2405796c8dcSSimon Schubert
2415796c8dcSSimon Schubert return 0;
2425796c8dcSSimon Schubert }
2435796c8dcSSimon Schubert }
2445796c8dcSSimon Schubert
245*ef5ccd6cSJohn Marino /* Read any error output we might have. */
246*ef5ccd6cSJohn Marino
247*ef5ccd6cSJohn Marino static void
ser_base_read_error_fd(struct serial * scb,int close_fd)248*ef5ccd6cSJohn Marino ser_base_read_error_fd (struct serial *scb, int close_fd)
249*ef5ccd6cSJohn Marino {
250*ef5ccd6cSJohn Marino if (scb->error_fd != -1)
251*ef5ccd6cSJohn Marino {
252*ef5ccd6cSJohn Marino ssize_t s;
253*ef5ccd6cSJohn Marino char buf[GDB_MI_MSG_WIDTH + 1];
254*ef5ccd6cSJohn Marino
255*ef5ccd6cSJohn Marino for (;;)
256*ef5ccd6cSJohn Marino {
257*ef5ccd6cSJohn Marino char *current;
258*ef5ccd6cSJohn Marino char *newline;
259*ef5ccd6cSJohn Marino int to_read = GDB_MI_MSG_WIDTH;
260*ef5ccd6cSJohn Marino int num_bytes = -1;
261*ef5ccd6cSJohn Marino
262*ef5ccd6cSJohn Marino if (scb->ops->avail)
263*ef5ccd6cSJohn Marino num_bytes = (scb->ops->avail)(scb, scb->error_fd);
264*ef5ccd6cSJohn Marino
265*ef5ccd6cSJohn Marino if (num_bytes != -1)
266*ef5ccd6cSJohn Marino to_read = (num_bytes < to_read) ? num_bytes : to_read;
267*ef5ccd6cSJohn Marino
268*ef5ccd6cSJohn Marino if (to_read == 0)
269*ef5ccd6cSJohn Marino break;
270*ef5ccd6cSJohn Marino
271*ef5ccd6cSJohn Marino s = read (scb->error_fd, &buf, to_read);
272*ef5ccd6cSJohn Marino if ((s == -1) || (s == 0 && !close_fd))
273*ef5ccd6cSJohn Marino break;
274*ef5ccd6cSJohn Marino
275*ef5ccd6cSJohn Marino if (s == 0 && close_fd)
276*ef5ccd6cSJohn Marino {
277*ef5ccd6cSJohn Marino /* End of file. */
278*ef5ccd6cSJohn Marino close (scb->error_fd);
279*ef5ccd6cSJohn Marino scb->error_fd = -1;
280*ef5ccd6cSJohn Marino break;
281*ef5ccd6cSJohn Marino }
282*ef5ccd6cSJohn Marino
283*ef5ccd6cSJohn Marino /* In theory, embedded newlines are not a problem.
284*ef5ccd6cSJohn Marino But for MI, we want each output line to have just
285*ef5ccd6cSJohn Marino one newline for legibility. So output things
286*ef5ccd6cSJohn Marino in newline chunks. */
287*ef5ccd6cSJohn Marino gdb_assert (s > 0 && s <= GDB_MI_MSG_WIDTH);
288*ef5ccd6cSJohn Marino buf[s] = '\0';
289*ef5ccd6cSJohn Marino current = buf;
290*ef5ccd6cSJohn Marino while ((newline = strstr (current, "\n")) != NULL)
291*ef5ccd6cSJohn Marino {
292*ef5ccd6cSJohn Marino *newline = '\0';
293*ef5ccd6cSJohn Marino fputs_unfiltered (current, gdb_stderr);
294*ef5ccd6cSJohn Marino fputs_unfiltered ("\n", gdb_stderr);
295*ef5ccd6cSJohn Marino current = newline + 1;
296*ef5ccd6cSJohn Marino }
297*ef5ccd6cSJohn Marino
298*ef5ccd6cSJohn Marino fputs_unfiltered (current, gdb_stderr);
299*ef5ccd6cSJohn Marino }
300*ef5ccd6cSJohn Marino }
301*ef5ccd6cSJohn Marino }
302*ef5ccd6cSJohn Marino
3035796c8dcSSimon Schubert /* Read a character with user-specified timeout. TIMEOUT is number of seconds
3045796c8dcSSimon Schubert to wait, or -1 to wait forever. Use timeout of 0 to effect a poll. Returns
3055796c8dcSSimon Schubert char if successful. Returns -2 if timeout expired, EOF if line dropped
3065796c8dcSSimon Schubert dead, or -3 for any other error (see errno in that case). */
3075796c8dcSSimon Schubert
3085796c8dcSSimon Schubert static int
do_ser_base_readchar(struct serial * scb,int timeout)3095796c8dcSSimon Schubert do_ser_base_readchar (struct serial *scb, int timeout)
3105796c8dcSSimon Schubert {
3115796c8dcSSimon Schubert int status;
3125796c8dcSSimon Schubert int delta;
3135796c8dcSSimon Schubert
3145796c8dcSSimon Schubert /* We have to be able to keep the GUI alive here, so we break the
3155796c8dcSSimon Schubert original timeout into steps of 1 second, running the "keep the
3165796c8dcSSimon Schubert GUI alive" hook each time through the loop.
3175796c8dcSSimon Schubert
3185796c8dcSSimon Schubert Also, timeout = 0 means to poll, so we just set the delta to 0,
3195796c8dcSSimon Schubert so we will only go through the loop once. */
3205796c8dcSSimon Schubert
3215796c8dcSSimon Schubert delta = (timeout == 0 ? 0 : 1);
3225796c8dcSSimon Schubert while (1)
3235796c8dcSSimon Schubert {
3245796c8dcSSimon Schubert /* N.B. The UI may destroy our world (for instance by calling
3255796c8dcSSimon Schubert remote_stop,) in which case we want to get out of here as
3265796c8dcSSimon Schubert quickly as possible. It is not safe to touch scb, since
3275796c8dcSSimon Schubert someone else might have freed it. The
3285796c8dcSSimon Schubert deprecated_ui_loop_hook signals that we should exit by
3295796c8dcSSimon Schubert returning 1. */
3305796c8dcSSimon Schubert
3315796c8dcSSimon Schubert if (deprecated_ui_loop_hook)
3325796c8dcSSimon Schubert {
3335796c8dcSSimon Schubert if (deprecated_ui_loop_hook (0))
3345796c8dcSSimon Schubert return SERIAL_TIMEOUT;
3355796c8dcSSimon Schubert }
3365796c8dcSSimon Schubert
3375796c8dcSSimon Schubert status = ser_base_wait_for (scb, delta);
3385796c8dcSSimon Schubert if (timeout > 0)
3395796c8dcSSimon Schubert timeout -= delta;
3405796c8dcSSimon Schubert
3415796c8dcSSimon Schubert /* If we got a character or an error back from wait_for, then we can
3425796c8dcSSimon Schubert break from the loop before the timeout is completed. */
3435796c8dcSSimon Schubert if (status != SERIAL_TIMEOUT)
3445796c8dcSSimon Schubert break;
3455796c8dcSSimon Schubert
3465796c8dcSSimon Schubert /* If we have exhausted the original timeout, then generate
3475796c8dcSSimon Schubert a SERIAL_TIMEOUT, and pass it out of the loop. */
3485796c8dcSSimon Schubert else if (timeout == 0)
3495796c8dcSSimon Schubert {
3505796c8dcSSimon Schubert status = SERIAL_TIMEOUT;
3515796c8dcSSimon Schubert break;
3525796c8dcSSimon Schubert }
353*ef5ccd6cSJohn Marino
354*ef5ccd6cSJohn Marino /* We also need to check and consume the stderr because it could
355*ef5ccd6cSJohn Marino come before the stdout for some stubs. If we just sit and wait
356*ef5ccd6cSJohn Marino for stdout, we would hit a deadlock for that case. */
357*ef5ccd6cSJohn Marino ser_base_read_error_fd (scb, 0);
3585796c8dcSSimon Schubert }
3595796c8dcSSimon Schubert
3605796c8dcSSimon Schubert if (status < 0)
3615796c8dcSSimon Schubert return status;
3625796c8dcSSimon Schubert
3635796c8dcSSimon Schubert status = scb->ops->read_prim (scb, BUFSIZ);
3645796c8dcSSimon Schubert
3655796c8dcSSimon Schubert if (status <= 0)
3665796c8dcSSimon Schubert {
3675796c8dcSSimon Schubert if (status == 0)
3685796c8dcSSimon Schubert return SERIAL_EOF;
3695796c8dcSSimon Schubert else
3705796c8dcSSimon Schubert /* Got an error from read. */
3715796c8dcSSimon Schubert return SERIAL_ERROR;
3725796c8dcSSimon Schubert }
3735796c8dcSSimon Schubert
3745796c8dcSSimon Schubert scb->bufcnt = status;
3755796c8dcSSimon Schubert scb->bufcnt--;
3765796c8dcSSimon Schubert scb->bufp = scb->buf;
3775796c8dcSSimon Schubert return *scb->bufp++;
3785796c8dcSSimon Schubert }
3795796c8dcSSimon Schubert
3805796c8dcSSimon Schubert /* Perform operations common to both old and new readchar. */
3815796c8dcSSimon Schubert
3825796c8dcSSimon Schubert /* Return the next character from the input FIFO. If the FIFO is
3835796c8dcSSimon Schubert empty, call the SERIAL specific routine to try and read in more
3845796c8dcSSimon Schubert characters.
3855796c8dcSSimon Schubert
3865796c8dcSSimon Schubert Initially data from the input FIFO is returned (fd_event()
3875796c8dcSSimon Schubert pre-reads the input into that FIFO. Once that has been emptied,
3885796c8dcSSimon Schubert further data is obtained by polling the input FD using the device
3895796c8dcSSimon Schubert specific readchar() function. Note: reschedule() is called after
3905796c8dcSSimon Schubert every read. This is because there is no guarentee that the lower
3915796c8dcSSimon Schubert level fd_event() poll_event() code (which also calls reschedule())
3925796c8dcSSimon Schubert will be called. */
3935796c8dcSSimon Schubert
3945796c8dcSSimon Schubert int
generic_readchar(struct serial * scb,int timeout,int (do_readchar)(struct serial * scb,int timeout))3955796c8dcSSimon Schubert generic_readchar (struct serial *scb, int timeout,
3965796c8dcSSimon Schubert int (do_readchar) (struct serial *scb, int timeout))
3975796c8dcSSimon Schubert {
3985796c8dcSSimon Schubert int ch;
3995796c8dcSSimon Schubert if (scb->bufcnt > 0)
4005796c8dcSSimon Schubert {
4015796c8dcSSimon Schubert ch = *scb->bufp;
4025796c8dcSSimon Schubert scb->bufcnt--;
4035796c8dcSSimon Schubert scb->bufp++;
4045796c8dcSSimon Schubert }
4055796c8dcSSimon Schubert else if (scb->bufcnt < 0)
4065796c8dcSSimon Schubert {
4075796c8dcSSimon Schubert /* Some errors/eof are are sticky. */
4085796c8dcSSimon Schubert ch = scb->bufcnt;
4095796c8dcSSimon Schubert }
4105796c8dcSSimon Schubert else
4115796c8dcSSimon Schubert {
4125796c8dcSSimon Schubert ch = do_readchar (scb, timeout);
4135796c8dcSSimon Schubert if (ch < 0)
4145796c8dcSSimon Schubert {
4155796c8dcSSimon Schubert switch ((enum serial_rc) ch)
4165796c8dcSSimon Schubert {
4175796c8dcSSimon Schubert case SERIAL_EOF:
4185796c8dcSSimon Schubert case SERIAL_ERROR:
4195796c8dcSSimon Schubert /* Make the error/eof stick. */
4205796c8dcSSimon Schubert scb->bufcnt = ch;
4215796c8dcSSimon Schubert break;
4225796c8dcSSimon Schubert case SERIAL_TIMEOUT:
4235796c8dcSSimon Schubert scb->bufcnt = 0;
4245796c8dcSSimon Schubert break;
4255796c8dcSSimon Schubert }
4265796c8dcSSimon Schubert }
4275796c8dcSSimon Schubert }
428*ef5ccd6cSJohn Marino
4295796c8dcSSimon Schubert /* Read any error output we might have. */
430*ef5ccd6cSJohn Marino ser_base_read_error_fd (scb, 1);
4315796c8dcSSimon Schubert
4325796c8dcSSimon Schubert reschedule (scb);
4335796c8dcSSimon Schubert return ch;
4345796c8dcSSimon Schubert }
4355796c8dcSSimon Schubert
4365796c8dcSSimon Schubert int
ser_base_readchar(struct serial * scb,int timeout)4375796c8dcSSimon Schubert ser_base_readchar (struct serial *scb, int timeout)
4385796c8dcSSimon Schubert {
4395796c8dcSSimon Schubert return generic_readchar (scb, timeout, do_ser_base_readchar);
4405796c8dcSSimon Schubert }
4415796c8dcSSimon Schubert
4425796c8dcSSimon Schubert int
ser_base_write(struct serial * scb,const char * str,int len)4435796c8dcSSimon Schubert ser_base_write (struct serial *scb, const char *str, int len)
4445796c8dcSSimon Schubert {
4455796c8dcSSimon Schubert int cc;
4465796c8dcSSimon Schubert
4475796c8dcSSimon Schubert while (len > 0)
4485796c8dcSSimon Schubert {
4495796c8dcSSimon Schubert cc = scb->ops->write_prim (scb, str, len);
4505796c8dcSSimon Schubert
4515796c8dcSSimon Schubert if (cc < 0)
4525796c8dcSSimon Schubert return 1;
4535796c8dcSSimon Schubert len -= cc;
4545796c8dcSSimon Schubert str += cc;
4555796c8dcSSimon Schubert }
4565796c8dcSSimon Schubert return 0;
4575796c8dcSSimon Schubert }
4585796c8dcSSimon Schubert
4595796c8dcSSimon Schubert int
ser_base_flush_output(struct serial * scb)4605796c8dcSSimon Schubert ser_base_flush_output (struct serial *scb)
4615796c8dcSSimon Schubert {
4625796c8dcSSimon Schubert return 0;
4635796c8dcSSimon Schubert }
4645796c8dcSSimon Schubert
4655796c8dcSSimon Schubert int
ser_base_flush_input(struct serial * scb)4665796c8dcSSimon Schubert ser_base_flush_input (struct serial *scb)
4675796c8dcSSimon Schubert {
4685796c8dcSSimon Schubert if (scb->bufcnt >= 0)
4695796c8dcSSimon Schubert {
4705796c8dcSSimon Schubert scb->bufcnt = 0;
4715796c8dcSSimon Schubert scb->bufp = scb->buf;
4725796c8dcSSimon Schubert return 0;
4735796c8dcSSimon Schubert }
4745796c8dcSSimon Schubert else
4755796c8dcSSimon Schubert return SERIAL_ERROR;
4765796c8dcSSimon Schubert }
4775796c8dcSSimon Schubert
4785796c8dcSSimon Schubert int
ser_base_send_break(struct serial * scb)4795796c8dcSSimon Schubert ser_base_send_break (struct serial *scb)
4805796c8dcSSimon Schubert {
4815796c8dcSSimon Schubert return 0;
4825796c8dcSSimon Schubert }
4835796c8dcSSimon Schubert
4845796c8dcSSimon Schubert int
ser_base_drain_output(struct serial * scb)4855796c8dcSSimon Schubert ser_base_drain_output (struct serial *scb)
4865796c8dcSSimon Schubert {
4875796c8dcSSimon Schubert return 0;
4885796c8dcSSimon Schubert }
4895796c8dcSSimon Schubert
4905796c8dcSSimon Schubert void
ser_base_raw(struct serial * scb)4915796c8dcSSimon Schubert ser_base_raw (struct serial *scb)
4925796c8dcSSimon Schubert {
493c50c785cSJohn Marino return; /* Always in raw mode. */
4945796c8dcSSimon Schubert }
4955796c8dcSSimon Schubert
4965796c8dcSSimon Schubert serial_ttystate
ser_base_get_tty_state(struct serial * scb)4975796c8dcSSimon Schubert ser_base_get_tty_state (struct serial *scb)
4985796c8dcSSimon Schubert {
499c50c785cSJohn Marino /* Allocate a dummy. */
500c50c785cSJohn Marino return (serial_ttystate) XMALLOC (int);
501c50c785cSJohn Marino }
502c50c785cSJohn Marino
503c50c785cSJohn Marino serial_ttystate
ser_base_copy_tty_state(struct serial * scb,serial_ttystate ttystate)504c50c785cSJohn Marino ser_base_copy_tty_state (struct serial *scb, serial_ttystate ttystate)
505c50c785cSJohn Marino {
506c50c785cSJohn Marino /* Allocate another dummy. */
5075796c8dcSSimon Schubert return (serial_ttystate) XMALLOC (int);
5085796c8dcSSimon Schubert }
5095796c8dcSSimon Schubert
5105796c8dcSSimon Schubert int
ser_base_set_tty_state(struct serial * scb,serial_ttystate ttystate)5115796c8dcSSimon Schubert ser_base_set_tty_state (struct serial *scb, serial_ttystate ttystate)
5125796c8dcSSimon Schubert {
5135796c8dcSSimon Schubert return 0;
5145796c8dcSSimon Schubert }
5155796c8dcSSimon Schubert
5165796c8dcSSimon Schubert int
ser_base_noflush_set_tty_state(struct serial * scb,serial_ttystate new_ttystate,serial_ttystate old_ttystate)5175796c8dcSSimon Schubert ser_base_noflush_set_tty_state (struct serial *scb,
5185796c8dcSSimon Schubert serial_ttystate new_ttystate,
5195796c8dcSSimon Schubert serial_ttystate old_ttystate)
5205796c8dcSSimon Schubert {
5215796c8dcSSimon Schubert return 0;
5225796c8dcSSimon Schubert }
5235796c8dcSSimon Schubert
5245796c8dcSSimon Schubert void
ser_base_print_tty_state(struct serial * scb,serial_ttystate ttystate,struct ui_file * stream)5255796c8dcSSimon Schubert ser_base_print_tty_state (struct serial *scb,
5265796c8dcSSimon Schubert serial_ttystate ttystate,
5275796c8dcSSimon Schubert struct ui_file *stream)
5285796c8dcSSimon Schubert {
5295796c8dcSSimon Schubert /* Nothing to print. */
5305796c8dcSSimon Schubert return;
5315796c8dcSSimon Schubert }
5325796c8dcSSimon Schubert
5335796c8dcSSimon Schubert int
ser_base_setbaudrate(struct serial * scb,int rate)5345796c8dcSSimon Schubert ser_base_setbaudrate (struct serial *scb, int rate)
5355796c8dcSSimon Schubert {
5365796c8dcSSimon Schubert return 0; /* Never fails! */
5375796c8dcSSimon Schubert }
5385796c8dcSSimon Schubert
5395796c8dcSSimon Schubert int
ser_base_setstopbits(struct serial * scb,int num)5405796c8dcSSimon Schubert ser_base_setstopbits (struct serial *scb, int num)
5415796c8dcSSimon Schubert {
5425796c8dcSSimon Schubert return 0; /* Never fails! */
5435796c8dcSSimon Schubert }
5445796c8dcSSimon Schubert
5455796c8dcSSimon Schubert /* Put the SERIAL device into/out-of ASYNC mode. */
5465796c8dcSSimon Schubert
5475796c8dcSSimon Schubert void
ser_base_async(struct serial * scb,int async_p)5485796c8dcSSimon Schubert ser_base_async (struct serial *scb,
5495796c8dcSSimon Schubert int async_p)
5505796c8dcSSimon Schubert {
5515796c8dcSSimon Schubert if (async_p)
5525796c8dcSSimon Schubert {
5535796c8dcSSimon Schubert /* Force a re-schedule. */
5545796c8dcSSimon Schubert scb->async_state = NOTHING_SCHEDULED;
5555796c8dcSSimon Schubert if (serial_debug_p (scb))
5565796c8dcSSimon Schubert fprintf_unfiltered (gdb_stdlog, "[fd%d->asynchronous]\n",
5575796c8dcSSimon Schubert scb->fd);
5585796c8dcSSimon Schubert reschedule (scb);
5595796c8dcSSimon Schubert }
5605796c8dcSSimon Schubert else
5615796c8dcSSimon Schubert {
5625796c8dcSSimon Schubert if (serial_debug_p (scb))
5635796c8dcSSimon Schubert fprintf_unfiltered (gdb_stdlog, "[fd%d->synchronous]\n",
5645796c8dcSSimon Schubert scb->fd);
5655796c8dcSSimon Schubert /* De-schedule whatever tasks are currently scheduled. */
5665796c8dcSSimon Schubert switch (scb->async_state)
5675796c8dcSSimon Schubert {
5685796c8dcSSimon Schubert case FD_SCHEDULED:
5695796c8dcSSimon Schubert delete_file_handler (scb->fd);
5705796c8dcSSimon Schubert break;
5715796c8dcSSimon Schubert case NOTHING_SCHEDULED:
5725796c8dcSSimon Schubert break;
5735796c8dcSSimon Schubert default: /* TIMER SCHEDULED */
5745796c8dcSSimon Schubert delete_timer (scb->async_state);
5755796c8dcSSimon Schubert break;
5765796c8dcSSimon Schubert }
5775796c8dcSSimon Schubert }
5785796c8dcSSimon Schubert }
579