void child_terminal_init_with_pgrp (int pgrp) { struct inferior *inf = current_inferior (); struct terminal_info *tinfo = get_inflow_inferior_data (inf); #ifdef PROCESS_GROUP_TYPE /* Store the process group even without a terminal as it is used not only to reset the tty foreground process group, but also to interrupt the inferior. */ tinfo->process_group = pgrp; #endif if (gdb_has_a_terminal ()) { xfree (tinfo->ttystate); tinfo->ttystate = serial_copy_tty_state (stdin_serial, our_terminal_info.ttystate); /* 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; } }
void terminal_inferior () { if (gdb_has_a_terminal () && terminal_is_ours && inferior_thisrun_terminal == 0) { int result; #ifdef F_GETFL /* 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, tflags_inferior); result = fcntl (0, F_SETFL, tflags_inferior); OOPSY ("fcntl F_SETFL"); #endif /* Because we were careful to not change in or out of raw mode in terminal_ours, we will not change in our out of raw mode with this call, so we don't flush any input. */ result = SERIAL_SET_TTY_STATE (stdin_serial, inferior_ttystate); OOPSY ("setting tty state"); if (!job_control) { sigint_ours = (void (*) ()) signal (SIGINT, SIG_IGN); sigquit_ours = (void (*) ()) signal (SIGQUIT, SIG_IGN); } /* If attach_flag is set, we don't know whether we are sharing a terminal with the inferior or not. (attaching a process without a terminal is one case where we do not; attaching a process which we ran from the same shell as GDB via `&' is one case where we do, I think (but perhaps this is not `sharing' in the sense that we need to save and restore tty state)). I don't know if there is any way to tell whether we are sharing a terminal. So what we do is to go through all the saving and restoring of the tty state, but ignore errors setting the process group, which will happen if we are not sharing a terminal). */ if (job_control) { #ifdef HAVE_TERMIOS result = tcsetpgrp (0, inferior_process_group); if (!attach_flag) OOPSY ("tcsetpgrp"); #endif #ifdef HAVE_SGTTY result = ioctl (0, TIOCSPGRP, &inferior_process_group); if (!attach_flag) OOPSY ("TIOCSPGRP"); #endif } } terminal_is_ours = 0; }
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); } }
static void show_interactive_mode (struct ui_file *file, int from_tty, struct cmd_list_element *c, const char *value) { if (interactive_mode == AUTO_BOOLEAN_AUTO) fprintf_filtered (file, "Debugger's interactive mode " "is %s (currently %s).\n", value, gdb_has_a_terminal () ? "on" : "off"); else fprintf_filtered (file, "Debugger's interactive mode is %s.\n", value); }
void terminal_init_inferior () { 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) free (inferior_ttystate); inferior_ttystate = SERIAL_GET_TTY_STATE (stdin_serial); #ifdef PROCESS_GROUP_TYPE inferior_process_group = inferior_pid; #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; } }
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; } }
void terminal_init_inferior_with_pgrp (int pgrp) { if (gdb_has_a_terminal ()) { struct inferior *inf = current_inferior (); struct terminal_info *tinfo = get_inflow_inferior_data (inf); xfree (tinfo->ttystate); tinfo->ttystate = serial_copy_tty_state (stdin_serial, our_terminal_info.ttystate); #ifdef PROCESS_GROUP_TYPE tinfo->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 } }
void child_terminal_inferior (struct target_ops *self) { struct inferior *inf; struct terminal_info *tinfo; if (!terminal_is_ours) return; inf = current_inferior (); tinfo = get_inflow_inferior_data (inf); if (gdb_has_a_terminal () && tinfo->ttystate != NULL && tinfo->run_terminal == NULL) { int result; #ifdef F_GETFL /* 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, tinfo->tflags); result = fcntl (0, F_SETFL, tinfo->tflags); OOPSY ("fcntl F_SETFL"); #endif /* Because we were careful to not change in or out of raw mode in terminal_ours, we will not change in our out of raw mode with this call, so we don't flush any input. */ result = serial_set_tty_state (stdin_serial, tinfo->ttystate); OOPSY ("setting tty state"); if (!job_control) { sigint_ours = (void (*)()) signal (SIGINT, SIG_IGN); #ifdef SIGQUIT sigquit_ours = (void (*)()) signal (SIGQUIT, SIG_IGN); #endif } /* If attach_flag is set, we don't know whether we are sharing a terminal with the inferior or not. (attaching a process without a terminal is one case where we do not; attaching a process which we ran from the same shell as GDB via `&' is one case where we do, I think (but perhaps this is not `sharing' in the sense that we need to save and restore tty state)). I don't know if there is any way to tell whether we are sharing a terminal. So what we do is to go through all the saving and restoring of the tty state, but ignore errors setting the process group, which will happen if we are not sharing a terminal). */ if (job_control) { #ifdef HAVE_TERMIOS result = tcsetpgrp (0, tinfo->process_group); if (!inf->attach_flag) OOPSY ("tcsetpgrp"); #endif #ifdef HAVE_SGTTY result = ioctl (0, TIOCSPGRP, &tinfo->process_group); if (!inf->attach_flag) OOPSY ("TIOCSPGRP"); #endif } } terminal_is_ours = 0; }
void child_terminal_info (char *args, int from_tty) { if (!gdb_has_a_terminal ()) { printf_filtered ("This GDB does not control a terminal.\n"); return; } printf_filtered ("Inferior's terminal status (currently saved by GDB):\n"); /* First the fcntl flags. */ { int flags; flags = tflags_inferior; printf_filtered ("File descriptor flags = "); #ifndef O_ACCMODE #define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR) #endif /* (O_ACCMODE) parens are to avoid Ultrix header file bug */ switch (flags & (O_ACCMODE)) { case O_RDONLY: printf_filtered ("O_RDONLY"); break; case O_WRONLY: printf_filtered ("O_WRONLY"); break; case O_RDWR: printf_filtered ("O_RDWR"); break; } flags &= ~(O_ACCMODE); #ifdef O_NONBLOCK if (flags & O_NONBLOCK) printf_filtered (" | O_NONBLOCK"); flags &= ~O_NONBLOCK; #endif #if defined (O_NDELAY) /* If O_NDELAY and O_NONBLOCK are defined to the same thing, we will print it as O_NONBLOCK, which is good cause that is what POSIX has, and the flag will already be cleared by the time we get here. */ if (flags & O_NDELAY) printf_filtered (" | O_NDELAY"); flags &= ~O_NDELAY; #endif if (flags & O_APPEND) printf_filtered (" | O_APPEND"); flags &= ~O_APPEND; #if defined (O_BINARY) if (flags & O_BINARY) printf_filtered (" | O_BINARY"); flags &= ~O_BINARY; #endif if (flags) printf_filtered (" | 0x%x", flags); printf_filtered ("\n"); } #ifdef PROCESS_GROUP_TYPE printf_filtered ("Process group = %d\n", (int) inferior_process_group); #endif serial_print_tty_state (stdin_serial, inferior_ttystate, gdb_stdout); }