Пример #1
0
static void
reschedule (struct serial *scb)
{
  if (serial_is_async_p (scb))
    {
      int next_state;

      switch (scb->async_state)
	{
	case FD_SCHEDULED:
	  if (scb->bufcnt == 0)
	    next_state = FD_SCHEDULED;
	  else
	    {
	      delete_file_handler (scb->fd);
	      next_state = create_timer (0, push_event, scb);
	    }
	  break;
	case NOTHING_SCHEDULED:
	  if (scb->bufcnt == 0)
	    {
	      add_file_handler (scb->fd, fd_event, scb);
	      next_state = FD_SCHEDULED;
	    }
	  else
	    {
	      next_state = create_timer (0, push_event, scb);
	    }
	  break;
	default: /* TIMER SCHEDULED */
	  if (scb->bufcnt == 0)
	    {
	      delete_timer (scb->async_state);
	      add_file_handler (scb->fd, fd_event, scb);
	      next_state = FD_SCHEDULED;
	    }
	  else
	    next_state = scb->async_state;
	  break;
	}
      if (serial_debug_p (scb))
	{
	  switch (next_state)
	    {
	    case FD_SCHEDULED:
	      if (scb->async_state != FD_SCHEDULED)
		fprintf_unfiltered (gdb_stdlog, "[fd%d->fd-scheduled]\n",
				    scb->fd);
	      break;
	    default: /* TIMER SCHEDULED */
	      if (scb->async_state == FD_SCHEDULED)
		fprintf_unfiltered (gdb_stdlog, "[fd%d->timer-scheduled]\n",
				    scb->fd);
	      break;
	    }
	}
      scb->async_state = next_state;
    }
}
Пример #2
0
void
initialize_async_signal_handlers (void)
{
    async_signal_handlers_serial_event = make_serial_event ();

    add_file_handler (serial_event_fd (async_signal_handlers_serial_event),
                      async_signals_handler, NULL);
}
Пример #3
0
/* Set things up for readline to be invoked via the alternate
   interface, i.e. via a callback function (rl_callback_read_char),
   and hook up instream to the event loop. */
