static void handle_error_fd (int error, gdb_client_data client_data) { serial *scb = (serial *) client_data; ser_base_read_error_fd (scb, 0); }
int generic_readchar (struct serial *scb, int timeout, int (do_readchar) (struct serial *scb, int timeout)) { int ch; if (scb->bufcnt > 0) { ch = *scb->bufp; scb->bufcnt--; scb->bufp++; } else if (scb->bufcnt < 0) { /* Some errors/eof are are sticky. */ ch = scb->bufcnt; } else { ch = do_readchar (scb, timeout); if (ch < 0) { switch ((enum serial_rc) ch) { case SERIAL_EOF: case SERIAL_ERROR: /* Make the error/eof stick. */ scb->bufcnt = ch; break; case SERIAL_TIMEOUT: scb->bufcnt = 0; break; } } } /* Read any error output we might have. */ ser_base_read_error_fd (scb, 1); reschedule (scb); return ch; }
static int do_ser_base_readchar (struct serial *scb, int timeout) { int status; int delta; /* We have to be able to keep the GUI alive here, so we break the original timeout into steps of 1 second, running the "keep the GUI alive" hook each time through the loop. Also, timeout = 0 means to poll, so we just set the delta to 0, so we will only go through the loop once. */ delta = (timeout == 0 ? 0 : 1); while (1) { /* N.B. The UI may destroy our world (for instance by calling remote_stop,) in which case we want to get out of here as quickly as possible. It is not safe to touch scb, since someone else might have freed it. The deprecated_ui_loop_hook signals that we should exit by returning 1. */ if (deprecated_ui_loop_hook) { if (deprecated_ui_loop_hook (0)) return SERIAL_TIMEOUT; } status = ser_base_wait_for (scb, delta); if (timeout > 0) timeout -= delta; /* If we got a character or an error back from wait_for, then we can break from the loop before the timeout is completed. */ if (status != SERIAL_TIMEOUT) break; /* If we have exhausted the original timeout, then generate a SERIAL_TIMEOUT, and pass it out of the loop. */ else if (timeout == 0) { status = SERIAL_TIMEOUT; break; } /* We also need to check and consume the stderr because it could come before the stdout for some stubs. If we just sit and wait for stdout, we would hit a deadlock for that case. */ ser_base_read_error_fd (scb, 0); } if (status < 0) return status; status = scb->ops->read_prim (scb, BUFSIZ); if (status <= 0) { if (status == 0) return SERIAL_EOF; else /* Got an error from read. */ return SERIAL_ERROR; } scb->bufcnt = status; scb->bufcnt--; scb->bufp = scb->buf; return *scb->bufp++; }