+2009-05-19 Pedro Alves <pedro@codesourcery.com>
+
+ * 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 <pedro@codesourcery.com>
* breakpoint.c (insert_breakpoints, breakpoint_init_inferior)
#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"
/* 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
#include "command.h"
#include "inferior.h"
#include "inflow.h"
+#include "terminal.h"
#include "gdbcore.h"
#include "regcache.h"
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 ();
/* 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;
#include "gdbcore.h"
#include "gdbthread.h"
#include "inferior.h"
+#include "terminal.h"
#include "target.h"
#include "gdb_assert.h"
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;
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 ();
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);
{
/* 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. */
/* 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
{
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)
{
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;
+}
+
\f
/* Kill the inferior process. Make us have no inferior. */
#include <sys/types.h>
#include "gdb_dirent.h"
#include "xml-support.h"
+#include "terminal.h"
#ifdef HAVE_PERSONALITY
# include <sys/personality.h>
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);
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
#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;
/* 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) */