void
gdb_setup_readline (void)
{
  /* This function is a noop for the sync case.  The assumption is
     that the sync setup is ALL done in gdb_init, and we would only
     mess it up here.  The sync stuff should really go away over
     time.  */
  extern int batch_silent;

  if (!batch_silent)
    gdb_stdout = stdio_fileopen (stdout);
  gdb_stderr = stdio_fileopen (stderr);
  gdb_stdlog = gdb_stderr;  /* for moment */
  gdb_stdtarg = gdb_stderr; /* for moment */

  /* If the input stream is connected to a terminal, turn on
     editing.  */
  if (ISATTY (instream))
    {
      /* Tell gdb that we will be using the readline library. This
	 could be overwritten by a command in .gdbinit like 'set
	 editing on' or 'off'.  */
      async_command_editing_p = 1;
	  
      /* When a character is detected on instream by select or poll,
	 readline will be invoked via this callback function.  */
      call_readline = rl_callback_read_char_wrapper;
    }
  else
    {
      async_command_editing_p = 0;
      call_readline = gdb_readline2;
    }
  
  /* When readline has read an end-of-line character, it passes the
     complete line to gdb for processing. command_line_handler is the
     function that does this.  */
  input_handler = command_line_handler;
      
  /* Tell readline to use the same input stream that gdb uses. */
  rl_instream = instream;

  /* Get a file descriptor for the input stream, so that we can
     register it with the event loop.  */
  input_fd = fileno (instream);

  /* Now we need to create the event sources for the input file
     descriptor.  */
  /* At this point in time, this is the only event source that we
     register with the even loop. Another source is going to be the
     target program (inferior), but that must be registered only when
     it actually exists (I.e. after we say 'run' or after we connect
     to a remote target.  */
  add_file_handler (input_fd, stdin_event_handler, 0);
}
Пример #4
0
static int
mi_interpreter_resume (void *data)
{
  struct mi_interp *mi = data;

  /* As per hack note in mi_interpreter_init, swap in the output channels... */
  gdb_setup_readline ();

  /* These overwrite some of the initialization done in
     _intialize_event_loop.  */
  call_readline = gdb_readline2;
  input_handler = mi_execute_command_wrapper;
  add_file_handler (input_fd, stdin_event_handler, 0);
  async_command_editing_p = 0;
  /* FIXME: This is a total hack for now.  PB's use of the MI
     implicitly relies on a bug in the async support which allows
     asynchronous commands to leak through the commmand loop.  The bug
     involves (but is not limited to) the fact that sync_execution was
     erroneously initialized to 0.  Duplicate by initializing it thus
     here...  */
  sync_execution = 0;

  gdb_stdout = mi->out;
  /* Route error and log output through the MI */
  gdb_stderr = mi->err;
  gdb_stdlog = mi->log;
  /* Route target output through the MI. */
  gdb_stdtarg = mi->targ;
  /* Route target error through the MI as well. */
  gdb_stdtargerr = mi->targ;

  /* Replace all the hooks that we know about.  There really needs to
     be a better way of doing this... */
  clear_interpreter_hooks ();

  deprecated_show_load_progress = mi_load_progress;

  /* If we're _the_ interpreter, take control. */
  if (current_interp_named_p (INTERP_MI1))
    deprecated_command_loop_hook = mi1_command_loop;
  else if (current_interp_named_p (INTERP_MI2))
    deprecated_command_loop_hook = mi2_command_loop;
  else if (current_interp_named_p (INTERP_MI3))
    deprecated_command_loop_hook = mi3_command_loop;
  else
    deprecated_command_loop_hook = mi2_command_loop;

  return 1;
}
Пример #5
0
/* Initialize the IO for gdb in curses mode.  */
void
tui_initialize_io (void)
{
#ifdef SIGCONT
  signal (SIGCONT, tui_cont_sig);
#endif

  /* Create tui output streams.  */
  tui_stdout = tui_fileopen (stdout);
  tui_stderr = tui_fileopen (stderr);
  tui_out = tui_out_new (tui_stdout);

  /* Create the default UI.  It is not created because we installed a
     deprecated_init_ui_hook.  */
  tui_old_uiout = uiout = cli_out_new (gdb_stdout);

#ifdef TUI_USE_PIPE_FOR_READLINE
  /* Temporary solution for readline writing to stdout:
     redirect readline output in a pipe, read that pipe and
     output the content in the curses command window.  */
  if (pipe (tui_readline_pipe) != 0)
    {
      fprintf_unfiltered (gdb_stderr, "Cannot create pipe for readline");
      exit (1);
    }
  tui_rl_outstream = fdopen (tui_readline_pipe[1], "w");
  if (tui_rl_outstream == 0)
    {
      fprintf_unfiltered (gdb_stderr, "Cannot redirect readline output");
      exit (1);
    }
  setvbuf (tui_rl_outstream, (char*) NULL, _IOLBF, 0);

#ifdef O_NONBLOCK
  (void) fcntl (tui_readline_pipe[0], F_SETFL, O_NONBLOCK);
#else
#ifdef O_NDELAY
  (void) fcntl (tui_readline_pipe[0], F_SETFL, O_NDELAY);
#endif
#endif
  add_file_handler (tui_readline_pipe[0], tui_readline_output, 0);
#else
  tui_rl_outstream = stdout;
#endif
}
Пример #6
0
/* Initialize the IO for gdb in curses mode.  */
void
tui_initialize_io (void)
{
#ifdef SIGCONT
  signal (SIGCONT, tui_cont_sig);
#endif

  /* Create tui output streams.  */
  tui_stdout = new tui_file (stdout);
  tui_stderr = new tui_file (stderr);
  tui_out = tui_out_new (tui_stdout);

  /* Create the default UI.  */
  tui_old_uiout = cli_out_new (gdb_stdout);

#ifdef TUI_USE_PIPE_FOR_READLINE
  /* Temporary solution for readline writing to stdout: redirect
     readline output in a pipe, read that pipe and output the content
     in the curses command window.  */
  if (gdb_pipe_cloexec (tui_readline_pipe) != 0)
    error (_("Cannot create pipe for readline"));

  tui_rl_outstream = fdopen (tui_readline_pipe[1], "w");
  if (tui_rl_outstream == 0)
    error (_("Cannot redirect readline output"));

  setvbuf (tui_rl_outstream, (char*) NULL, _IOLBF, 0);

#ifdef O_NONBLOCK
  (void) fcntl (tui_readline_pipe[0], F_SETFL, O_NONBLOCK);
#else
#ifdef O_NDELAY
  (void) fcntl (tui_readline_pipe[0], F_SETFL, O_NDELAY);
#endif
#endif
  add_file_handler (tui_readline_pipe[0], tui_readline_output, 0);
#else
  tui_rl_outstream = stdout;
#endif
}
Пример #7
0
void
ser_base_async (struct serial *scb,
		int async_p)
{
  if (async_p)
    {
      /* Force a re-schedule.  */
      scb->async_state = NOTHING_SCHEDULED;
      if (serial_debug_p (scb))
	fprintf_unfiltered (gdb_stdlog, "[fd%d->asynchronous]\n",
			    scb->fd);
      reschedule (scb);

      if (scb->error_fd != -1)
	add_file_handler (scb->error_fd, handle_error_fd, scb);
    }
  else
    {
      if (serial_debug_p (scb))
	fprintf_unfiltered (gdb_stdlog, "[fd%d->synchronous]\n",
			    scb->fd);
      /* De-schedule whatever tasks are currently scheduled.  */
      switch (scb->async_state)
	{
	case FD_SCHEDULED:
	  delete_file_handler (scb->fd);
	  break;
	case NOTHING_SCHEDULED:
	  break;
	default: /* TIMER SCHEDULED */
	  delete_timer (scb->async_state);
	  break;
	}

      if (scb->error_fd != -1)
	delete_file_handler (scb->error_fd);
    }
}
Пример #8
0
void
ui_register_input_event_handler (struct ui *ui)
{
  add_file_handler (ui->input_fd, stdin_event_handler, ui);
}
Пример #9
0
/* Displays the prompt. The prompt that is displayed is the current
   top of the prompt stack, if the argument NEW_PROMPT is
   0. Otherwise, it displays whatever NEW_PROMPT is. This is used
   after each gdb command has completed, and in the following cases:
   1. when the user enters a command line which is ended by '\'
   indicating that the command will continue on the next line.
   In that case the prompt that is displayed is the empty string.
   2. When the user is entering 'commands' for a breakpoint, or
   actions for a tracepoint. In this case the prompt will be '>'
   3. Other????
   FIXME: 2. & 3. not implemented yet for async. */
