X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Finflow.c;h=5503a42518cfa34a790f25b39cc5d371558f410b;hb=9f1b45b0da430a7a7abf9e54acbe6f2ef9d3a763;hp=8de68e14cbdc59ff765b474ec050cd00203a1454;hpb=a79b8f6ea8c26650ad9b6f29e3df46f86f4f3530;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/inflow.c b/gdb/inflow.c index 8de68e14cb..5503a42518 100644 --- a/gdb/inflow.c +++ b/gdb/inflow.c @@ -1,7 +1,5 @@ /* Low level interface to ptrace, for GDB when running under Unix. - Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, - 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, - 2009, 2010 Free Software Foundation, Inc. + Copyright (C) 1986-2014 Free Software Foundation, Inc. This file is part of GDB. @@ -28,12 +26,13 @@ #include "gdbthread.h" #include "observer.h" -#include "gdb_string.h" +#include #include #include #include "gdb_select.h" #include "inflow.h" +#include "gdbcmd.h" #ifdef HAVE_SYS_IOCTL_H #include @@ -121,6 +120,7 @@ static PROCESS_GROUP_TYPE gdb_getpgrp (void) { int process_group = -1; + #ifdef HAVE_TERMIOS process_group = tcgetpgrp (0); #endif @@ -140,10 +140,31 @@ enum } gdb_has_a_terminal_flag = have_not_checked; +/* The value of the "interactive-mode" setting. */ +static enum auto_boolean interactive_mode = AUTO_BOOLEAN_AUTO; + +/* Implement the "show interactive-mode" option. */ + +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); +} + /* 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: @@ -196,20 +217,22 @@ static void terminal_ours_1 (int); 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); - - /* We could just as well copy our_ttystate (if we felt like - adding a new function serial_copy_tty_state()). */ - xfree (tinfo->ttystate); - tinfo->ttystate = serial_get_tty_state (stdin_serial); + struct inferior *inf = current_inferior (); + struct terminal_info *tinfo = get_inflow_inferior_data (inf); #ifdef PROCESS_GROUP_TYPE - tinfo->process_group = pgrp; + /* 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. */ @@ -226,8 +249,6 @@ 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); } @@ -243,7 +264,7 @@ terminal_init_inferior (void) (and the non-threaded child_terminal_init_inferior can just pass in inferior_ptid to the same routine). */ /* We assume INFERIOR_PID is also the child's process group. */ - terminal_init_inferior_with_pgrp (PIDGET (inferior_ptid)); + terminal_init_inferior_with_pgrp (ptid_get_pid (inferior_ptid)); #endif /* PROCESS_GROUP_TYPE */ } @@ -408,8 +429,8 @@ terminal_ours_1 (int output_only) 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. - */ + 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); @@ -424,7 +445,8 @@ terminal_ours_1 (int output_only) 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", + fprintf_unfiltered (gdb_stderr, + "[tcsetpgrp failed in terminal_ours: %s]\n", safe_strerror (errno)); #endif #endif /* termios */ @@ -465,14 +487,11 @@ static const struct inferior_data *inflow_inferior_data; static void inflow_inferior_data_cleanup (struct inferior *inf, void *arg) { - struct terminal_info *info; + struct terminal_info *info = arg; - info = inferior_data (inf, inflow_inferior_data); - if (info != NULL) - { - xfree (info->run_terminal); - xfree (info); - } + xfree (info->run_terminal); + xfree (info->ttystate); + xfree (info); } /* Get the current svr4 data. If none is found yet, add it now. This @@ -486,7 +505,7 @@ get_inflow_inferior_data (struct inferior *inf) info = inferior_data (inf, inflow_inferior_data); if (info == NULL) { - info = XZALLOC (struct terminal_info); + info = XCNEW (struct terminal_info); set_inferior_data (inf, inflow_inferior_data, info); } @@ -508,6 +527,7 @@ inflow_inferior_exit (struct inferior *inf) if (info != NULL) { xfree (info->run_terminal); + xfree (info->ttystate); xfree (info); set_inferior_data (inf, inflow_inferior_data, NULL); } @@ -520,10 +540,19 @@ copy_terminal_info (struct inferior *to, struct inferior *from) tinfo_to = get_inflow_inferior_data (to); tinfo_from = get_inflow_inferior_data (from); + + xfree (tinfo_to->run_terminal); + xfree (tinfo_to->ttystate); + *tinfo_to = *tinfo_from; + if (tinfo_from->run_terminal) tinfo_to->run_terminal = xstrdup (tinfo_from->run_terminal); + + if (tinfo_from->ttystate) + tinfo_to->ttystate + = serial_copy_tty_state (stdin_serial, tinfo_from->ttystate); } void @@ -533,7 +562,7 @@ term_info (char *arg, int from_tty) } void -child_terminal_info (char *args, int from_tty) +child_terminal_info (const char *args, int from_tty) { struct inferior *inf; struct terminal_info *tinfo; @@ -550,7 +579,8 @@ child_terminal_info (char *args, int from_tty) inf = current_inferior (); tinfo = get_inflow_inferior_data (inf); - printf_filtered (_("Inferior's terminal status (currently saved by GDB):\n")); + printf_filtered (_("Inferior's terminal status " + "(currently saved by GDB):\n")); /* First the fcntl flags. */ { @@ -563,7 +593,7 @@ child_terminal_info (char *args, int from_tty) #ifndef O_ACCMODE #define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR) #endif - /* (O_ACCMODE) parens are to avoid Ultrix header file bug */ + /* (O_ACCMODE) parens are to avoid Ultrix header file bug. */ switch (flags & (O_ACCMODE)) { case O_RDONLY: @@ -658,7 +688,7 @@ new_tty (void) #ifdef TIOCNOTTY /* Disconnect the child process from our controlling terminal. On some systems (SVR4 for example), this may cause a SIGTTOU, so temporarily - ignore SIGTTOU. */ + ignore SIGTTOU. */ tty = open ("/dev/tty", O_RDWR); if (tty > 0) { @@ -697,7 +727,7 @@ new_tty (void) if (ioctl (tty, TIOCSCTTY, 0) == -1) /* Mention GDB in warning because it will appear in the inferior's terminal instead of GDB's. */ - warning ("GDB: Failed to set controlling terminal: %s", + warning (_("GDB: Failed to set controlling terminal: %s"), safe_strerror (errno)); #endif @@ -729,13 +759,13 @@ new_tty_postfork (void) /* Call set_sigint_trap when you need to pass a signal on to an attached - process when handling SIGINT */ + process when handling SIGINT. */ static void pass_signal (int signo) { #ifndef _WIN32 - kill (PIDGET (inferior_ptid), SIGINT); + kill (ptid_get_pid (inferior_ptid), SIGINT); #endif } @@ -786,7 +816,7 @@ create_tty_session (void) ret = setsid (); if (ret == -1) - warning ("Failed to create new terminal session: setsid: %s", + warning (_("Failed to create new terminal session: setsid: %s"), safe_strerror (errno)); return ret; @@ -850,6 +880,20 @@ _initialize_inflow (void) add_info ("terminal", term_info, _("Print inferior's saved terminal status.")); + add_setshow_auto_boolean_cmd ("interactive-mode", class_support, + &interactive_mode, _("\ +Set whether GDB's standard input is a terminal."), _("\ +Show whether GDB's standard input is a terminal."), _("\ +If on, GDB assumes that standard input is a terminal. In practice, it\n\ +means that GDB should wait for the user to answer queries associated to\n\ +commands entered at the command prompt. If off, GDB assumes that standard\n\ +input is not a terminal, and uses the default answer to all queries.\n\ +If auto (the default), determine which mode to use based on the standard\n\ +input settings."), + NULL, + show_interactive_mode, + &setlist, &showlist); + terminal_is_ours = 1; /* OK, figure out whether we have job control. If neither termios nor @@ -864,7 +908,7 @@ _initialize_inflow (void) #ifdef _SC_JOB_CONTROL job_control = sysconf (_SC_JOB_CONTROL); #else - job_control = 0; /* have to assume the worst */ + job_control = 0; /* Have to assume the worst. */ #endif /* _SC_JOB_CONTROL */ #endif /* _POSIX_JOB_CONTROL */ #endif /* HAVE_TERMIOS */ @@ -880,5 +924,5 @@ _initialize_inflow (void) observer_attach_inferior_exit (inflow_inferior_exit); inflow_inferior_data - = register_inferior_data_with_cleanup (inflow_inferior_data_cleanup); + = register_inferior_data_with_cleanup (NULL, inflow_inferior_data_cleanup); }