From 191c4426c1ffa97a8b818c4d4280eb095de811eb Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Tue, 19 May 2009 02:46:45 +0000 Subject: [PATCH] * fork-child.c: Don't include frame.h. Include terminal.h. (fork_inferior): Call new_tty_postfork after forking adn adding the child to the inferior list. * inferior.h (new_tty_prefork, gdb_has_a_terminal): Don't declare here. * inflow.c (struct terminal_info): Remove const qualifier from `run_terminal' field. (inferior_thisrun_terminal): Tweak comment. (inflow_inferior_exit): Release the `run_terminal' field. (copy_terminal_info): New function. (new_tty_postfork): New function. * terminal.h (new_tty_prefork, new_tty, new_tty_postfork, (copy_terminal_info, gdb_has_a_terminal, gdb_setpgid): Declare. * inf-ptrace.c: Include terminal.h. (inf_ptrace_follow_fork): Copy the parent's terminal info to the child. * linux-nat.c: Include terminal.h. (linux_child_follow_fork): Copy the parent's terminal info to the child. * inf-ttrace.c: Include terminal.h. (inf_ttrace_follow_fork): Copy the parent's terminal info to the child. --- gdb/ChangeLog | 25 +++++++++++++++++++++++++ gdb/fork-child.c | 4 +++- gdb/inf-ptrace.c | 14 +++++++++----- gdb/inf-ttrace.c | 7 ++++++- gdb/inferior.h | 6 ------ gdb/inflow.c | 35 +++++++++++++++++++++++++++++++---- gdb/linux-nat.c | 3 +++ gdb/terminal.h | 14 ++++++++++++++ 8 files changed, 91 insertions(+), 17 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 300c3af90bd..033dd7d8aef 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,28 @@ +2009-05-19 Pedro Alves + + * fork-child.c: Don't include frame.h. Include terminal.h. + (fork_inferior): Call new_tty_postfork after forking adn adding + the child to the inferior list. + * inferior.h (new_tty_prefork, gdb_has_a_terminal): Don't declare + here. + * inflow.c (struct terminal_info): Remove const qualifier from + `run_terminal' field. + (inferior_thisrun_terminal): Tweak comment. + (inflow_inferior_exit): Release the `run_terminal' field. + (copy_terminal_info): New function. + (new_tty_postfork): New function. + * terminal.h (new_tty_prefork, new_tty, new_tty_postfork, + (copy_terminal_info, gdb_has_a_terminal, gdb_setpgid): Declare. + * inf-ptrace.c: Include terminal.h. + (inf_ptrace_follow_fork): Copy the parent's terminal info to the + child. + * linux-nat.c: Include terminal.h. + (linux_child_follow_fork): Copy the parent's terminal info to the + child. + * inf-ttrace.c: Include terminal.h. + (inf_ttrace_follow_fork): Copy the parent's terminal info to the + child. + 2009-05-19 Pedro Alves * breakpoint.c (insert_breakpoints, breakpoint_init_inferior) diff --git a/gdb/fork-child.c b/gdb/fork-child.c index 03f5e28263b..988154a11b3 100644 --- a/gdb/fork-child.c +++ b/gdb/fork-child.c @@ -22,8 +22,8 @@ #include "defs.h" #include "gdb_string.h" -#include "frame.h" /* required by inferior.h */ #include "inferior.h" +#include "terminal.h" #include "target.h" #include "gdb_wait.h" #include "gdb_vfork.h" @@ -400,6 +400,8 @@ fork_inferior (char *exec_file_arg, char *allargs, char **env, /* Needed for wait_for_inferior stuff below. */ inferior_ptid = pid_to_ptid (pid); + new_tty_postfork (); + /* We have something that executes now. We'll be running through the shell at this point, but the pid shouldn't change. Targets supporting MT should fill this task's ptid with more data as soon diff --git a/gdb/inf-ptrace.c b/gdb/inf-ptrace.c index aff60385f9f..d9f73386165 100644 --- a/gdb/inf-ptrace.c +++ b/gdb/inf-ptrace.c @@ -23,6 +23,7 @@ #include "command.h" #include "inferior.h" #include "inflow.h" +#include "terminal.h" #include "gdbcore.h" #include "regcache.h" @@ -74,14 +75,20 @@ inf_ptrace_follow_fork (struct target_ops *ops, int follow_child) CORE_ADDR step_range_start = last_tp->step_range_start; CORE_ADDR step_range_end = last_tp->step_range_end; struct frame_id step_frame_id = last_tp->step_frame_id; - int attach_flag = find_inferior_pid (pid)->attach_flag; - struct inferior *inf; + struct inferior *parent_inf, *child_inf; struct thread_info *tp; /* Otherwise, deleting the parent would get rid of this breakpoint. */ last_tp->step_resume_breakpoint = NULL; + parent_inf = find_inferior_pid (pid); + + /* Add the child. */ + child_inf = add_inferior (fpid); + child_inf->attach_flag = parent_inf->attach_flag; + copy_terminal_info (child_inf, parent_inf); + /* Before detaching from the parent, remove all breakpoints from it. */ remove_breakpoints (); @@ -95,9 +102,6 @@ inf_ptrace_follow_fork (struct target_ops *ops, int follow_child) /* Delete the parent. */ detach_inferior (pid); - /* Add the child. */ - inf = add_inferior (fpid); - inf->attach_flag = attach_flag; tp = add_thread_silent (inferior_ptid); tp->step_resume_breakpoint = step_resume_breakpoint; diff --git a/gdb/inf-ttrace.c b/gdb/inf-ttrace.c index 3014c2cf9d6..e78ad8ecf2b 100644 --- a/gdb/inf-ttrace.c +++ b/gdb/inf-ttrace.c @@ -28,6 +28,7 @@ #include "gdbcore.h" #include "gdbthread.h" #include "inferior.h" +#include "terminal.h" #include "target.h" #include "gdb_assert.h" @@ -457,6 +458,9 @@ inf_ttrace_follow_fork (struct target_ops *ops, int follow_child) if (follow_child) { struct inferior *inf; + struct inferior *parent_inf; + + parent_inf = find_inferior_pid (pid); /* Copy user stepping state to the new inferior thread. */ step_resume_breakpoint = last_tp->step_resume_breakpoint; @@ -470,7 +474,8 @@ inf_ttrace_follow_fork (struct target_ops *ops, int follow_child) inferior_ptid = ptid_build (fpid, flwpid, 0); inf = add_inferior (fpid); - inf->attach_flag = find_inferior_pid (pid)->attach_flag; + inf->attach_flag = parent_inf->attach_flag; + copy_terminal_info (inf, parent_inf); detach_breakpoints (pid); target_terminal_ours (); diff --git a/gdb/inferior.h b/gdb/inferior.h index df87bf9ecc6..2938f537b3a 100644 --- a/gdb/inferior.h +++ b/gdb/inferior.h @@ -213,12 +213,6 @@ extern void startup_inferior (int); extern char *construct_inferior_arguments (struct gdbarch *, int, char **); -/* From inflow.c */ - -extern void new_tty_prefork (const char *); - -extern int gdb_has_a_terminal (void); - /* From infrun.c */ extern void start_remote (int from_tty); diff --git a/gdb/inflow.c b/gdb/inflow.c index bf2de0c72ed..f65b9c52c45 100644 --- a/gdb/inflow.c +++ b/gdb/inflow.c @@ -67,7 +67,7 @@ struct terminal_info { /* The name of the tty (from the `tty' command) that we gave to the inferior when it was started. */ - const char *run_terminal; + char *run_terminal; /* TTY state. We save it whenever the inferior stops, and restore it when it resumes. */ @@ -109,9 +109,9 @@ static void (*sigquit_ours) (); /* The name of the tty (from the `tty' command) that we're giving to the inferior when starting it up. This is only (and should only - be) used as a transient global by new_tty_prefork, new_tty and - create_tty_session, called from fork_inferior, while forking a new - child. */ + be) used as a transient global by new_tty_prefork, + create_tty_session, new_tty and new_tty_postfork, all called from + fork_inferior, while forking a new child. */ static const char *inferior_thisrun_terminal; /* Nonzero if our terminal settings are in effect. Zero if the @@ -485,10 +485,19 @@ inflow_inferior_exit (int pid) { struct inferior *inf = find_inferior_pid (pid); + xfree (inf->terminal_info->run_terminal); xfree (inf->terminal_info); inf->terminal_info = NULL; } +void +copy_terminal_info (struct inferior *to, struct inferior *from) +{ + *to->terminal_info = *from->terminal_info; + if (from->terminal_info->run_terminal) + to->terminal_info->run_terminal = from->terminal_info->run_terminal; +} + void term_info (char *arg, int from_tty) { @@ -668,6 +677,24 @@ new_tty (void) close (tty); #endif /* !go32 && !win32 */ } + +/* NEW_TTY_POSTFORK is called after forking a new child process, and + adding it to the inferior table, to store the TTYNAME being used by + the child, or null if it sharing the terminal with gdb. */ + +void +new_tty_postfork (void) +{ + /* Save the name for later, for determining whether we and the child + are sharing a tty. */ + + if (inferior_thisrun_terminal) + current_inferior ()->terminal_info->run_terminal + = xstrdup (inferior_thisrun_terminal); + + inferior_thisrun_terminal = NULL; +} + /* Kill the inferior process. Make us have no inferior. */ diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c index c3aa94fe3ad..d5799200002 100644 --- a/gdb/linux-nat.c +++ b/gdb/linux-nat.c @@ -53,6 +53,7 @@ #include #include "gdb_dirent.h" #include "xml-support.h" +#include "terminal.h" #ifdef HAVE_PERSONALITY # include @@ -626,6 +627,7 @@ linux_child_follow_fork (struct target_ops *ops, int follow_child) parent_inf = find_inferior_pid (GET_PID (last_ptid)); child_inf->attach_flag = parent_inf->attach_flag; + copy_terminal_info (child_inf, parent_inf); /* Retain child fork in ptrace (stopped) state. */ fp = find_fork_pid (child_pid); @@ -723,6 +725,7 @@ linux_child_follow_fork (struct target_ops *ops, int follow_child) parent_inf = find_inferior_pid (GET_PID (last_ptid)); child_inf->attach_flag = parent_inf->attach_flag; + copy_terminal_info (child_inf, parent_inf); /* If we're vforking, we may want to hold on to the parent until the child exits or execs. At exec time we can remove the old diff --git a/gdb/terminal.h b/gdb/terminal.h index 37947b3366d..f6a3e56febb 100644 --- a/gdb/terminal.h +++ b/gdb/terminal.h @@ -76,8 +76,16 @@ #endif /* sgtty */ #endif +struct inferior; + +extern void new_tty_prefork (const char *); + extern void new_tty (void); +extern void new_tty_postfork (void); + +extern void copy_terminal_info (struct inferior *to, struct inferior *from); + /* Do we have job control? Can be assumed to always be the same within a given run of GDB. In inflow.c. */ extern int job_control; @@ -91,4 +99,10 @@ extern int gdb_setpgid (void); /* Set up a serial structure describing standard input. In inflow.c. */ extern void initialize_stdin_serial (void); +extern int gdb_has_a_terminal (void); + +/* Set the process group of the caller to its own pid, or do nothing + if we lack job control. */ +extern int gdb_setpgid (void); + #endif /* !defined (TERMINAL_H) */ -- 2.30.2