void gdb_save_tty_state (void) { if (gdb_has_a_terminal ()) { xfree (our_terminal_info.ttystate); our_terminal_info.ttystate = serial_get_tty_state (stdin_serial); } }
void terminal_save_ours (void) { if (gdb_has_a_terminal ()) { /* We could just as well copy our_ttystate (if we felt like adding a new function serial_copy_tty_state). */ xfree (our_terminal_info.ttystate); our_terminal_info.ttystate = serial_get_tty_state (stdin_serial); } }
/* 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; } }
/* Does GDB have a terminal (on stdin)? */ int gdb_has_a_terminal (void) { if (interactive_mode != AUTO_BOOLEAN_AUTO) return interactive_mode == AUTO_BOOLEAN_TRUE; 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 our_terminal_info.tflags = fcntl (0, F_GETFL, 0); #endif gdb_has_a_terminal_flag = no; if (stdin_serial != NULL) { our_terminal_info.ttystate = serial_get_tty_state (stdin_serial); if (our_terminal_info.ttystate != NULL) { gdb_has_a_terminal_flag = yes; #ifdef PROCESS_GROUP_TYPE our_terminal_info.process_group = gdb_getpgrp (); #endif } } return gdb_has_a_terminal_flag == yes; default: /* "Can't happen". */ return 0; } }
void terminal_init_inferior_with_pgrp (int pgrp) { if (gdb_has_a_terminal ()) { /* We could just as well copy our_ttystate (if we felt like adding a new function serial_copy_tty_state()). */ if (inferior_ttystate) xfree (inferior_ttystate); inferior_ttystate = serial_get_tty_state (stdin_serial); #ifdef PROCESS_GROUP_TYPE inferior_process_group = pgrp; #endif /* Make sure that next time we call terminal_inferior (which will be before the program runs, as it needs to be), we install the new process group. */ terminal_is_ours = 1; } }
static void terminal_ours_1 (int output_only) { struct inferior *inf; struct terminal_info *tinfo; if (terminal_is_ours) return; terminal_is_ours = 1; /* Checking inferior->run_terminal is necessary so that if GDB is running in the background, it won't block trying to do the ioctl()'s below. Checking gdb_has_a_terminal avoids attempting all the ioctl's when running in batch. */ inf = current_inferior (); tinfo = get_inflow_inferior_data (inf); if (tinfo->run_terminal != NULL || gdb_has_a_terminal () == 0) return; { #ifdef SIGTTOU /* Ignore this signal since it will happen when we try to set the pgrp. */ void (*osigttou) () = NULL; #endif int result; #ifdef SIGTTOU if (job_control) osigttou = (void (*)()) signal (SIGTTOU, SIG_IGN); #endif xfree (tinfo->ttystate); tinfo->ttystate = serial_get_tty_state (stdin_serial); #ifdef PROCESS_GROUP_TYPE if (!inf->attach_flag) /* If setpgrp failed in terminal_inferior, this would give us our process group instead of the inferior's. See terminal_inferior for details. */ tinfo->process_group = gdb_getpgrp (); #endif /* Here we used to set ICANON in our ttystate, but I believe this was an artifact from before when we used readline. Readline sets the tty state when it needs to. FIXME-maybe: However, query() expects non-raw mode and doesn't use readline. Maybe query should use readline (on the other hand, this only matters for HAVE_SGTTY, not termio or termios, I think). */ /* Set tty state to our_ttystate. We don't change in our out of raw mode, to avoid flushing input. We need to do the same thing regardless of output_only, because we don't have separate terminal_is_ours and terminal_is_ours_for_output flags. It's OK, though, since readline will deal with raw mode when/if it needs to. */ serial_noflush_set_tty_state (stdin_serial, our_terminal_info.ttystate, tinfo->ttystate); if (job_control) { #ifdef HAVE_TERMIOS result = tcsetpgrp (0, our_terminal_info.process_group); #if 0 /* This fails on Ultrix with EINVAL if you run the testsuite in the background with nohup, and then log out. GDB never used to check for an error here, so perhaps there are other such situations as well. */ if (result == -1) fprintf_unfiltered (gdb_stderr, "[tcsetpgrp failed in terminal_ours: %s]\n", safe_strerror (errno)); #endif #endif /* termios */ #ifdef HAVE_SGTTY result = ioctl (0, TIOCSPGRP, &our_terminal_info.process_group); #endif } #ifdef SIGTTOU if (job_control) signal (SIGTTOU, osigttou); #endif if (!job_control) { signal (SIGINT, sigint_ours); #ifdef SIGQUIT signal (SIGQUIT, sigquit_ours); #endif } #ifdef F_GETFL tinfo->tflags = fcntl (0, F_GETFL, 0); /* Is there a reason this is being done twice? It happens both places we use F_SETFL, so I'm inclined to think perhaps there is some reason, however perverse. Perhaps not though... */ result = fcntl (0, F_SETFL, our_terminal_info.tflags); result = fcntl (0, F_SETFL, our_terminal_info.tflags); #endif } }
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); } } } }