X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Finflow.c;h=6a775316c84b8a7a69e5b5f504ea823241c41f59;hb=6ba2a41553ce33bc63e4ee1beef0ff1193e3ed70;hp=d9a0439901bda8dfd446191d6553305e884fdeba;hpb=b6ba6518e9254bc25f88088228e93ac966ebccd1;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/inflow.c b/gdb/inflow.c index d9a0439901..6a775316c8 100644 --- a/gdb/inflow.c +++ b/gdb/inflow.c @@ -1,12 +1,13 @@ /* Low level interface to ptrace, for GDB when running under Unix. - Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, - 1996, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. + Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, + 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 + Free Software Foundation, Inc. This file is part of GDB. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -15,9 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + along with this program. If not, see . */ #include "defs.h" #include "frame.h" @@ -31,31 +30,18 @@ #include "gdb_string.h" #include #include -#ifdef HAVE_SYS_SELECT_H -#include -#endif +#include "gdb_select.h" -#ifdef HAVE_TERMIOS -#define PROCESS_GROUP_TYPE pid_t -#endif - -#ifdef HAVE_TERMIO -#define PROCESS_GROUP_TYPE int -#endif - -#ifdef HAVE_SGTTY -#ifdef SHORT_PGRP -/* This is only used for the ultra. Does it have pid_t? */ -#define PROCESS_GROUP_TYPE short -#else -#define PROCESS_GROUP_TYPE int -#endif -#endif /* sgtty */ +#include "inflow.h" #ifdef HAVE_SYS_IOCTL_H #include #endif +#ifndef O_NOCTTY +#define O_NOCTTY 0 +#endif + #if defined (SIGIO) && defined (FASYNC) && defined (FD_SET) && defined (F_SETOWN) static void handle_sigio (int); #endif @@ -70,7 +56,7 @@ static void terminal_ours_1 (int); /* Record terminal status separately for debugger and inferior. */ -static serial_t stdin_serial; +static struct serial *stdin_serial; /* TTY state for the inferior. We save it whenever the inferior stops, and restore it when it resumes. */ @@ -104,7 +90,7 @@ static void (*sigquit_ours) (); /* The name of the tty (from the `tty' command) that we gave to the inferior when it was last started. */ -static char *inferior_thisrun_terminal; +static const char *inferior_thisrun_terminal; /* Nonzero if our terminal settings are in effect. Zero if the inferior's settings are in effect. Ignored if !gdb_has_a_terminal @@ -112,6 +98,24 @@ static char *inferior_thisrun_terminal; int terminal_is_ours; +#ifdef PROCESS_GROUP_TYPE +static PROCESS_GROUP_TYPE +gdb_getpgrp (void) +{ + int process_group = -1; +#ifdef HAVE_TERMIOS + process_group = tcgetpgrp (0); +#endif +#ifdef HAVE_TERMIO + process_group = getpgrp (); +#endif +#ifdef HAVE_SGTTY + ioctl (0, TIOCGPGRP, &process_group); +#endif + return process_group; +} +#endif + enum { yes, no, have_not_checked @@ -129,31 +133,25 @@ gdb_has_a_terminal (void) 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. */ + /* 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); + 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); +#ifdef PROCESS_GROUP_TYPE + our_process_group = gdb_getpgrp (); #endif } } @@ -170,7 +168,7 @@ gdb_has_a_terminal (void) #define OOPSY(what) \ if (result == -1) \ fprintf_unfiltered(gdb_stderr, "[%s failed in terminal_inferior: %s]\n", \ - what, strerror (errno)) + what, safe_strerror (errno)) static void terminal_ours_1 (int); @@ -182,11 +180,11 @@ 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). */ + /* 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); + inferior_ttystate = serial_get_tty_state (stdin_serial); #ifdef PROCESS_GROUP_TYPE inferior_process_group = pgrp; @@ -199,6 +197,23 @@ terminal_init_inferior_with_pgrp (int pgrp) } } +/* Save the terminal settings again. This is necessary for the TUI + when it switches to TUI or non-TUI mode; curses changes the terminal + and gdb must be able to restore it correctly. */ + +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). */ + if (our_ttystate) + xfree (our_ttystate); + our_ttystate = serial_get_tty_state (stdin_serial); + } +} + void terminal_init_inferior (void) { @@ -207,9 +222,9 @@ terminal_init_inferior (void) debugging target with a version of target_terminal_init_inferior which passes in the process group to a generic routine which does all the work (and the non-threaded child_terminal_init_inferior can just pass in - inferior_pid to the same routine). */ + inferior_ptid to the same routine). */ /* We assume INFERIOR_PID is also the child's process group. */ - terminal_init_inferior_with_pgrp (PIDGET (inferior_pid)); + terminal_init_inferior_with_pgrp (PIDGET (inferior_ptid)); #endif /* PROCESS_GROUP_TYPE */ } @@ -220,6 +235,7 @@ void terminal_inferior (void) { if (gdb_has_a_terminal () && terminal_is_ours + && inferior_ttystate != NULL && inferior_thisrun_terminal == 0) { int result; @@ -236,7 +252,7 @@ terminal_inferior (void) /* 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); + result = serial_set_tty_state (stdin_serial, inferior_ttystate); OOPSY ("setting tty state"); if (!job_control) @@ -334,15 +350,14 @@ terminal_ours_1 (int output_only) if (inferior_ttystate) xfree (inferior_ttystate); - inferior_ttystate = SERIAL_GET_TTY_STATE (stdin_serial); -#ifdef HAVE_TERMIOS - inferior_process_group = tcgetpgrp (0); -#endif -#ifdef HAVE_TERMIO - inferior_process_group = getpgrp (); -#endif -#ifdef HAVE_SGTTY - ioctl (0, TIOCGPGRP, &inferior_process_group); + inferior_ttystate = serial_get_tty_state (stdin_serial); + +#ifdef PROCESS_GROUP_TYPE + if (!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. */ + inferior_process_group = gdb_getpgrp (); #endif /* Here we used to set ICANON in our ttystate, but I believe this @@ -359,7 +374,7 @@ terminal_ours_1 (int output_only) though, since readline will deal with raw mode when/if it needs to. */ - SERIAL_NOFLUSH_SET_TTY_STATE (stdin_serial, our_ttystate, + serial_noflush_set_tty_state (stdin_serial, our_ttystate, inferior_ttystate); if (job_control) @@ -373,7 +388,7 @@ terminal_ours_1 (int output_only) such situations as well. */ if (result == -1) fprintf_unfiltered (gdb_stderr, "[tcsetpgrp failed in terminal_ours: %s]\n", - strerror (errno)); + safe_strerror (errno)); #endif #endif /* termios */ @@ -404,29 +419,25 @@ terminal_ours_1 (int output_only) result = fcntl (0, F_SETFL, tflags_ours); result = fcntl (0, F_SETFL, tflags_ours); #endif - - result = result; /* lint */ } } -/* ARGSUSED */ void term_info (char *arg, int from_tty) { target_terminal_info (arg, from_tty); } -/* ARGSUSED */ void child_terminal_info (char *args, int from_tty) { if (!gdb_has_a_terminal ()) { - printf_filtered ("This GDB does not control a terminal.\n"); + printf_filtered (_("This GDB does not control a terminal.\n")); return; } - 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. */ { @@ -489,7 +500,7 @@ child_terminal_info (char *args, int from_tty) (int) inferior_process_group); #endif - SERIAL_PRINT_TTY_STATE (stdin_serial, inferior_ttystate, gdb_stdout); + serial_print_tty_state (stdin_serial, inferior_ttystate, gdb_stdout); } /* NEW_TTY_PREFORK is called before forking a new child process, @@ -502,7 +513,7 @@ child_terminal_info (char *args, int from_tty) the terminal specified in the NEW_TTY_PREFORK call. */ void -new_tty_prefork (char *ttyname) +new_tty_prefork (const char *ttyname) { /* Save the name for later, for determining whether we and the child are sharing a tty. */ @@ -512,7 +523,7 @@ new_tty_prefork (char *ttyname) void new_tty (void) { - register int tty; + int tty; if (inferior_thisrun_terminal == 0) return; @@ -534,12 +545,7 @@ new_tty (void) #endif /* Now open the specified new terminal. */ - -#ifdef USE_O_NOCTTY tty = open (inferior_thisrun_terminal, O_RDWR | O_NOCTTY); -#else - tty = open (inferior_thisrun_terminal, O_RDWR); -#endif if (tty == -1) { print_sys_errmsg (inferior_thisrun_terminal, errno); @@ -562,6 +568,16 @@ new_tty (void) close (2); dup (tty); } + +#ifdef TIOCSCTTY + /* Make tty our new controlling terminal. */ + 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", + safe_strerror (errno)); +#endif + if (tty > 2) close (tty); #endif /* !go32 && !win32 */ @@ -569,18 +585,17 @@ new_tty (void) /* Kill the inferior process. Make us have no inferior. */ -/* ARGSUSED */ static void kill_command (char *arg, int from_tty) { - /* FIXME: This should not really be inferior_pid (or target_has_execution). + /* FIXME: This should not really be inferior_ptid (or target_has_execution). It should be a distinct flag that indicates that a target is active, cuz some targets don't have processes! */ - if (inferior_pid == 0) - error ("The program is not being run."); + if (ptid_equal (inferior_ptid, null_ptid)) + error (_("The program is not being run.")); if (!query ("Kill the program being debugged? ")) - error ("Not confirmed."); + error (_("Not confirmed.")); target_kill (); init_thread_list (); /* Destroy thread info */ @@ -589,23 +604,20 @@ kill_command (char *arg, int from_tty) print the state we are left in. */ if (target_has_stack) { - printf_filtered ("In %s,\n", target_longname); - if (selected_frame == NULL) - fputs_filtered ("No selected stack frame.\n", gdb_stdout); - else - print_stack_frame (selected_frame, selected_frame_level, 1); + printf_filtered (_("In %s,\n"), target_longname); + print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC); } + bfd_cache_close_all (); } /* Call set_sigint_trap when you need to pass a signal on to an attached process when handling SIGINT */ -/* ARGSUSED */ static void pass_signal (int signo) { #ifndef _WIN32 - kill (PIDGET (inferior_pid), SIGINT); + kill (PIDGET (inferior_ptid), SIGINT); #endif } @@ -642,12 +654,12 @@ handle_sigio (int signo) FD_ZERO (&readfds); FD_SET (target_activity_fd, &readfds); - numfds = select (target_activity_fd + 1, &readfds, NULL, NULL, NULL); + numfds = gdb_select (target_activity_fd + 1, &readfds, NULL, NULL, NULL); if (numfds >= 0 && FD_ISSET (target_activity_fd, &readfds)) { #ifndef _WIN32 if ((*target_activity_function) ()) - kill (inferior_pid, SIGINT); + kill (PIDGET (inferior_ptid), SIGINT); #endif } } @@ -680,18 +692,45 @@ void set_sigio_trap (void) { if (target_activity_function) - internal_error (__FILE__, __LINE__, "failed internal consistency check"); + internal_error (__FILE__, __LINE__, _("failed internal consistency check")); } void clear_sigio_trap (void) { if (target_activity_function) - internal_error (__FILE__, __LINE__, "failed internal consistency check"); + internal_error (__FILE__, __LINE__, _("failed internal consistency check")); } #endif /* No SIGIO. */ +/* Create a new session if the inferior will run in a different tty. + A session is UNIX's way of grouping processes that share a controlling + terminal, so a new one is needed if the inferior terminal will be + different from GDB's. + + Returns the session id of the new session, 0 if no session was created + or -1 if an error occurred. */ +pid_t +create_tty_session (void) +{ +#ifdef HAVE_SETSID + pid_t ret; + + if (!job_control || inferior_thisrun_terminal == 0) + return 0; + + ret = setsid (); + if (ret == -1) + warning ("Failed to create new terminal session: setsid: %s", + safe_strerror (errno)); + + return ret; +#else + return 0; +#endif /* HAVE_SETSID */ +} + /* This is here because this is where we figure out whether we (probably) have job control. Just using job_control only does part of it because setpgid or setpgrp might not exist on a system without job control. @@ -708,34 +747,49 @@ gdb_setpgid (void) if (job_control) { -#if defined (NEED_POSIX_SETPGID) || (defined (HAVE_TERMIOS) && defined (HAVE_SETPGID)) - /* setpgid (0, 0) is supposed to work and mean the same thing as - this, but on Ultrix 4.2A it fails with EPERM (and +#if defined (HAVE_TERMIOS) || defined (TIOCGPGRP) +#ifdef HAVE_SETPGID + /* The call setpgid (0, 0) is supposed to work and mean the same + thing as this, but on Ultrix 4.2A it fails with EPERM (and setpgid (getpid (), getpid ()) succeeds). */ retval = setpgid (getpid (), getpid ()); #else -#if defined (TIOCGPGRP) -#if defined(USG) && !defined(SETPGRP_ARGS) +#ifdef HAVE_SETPGRP +#ifdef SETPGRP_VOID retval = setpgrp (); #else retval = setpgrp (getpid (), getpid ()); -#endif /* USG */ -#endif /* TIOCGPGRP. */ -#endif /* NEED_POSIX_SETPGID */ +#endif +#endif /* HAVE_SETPGRP */ +#endif /* HAVE_SETPGID */ +#endif /* defined (HAVE_TERMIOS) || defined (TIOCGPGRP) */ } + return retval; } +/* 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); +} + void _initialize_inflow (void) { add_info ("terminal", term_info, - "Print inferior's saved terminal status."); + _("Print inferior's saved terminal status.")); add_com ("kill", class_run, kill_command, - "Kill execution of program being debugged."); + _("Kill execution of program being debugged.")); - inferior_pid = 0; + inferior_ptid = null_ptid; terminal_is_ours = 1;