static void print_flush (void) { struct serial *gdb_stdout_serial; if (deprecated_error_begin_hook) deprecated_error_begin_hook (); if (target_supports_terminal_ours ()) target_terminal_ours (); /* We want all output to appear now, before we print the error. We have 3 levels of buffering we have to flush (it's possible that some of these should be changed to flush the lower-level ones too): */ /* 1. The _filtered buffer. */ if (filtered_printing_initialized ()) wrap_here (""); /* 2. The stdio buffer. */ gdb_flush (gdb_stdout); gdb_flush (gdb_stderr); /* 3. The system-level buffer. */ gdb_stdout_serial = serial_fdopen (1); if (gdb_stdout_serial) { serial_drain_output (gdb_stdout_serial); serial_un_fdopen (gdb_stdout_serial); } annotate_error_begin (); }
/* Does GDB have a terminal (on stdin)? */ int gdb_has_a_terminal (void) { switch (gdb_has_a_terminal_flag) { case yes: return 1; case no: return 0; case have_not_checked: /* Get all the current tty settings (including whether we have a tty at all!). Can't do this in _initialize_inflow because serial_fdopen() won't work until the serial_ops_list is initialized. */ #ifdef F_GETFL tflags_ours = fcntl (0, F_GETFL, 0); #endif gdb_has_a_terminal_flag = no; stdin_serial = serial_fdopen (0); if (stdin_serial != NULL) { our_ttystate = serial_get_tty_state (stdin_serial); if (our_ttystate != NULL) { gdb_has_a_terminal_flag = yes; #ifdef HAVE_TERMIOS our_process_group = tcgetpgrp (0); #endif #ifdef HAVE_TERMIO our_process_group = getpgrp (); #endif #ifdef HAVE_SGTTY ioctl (0, TIOCGPGRP, &our_process_group); #endif } } return gdb_has_a_terminal_flag == yes; default: /* "Can't happen". */ return 0; } }
static void print_flush (void) { struct ui *ui = current_ui; struct serial *gdb_stdout_serial; if (deprecated_error_begin_hook) deprecated_error_begin_hook (); gdb::optional<target_terminal::scoped_restore_terminal_state> term_state; /* While normally there's always something pushed on the target stack, the NULL check is needed here because we can get here very early during startup, before the target stack is first initialized. */ if (current_top_target () != NULL && target_supports_terminal_ours ()) { term_state.emplace (); target_terminal::ours_for_output (); } /* We want all output to appear now, before we print the error. We have 3 levels of buffering we have to flush (it's possible that some of these should be changed to flush the lower-level ones too): */ /* 1. The _filtered buffer. */ if (filtered_printing_initialized ()) wrap_here (""); /* 2. The stdio buffer. */ gdb_flush (gdb_stdout); gdb_flush (gdb_stderr); /* 3. The system-level buffer. */ gdb_stdout_serial = serial_fdopen (fileno (ui->outstream)); if (gdb_stdout_serial) { serial_drain_output (gdb_stdout_serial); serial_un_fdopen (gdb_stdout_serial); } annotate_error_begin (); }
static void connect_command (char *args, int fromtty) { int c; char cur_esc = 0; serial_ttystate ttystate; struct serial *port_desc; /* TTY port */ dont_repeat (); if (args) fprintf_unfiltered (gdb_stderr, "This command takes no args. They have been ignored.\n"); printf_unfiltered ("[Entering connect mode. Use ~. or ~^D to escape]\n"); tty_desc = serial_fdopen (0); port_desc = last_serial_opened; ttystate = serial_get_tty_state (tty_desc); serial_raw (tty_desc); serial_raw (port_desc); make_cleanup (cleanup_tty, ttystate); while (1) { int mask; mask = serial_wait_2 (tty_desc, port_desc, -1); if (mask & 2) { /* tty input */ char cx; while (1) { c = serial_readchar (tty_desc, 0); if (c == SERIAL_TIMEOUT) break; if (c < 0) perror_with_name ("connect"); cx = c; serial_write (port_desc, &cx, 1); switch (cur_esc) { case 0: if (c == '\r') cur_esc = c; break; case '\r': if (c == '~') cur_esc = c; else cur_esc = 0; break; case '~': if (c == '.' || c == '\004') return; else cur_esc = 0; } } } if (mask & 1) { /* Port input */ char cx; while (1) { c = serial_readchar (port_desc, 0); if (c == SERIAL_TIMEOUT) break; if (c < 0) perror_with_name ("connect"); cx = c; serial_write (tty_desc, &cx, 1); } } } }
/* Get all the current tty settings (including whether we have a tty at all!). We can't do this in _initialize_inflow because serial_fdopen() won't work until the serial_ops_list is initialized, but we don't want to do it lazily either, so that we can guarantee stdin_serial is opened if there is a terminal. */ void initialize_stdin_serial (void) { stdin_serial = serial_fdopen (0); }