int interruptible_select (int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) { fd_set my_readfds; int fd; int res; if (readfds == NULL) { readfds = &my_readfds; FD_ZERO (&my_readfds); } fd = quit_serial_event_fd (); FD_SET (fd, readfds); if (n <= fd) n = fd + 1; do { res = gdb_select (n, readfds, writefds, exceptfds, timeout); } while (res == -1 && errno == EINTR); if (res == 1 && FD_ISSET (fd, readfds)) { errno = EINTR; return -1; } return res; }
static int hardwire_send_break (struct serial *scb) { #ifdef HAVE_TERMIOS return tcsendbreak (scb->fd, 0); #endif #ifdef HAVE_TERMIO return ioctl (scb->fd, TCSBRK, 0); #endif #ifdef HAVE_SGTTY { int status; struct timeval timeout; status = ioctl (scb->fd, TIOCSBRK, 0); /* Can't use usleep; it doesn't exist in BSD 4.2. */ /* Note that if this select() is interrupted by a signal it will not wait the full length of time. I think that is OK. */ timeout.tv_sec = 0; timeout.tv_usec = 250000; gdb_select (0, 0, 0, 0, &timeout); status = ioctl (scb->fd, TIOCCBRK, 0); return status; } #endif }
static int ser_base_wait_for (struct serial *scb, int timeout) { while (1) { int numfds; struct timeval tv; fd_set readfds, exceptfds; /* NOTE: Some OS's can scramble the READFDS when the select() call fails (ex the kernel with Red Hat 5.2). Initialize all arguments before each call. */ tv.tv_sec = timeout; tv.tv_usec = 0; FD_ZERO (&readfds); FD_ZERO (&exceptfds); FD_SET (scb->fd, &readfds); FD_SET (scb->fd, &exceptfds); if (timeout >= 0) numfds = gdb_select (scb->fd + 1, &readfds, 0, &exceptfds, &tv); else numfds = gdb_select (scb->fd + 1, &readfds, 0, &exceptfds, 0); if (numfds <= 0) { if (numfds == 0) return SERIAL_TIMEOUT; else if (errno == EINTR) continue; else return SERIAL_ERROR; /* Got an error from select or poll. */ } return 0; } }
int gdb_usleep (int usec) { struct timeval delay; int retval; delay.tv_sec = usec / 1000000; delay.tv_usec = usec % 1000000; retval = gdb_select (0, 0, 0, 0, &delay); if (retval < 0) retval = -1; else retval = 0; return retval; }
static void handle_sigio (int signo) { int numfds; fd_set readfds; signal (SIGIO, handle_sigio); FD_ZERO (&readfds); FD_SET (target_activity_fd, &readfds); numfds = gdb_select (target_activity_fd + 1, &readfds, NULL, NULL, NULL); if (numfds >= 0 && FD_ISSET (target_activity_fd, &readfds)) { #ifndef _WIN32 if ((*target_activity_function) ()) kill (PIDGET (inferior_ptid), SIGINT); #endif } }
/* Called by gdb_do_one_event to wait for new events on the monitored file descriptors. Queue file events as they are detected by the poll. If BLOCK and if there are no events, this function will block in the call to poll. Return -1 if there are no files descriptors to monitor, otherwise return 0. */ static int gdb_wait_for_event (int block) { file_handler *file_ptr; gdb_event *file_event_ptr; int num_found = 0; int i; /* Make sure all output is done before getting another event. */ gdb_flush (gdb_stdout); gdb_flush (gdb_stderr); if (gdb_notifier.num_fds == 0) return -1; if (use_poll) { #ifdef HAVE_POLL int timeout; if (block) timeout = gdb_notifier.timeout_valid ? gdb_notifier.poll_timeout : -1; else timeout = 0; num_found = poll (gdb_notifier.poll_fds, (unsigned long) gdb_notifier.num_fds, timeout); /* Don't print anything if we get out of poll because of a signal. */ if (num_found == -1 && errno != EINTR) perror_with_name (("poll")); #else internal_error (__FILE__, __LINE__, _("use_poll without HAVE_POLL")); #endif /* HAVE_POLL */ } else { struct timeval select_timeout; struct timeval *timeout_p; if (block) timeout_p = gdb_notifier.timeout_valid ? &gdb_notifier.select_timeout : NULL; else { memset (&select_timeout, 0, sizeof (select_timeout)); timeout_p = &select_timeout; } gdb_notifier.ready_masks[0] = gdb_notifier.check_masks[0]; gdb_notifier.ready_masks[1] = gdb_notifier.check_masks[1]; gdb_notifier.ready_masks[2] = gdb_notifier.check_masks[2]; num_found = gdb_select (gdb_notifier.num_fds, &gdb_notifier.ready_masks[0], &gdb_notifier.ready_masks[1], &gdb_notifier.ready_masks[2], timeout_p); /* Clear the masks after an error from select. */ if (num_found == -1) { FD_ZERO (&gdb_notifier.ready_masks[0]); FD_ZERO (&gdb_notifier.ready_masks[1]); FD_ZERO (&gdb_notifier.ready_masks[2]); /* Dont print anything if we got a signal, let gdb handle it. */ if (errno != EINTR) perror_with_name (("select")); } } /* Enqueue all detected file events. */ if (use_poll) { #ifdef HAVE_POLL for (i = 0; (i < gdb_notifier.num_fds) && (num_found > 0); i++) { if ((gdb_notifier.poll_fds + i)->revents) num_found--; else continue; for (file_ptr = gdb_notifier.first_file_handler; file_ptr != NULL; file_ptr = file_ptr->next_file) { if (file_ptr->fd == (gdb_notifier.poll_fds + i)->fd) break; } if (file_ptr) { /* Enqueue an event only if this is still a new event for this fd. */ if (file_ptr->ready_mask == 0) { file_event_ptr = create_file_event (file_ptr->fd); async_queue_event (file_event_ptr, TAIL); } file_ptr->ready_mask = (gdb_notifier.poll_fds + i)->revents; } } #else internal_error (__FILE__, __LINE__, _("use_poll without HAVE_POLL")); #endif /* HAVE_POLL */ } else { for (file_ptr = gdb_notifier.first_file_handler; (file_ptr != NULL) && (num_found > 0); file_ptr = file_ptr->next_file) { int mask = 0; if (FD_ISSET (file_ptr->fd, &gdb_notifier.ready_masks[0])) mask |= GDB_READABLE; if (FD_ISSET (file_ptr->fd, &gdb_notifier.ready_masks[1])) mask |= GDB_WRITABLE; if (FD_ISSET (file_ptr->fd, &gdb_notifier.ready_masks[2])) mask |= GDB_EXCEPTION; if (!mask) continue; else num_found--; /* Enqueue an event only if this is still a new event for this fd. */ if (file_ptr->ready_mask == 0) { file_event_ptr = create_file_event (file_ptr->fd); async_queue_event (file_event_ptr, TAIL); } file_ptr->ready_mask = mask; } } return 0; }
static int wait_for (struct serial *scb, int timeout) { #ifdef HAVE_SGTTY while (1) { struct timeval tv; fd_set readfds; int numfds; /* NOTE: Some OS's can scramble the READFDS when the select() call fails (ex the kernel with Red Hat 5.2). Initialize all arguments before each call. */ tv.tv_sec = timeout; tv.tv_usec = 0; FD_ZERO (&readfds); FD_SET (scb->fd, &readfds); if (timeout >= 0) numfds = gdb_select (scb->fd + 1, &readfds, 0, 0, &tv); else numfds = gdb_select (scb->fd + 1, &readfds, 0, 0, 0); if (numfds <= 0) if (numfds == 0) return SERIAL_TIMEOUT; else if (errno == EINTR) continue; else return SERIAL_ERROR; /* Got an error from select or poll */ return 0; } #endif /* HAVE_SGTTY */ #if defined HAVE_TERMIO || defined HAVE_TERMIOS if (timeout == scb->current_timeout) return 0; scb->current_timeout = timeout; { struct hardwire_ttystate state; if (get_tty_state (scb, &state)) fprintf_unfiltered (gdb_stderr, "get_tty_state failed: %s\n", safe_strerror (errno)); #ifdef HAVE_TERMIOS if (timeout < 0) { /* No timeout. */ state.termios.c_cc[VTIME] = 0; state.termios.c_cc[VMIN] = 1; } else { state.termios.c_cc[VMIN] = 0; state.termios.c_cc[VTIME] = timeout * 10; if (state.termios.c_cc[VTIME] != timeout * 10) { /* If c_cc is an 8-bit signed character, we can't go bigger than this. If it is always unsigned, we could use 25. */ scb->current_timeout = 12; state.termios.c_cc[VTIME] = scb->current_timeout * 10; scb->timeout_remaining = timeout - scb->current_timeout; } } #endif #ifdef HAVE_TERMIO if (timeout < 0) { /* No timeout. */ state.termio.c_cc[VTIME] = 0; state.termio.c_cc[VMIN] = 1; } else { state.termio.c_cc[VMIN] = 0; state.termio.c_cc[VTIME] = timeout * 10; if (state.termio.c_cc[VTIME] != timeout * 10) { /* If c_cc is an 8-bit signed character, we can't go bigger than this. If it is always unsigned, we could use 25. */ scb->current_timeout = 12; state.termio.c_cc[VTIME] = scb->current_timeout * 10; scb->timeout_remaining = timeout - scb->current_timeout; } } #endif if (set_tty_state (scb, &state)) fprintf_unfiltered (gdb_stderr, "set_tty_state failed: %s\n", safe_strerror (errno)); return 0; } #endif /* HAVE_TERMIO || HAVE_TERMIOS */ }