void
display_gdb_prompt (char *new_prompt)
{
  int prompt_length = 0;
  char *gdb_prompt = get_prompt ();
  static int stdin_handler_removed = 0;

  /* APPLE LOCAL begin Inform user about debugging optimized code  */
  if (strcmp (gdb_prompt, "") != 0)
    {
      adjust_prompts_for_optimized_code ();
      gdb_prompt = get_prompt ();
    }
  /* APPLE LOCAL end Inform user about debugging optimized code  */

  /* Each interpreter has its own rules on displaying the command
     prompt.  */
  if (!current_interp_display_prompt_p ())
    return;

  if (target_executing && sync_execution)
    {
      /* This is to trick readline into not trying to display the
         prompt.  Even though we display the prompt using this
         function, readline still tries to do its own display if we
         don't call rl_callback_handler_install and
         rl_callback_handler_remove (which readline detects because a
         global variable is not set). If readline did that, it could
         mess up gdb signal handlers for SIGINT.  Readline assumes
         that between calls to rl_set_signals and rl_clear_signals gdb
         doesn't do anything with the signal handlers. Well, that's
         not the case, because when the target executes we change the
         SIGINT signal handler. If we allowed readline to display the
         prompt, the signal handler change would happen exactly
         between the calls to the above two functions.
         Calling rl_callback_handler_remove(), does the job. */

      delete_file_handler (input_fd);
      stdin_handler_removed = 1;
      rl_callback_handler_remove ();
      return;
    }

  if (!new_prompt)
    {
      /* Just use the top of the prompt stack. */
      prompt_length = strlen (PREFIX (0)) +
	strlen (SUFFIX (0)) +
	strlen (gdb_prompt) + 1;

      new_prompt = (char *) alloca (prompt_length);

      /* Prefix needs to have new line at end. */
      strcpy (new_prompt, PREFIX (0));
      strcat (new_prompt, gdb_prompt);
      /* Suffix needs to have a new line at end and \032 \032 at
         beginning. */
      strcat (new_prompt, SUFFIX (0));
    }

  if (async_command_editing_p)
    {
      /* Claim the terminal before we reset it.  It is quick if the
	 terminal is already ours, and if not, we are going to lose
	 when we try to install the callback handler otherwise.  We
	 can get here with the terminal still belonging to the
	 inferior if it dies an unexpected death, and somebody forgets
	 to clean up properly.  Better safe than sorry... */

      target_terminal_ours ();
      if (stdin_handler_removed)
	{
	  add_file_handler (input_fd, stdin_event_handler, 0);
	  stdin_handler_removed = 0;
	}

      rl_callback_handler_remove ();
      rl_callback_handler_install (new_prompt, input_handler);
    }
  /* new_prompt at this point can be the top of the stack or the one passed in */
  else if (new_prompt)
    {
      /* Don't use a _filtered function here.  It causes the assumed
         character position to be off, since the newline we read from
         the user is not accounted for.  */
      fputs_unfiltered (new_prompt, gdb_stdout);
      gdb_flush (gdb_stdout);
    }
}