changeset 3655:3e6cc11cfe9f

Interact properly with shells lacking job control (sh, rc, es...) * sysdep.c [BSD] (inherited_pgroup): New variable. (narrow_foreground_group, widen_foreground_group): New functions. (init_sys_modes): Call narrow_foreground_group. (reset_sys_modes): Call widen_foreground_group. * emacs.c [BSD] (inherited_pgroup): Add extern declaration. [BSD] (main): Set inherited_pgroup, and put ourselves in our own pgroup.
author Jim Blandy <jimb@redhat.com>
date Fri, 11 Jun 1993 16:22:03 +0000
parents d9313b9a63ad
children c57aec7e822b
files src/emacs.c src/sysdep.c
diffstat 2 files changed, 70 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/src/emacs.c	Fri Jun 11 16:20:38 1993 +0000
+++ b/src/emacs.c	Fri Jun 11 16:22:03 1993 +0000
@@ -81,6 +81,11 @@
    priority; Those functions have their own extern declaration.  */
 int emacs_priority;
 
+#ifdef BSD
+/* See sysdep.c.  */
+extern int inherited_pgroup;
+#endif
+
 #ifdef HAVE_X_WINDOWS
 /* If non-zero, -d was specified, meaning we're using some window system. */
 int display_arg;
@@ -292,17 +297,18 @@
 #endif
 
   clearerr (stdin);
-#if 0 /* Without EMACS_SET_TTY_PGRP, this causes Emacs to hang
-	 when run under a non-job-control shell.
-	 EMACS_SET_TTY_PGRP seems correct, but breaks even more.  */
+
 #ifdef BSD
   {
-    int pid = getpid ();
-    setpgrp (0, pid);
-    EMACS_SET_TTY_PGRP (0, &pid);
+#ifdef GETPGRP_NO_ARG
+    inherited_pgroup = getpgrp (0);
+#else /* THISSENTENCE_NO_VERB */
+    inherited_pgroup = getpgrp (0);
+#endif
+    setpgrp (0, getpid ());
   }
 #endif
-#endif
+
 
 #ifdef APOLLO
 #ifndef APOLLO_SR10
--- a/src/sysdep.c	Fri Jun 11 16:20:38 1993 +0000
+++ b/src/sysdep.c	Fri Jun 11 16:22:03 1993 +0000
@@ -756,6 +756,54 @@
 #endif /* FASYNC */
 #endif /* F_SETFL */
 
+/* Saving and restoring the process group of Emacs's terminal.  */
+
+#ifdef BSD
+
+/* The process group of which Emacs was a member when it initially
+   started.
+
+   If Emacs was in its own process group (i.e. inherited_pgroup ==
+   getpid ()), then we know we're running under a shell with job
+   control (Emacs would never be run as part of a pipeline).
+   Everything is fine.
+
+   If Emacs was not in its own process group, then we know we're
+   running under a shell (or a caller) that doesn't know how to
+   separate itself from Emacs (like sh).  Emacs must be in its own
+   process group in order to receive SIGIO correctly.  In this
+   situation, we put ourselves in our own pgroup, forcibly set the
+   tty's pgroup to our pgroup, and make sure to restore and reinstate
+   the tty's pgroup just like any other terminal setting.  If
+   inherited_group was not the tty's pgroup, then we'll get a
+   SIGTTmumble when we try to change the tty's pgroup, and a CONT if
+   it goes foreground in the future, which is what should happen.  */
+int inherited_pgroup;
+
+/* Split off the foreground process group to Emacs alone.
+   When we are in the foreground, but not started in our own process
+   group, redirect the TTY to point to our own process group.  We need
+   to be in our own process group to receive SIGIO properly.  */
+narrow_foreground_group ()
+{
+  int me = getpid ();
+
+  setpgrp (0, inherited_pgroup);
+  if (inherited_pgroup != me)
+    EMACS_SET_TTY_PGRP (0, &me);
+  setpgrp (0, me);
+}
+
+/* Set the tty to our original foreground group.  */
+widen_foreground_group ()
+{
+  if (inherited_pgroup != getpid ())
+    EMACS_SET_TTY_PGRP (0, &inherited_pgroup);
+  setpgrp (0, inherited_pgroup);
+}
+
+#endif
+
 /* Getting and setting emacs_tty structures.  */
 
 /* Set *TC to the parameters associated with the terminal FD.
@@ -982,6 +1030,11 @@
 #endif
 #endif /* not VMS */
 
+#ifdef BSD
+  if (! read_socket_hook && EQ (Vwindow_system, Qnil))
+    narrow_foreground_group ();
+#endif
+
   EMACS_GET_TTY (input_fd, &old_tty);
 
   if (!read_socket_hook && EQ (Vwindow_system, Qnil))
@@ -1334,6 +1387,10 @@
 #ifdef AIX
   hft_reset ();
 #endif
+
+#ifdef BSD
+  widen_foreground_group ();
+#endif
 }
 
 #ifdef HAVE_PTYS