diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 5e3bce1d70..ed3a1bfeb6 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,12 @@ +2008-03-12 Thiago Jung Bauermann + + * configure.ac (AC_CHECK_FUNCS): Add check for setsid. + * config.in, configure: Regenerate. + * fork-child.c (fork_inferior): Call create_tty_session. + * inflow.c (new_tty): Set controlling terminal with TIOCSCTTY. + (create_tty_session): New function. + * terminal.h: Declare create_tty_session. + 2008-03-12 Alan Modra PR 5900 diff --git a/gdb/config.in b/gdb/config.in index b6aba7d285..fd83c62402 100644 --- a/gdb/config.in +++ b/gdb/config.in @@ -278,6 +278,9 @@ /* Define to 1 if you have the `setpgrp' function. */ #undef HAVE_SETPGRP +/* Define to 1 if you have the `setsid' function. */ +#undef HAVE_SETSID + /* Define to 1 if you have the header file. */ #undef HAVE_SGTTY_H diff --git a/gdb/configure b/gdb/configure index 5faaebaa24..b4930c46d9 100755 --- a/gdb/configure +++ b/gdb/configure @@ -18503,7 +18503,8 @@ done -for ac_func in setpgid setpgrp + +for ac_func in setpgid setpgrp setsid do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_func" >&5 diff --git a/gdb/configure.ac b/gdb/configure.ac index 2f1c33bcf6..fcc35136a8 100644 --- a/gdb/configure.ac +++ b/gdb/configure.ac @@ -603,7 +603,7 @@ AC_CHECK_FUNCS(getuid getgid) AC_CHECK_FUNCS(poll) AC_CHECK_FUNCS(pread64) AC_CHECK_FUNCS(sbrk) -AC_CHECK_FUNCS(setpgid setpgrp) +AC_CHECK_FUNCS(setpgid setpgrp setsid) AC_CHECK_FUNCS(sigaction sigprocmask sigsetmask) AC_CHECK_FUNCS(socketpair) AC_CHECK_FUNCS(syscall) diff --git a/gdb/fork-child.c b/gdb/fork-child.c index cbde5dbfac..c8e76838db 100644 --- a/gdb/fork-child.c +++ b/gdb/fork-child.c @@ -303,10 +303,16 @@ fork_inferior (char *exec_file_arg, char *allargs, char **env, if (debug_fork) sleep (debug_fork); - /* Run inferior in a separate process group. */ - debug_setpgrp = gdb_setpgid (); - if (debug_setpgrp == -1) - perror ("setpgrp failed in child"); + /* Create a new session for the inferior process, if necessary. + It will also place the inferior in a separate process group. */ + if (create_tty_session () <= 0) + { + /* No session was created, but we still want to run the inferior + in a separate process group. */ + debug_setpgrp = gdb_setpgid (); + if (debug_setpgrp == -1) + perror ("setpgrp failed in child"); + } /* Ask the tty subsystem to switch to the one we specified earlier (or to share the current terminal, if none was diff --git a/gdb/inflow.c b/gdb/inflow.c index f7bf7d12e3..d003a98dcd 100644 --- a/gdb/inflow.c +++ b/gdb/inflow.c @@ -557,6 +557,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 */ @@ -683,6 +693,33 @@ clear_sigio_trap (void) #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. diff --git a/gdb/terminal.h b/gdb/terminal.h index 911a23a355..743be6c1dc 100644 --- a/gdb/terminal.h +++ b/gdb/terminal.h @@ -82,6 +82,8 @@ extern void new_tty (void); a given run of GDB. In inflow.c. */ extern int job_control; +extern int create_tty_session (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);