diff src/process.c @ 9686:cd788aa8cb2a

Handle multiple keyboard input descriptors. (non_keyboard_wait_mask): New variable. (Fset_process_filter): Update non_keyboard_wait_mask (create_process, Fopen_network_stream, deactivate_process): (init_process, sigchld_handler): Likewise. (wait_reading_process_input): Maybe use non_keyboard_wait_mask. (add_keyboard_wait_descriptor): Renamed from change_keyboard_wait_descriptor. Clear the old descriptor's bit only the first call. (delete_keyboard_wait_descriptor): New function. (keyboard_bit_set): New function. (wait_reading_process_input): Use keyboard_bit_set. Start the loop over process descs from 0, and explicitly ignore non-process input descs. (init_process): Don't init keyboard_descriptor. (keyboard_descriptor): Variable deleted. (add_keyboard_wait_descriptor): Don't set keyboard_descriptor. (delete_keyboard_wait_descriptor): New function.
author Richard M. Stallman <rms@gnu.org>
date Tue, 25 Oct 1994 09:48:44 +0000
parents d949b1150e25
children 328b8bc31f73
line wrap: on
line diff
--- a/src/process.c	Tue Oct 25 07:53:05 1994 +0000
+++ b/src/process.c	Tue Oct 25 09:48:44 1994 +0000
@@ -222,15 +222,19 @@
 #define POLL_FOR_INPUT
 #endif
 
-/* Mask of bits indicating the descriptors that we wait for input on */
+/* Mask of bits indicating the descriptors that we wait for input on.  */
 
 static SELECT_TYPE input_wait_mask;
 
+/* Mask that excludes keyboard input descriptor (s).  */
+
+static SELECT_TYPE non_keyboard_wait_mask;
+
 /* The largest descriptor currently in use for a process object.  */
 static int max_process_desc;
 
-/* Descriptor to use for keyboard input.  */
-static int keyboard_descriptor;
+/* The largest descriptor currently in use for keyboard input.  */
+static int max_keyboard_desc;
 
 /* Nonzero means delete a process right away if it exits.  */
 static int delete_exited_processes;
@@ -764,9 +768,15 @@
 {
   CHECK_PROCESS (proc, 0);
   if (EQ (filter, Qt))
-    FD_CLR (XINT (XPROCESS (proc)->infd), &input_wait_mask);
+    {
+      FD_CLR (XINT (XPROCESS (proc)->infd), &input_wait_mask);
+      FD_CLR (XINT (XPROCESS (proc)->infd), &non_keyboard_wait_mask);
+    }
   else if (EQ (XPROCESS (proc)->filter, Qt))
-    FD_SET (XINT (XPROCESS (proc)->infd), &input_wait_mask);
+    {
+      FD_SET (XINT (XPROCESS (proc)->infd), &input_wait_mask);
+      FD_SET (XINT (XPROCESS (proc)->infd), &non_keyboard_wait_mask);
+    }
   XPROCESS (proc)->filter = filter;
   return filter;
 }
@@ -1277,6 +1287,7 @@
 #endif /* SIGCHLD */
 
   FD_SET (inchannel, &input_wait_mask);
+  FD_SET (inchannel, &non_keyboard_wait_mask);
   if (inchannel > max_process_desc)
     max_process_desc = inchannel;
 
@@ -1663,6 +1674,7 @@
   XSETINT (XPROCESS (proc)->outfd, outch);
   XPROCESS (proc)->status = Qrun;
   FD_SET (inch, &input_wait_mask);
+  FD_SET (inch, &non_keyboard_wait_mask);
   if (inch > max_process_desc)
     max_process_desc = inch;
 
@@ -1702,6 +1714,7 @@
       XSETINT (p->outfd, -1);
       chan_process[inchannel] = Qnil;
       FD_CLR (inchannel, &input_wait_mask);
+      FD_CLR (inchannel, &non_keyboard_wait_mask);
       if (inchannel == max_process_desc)
 	{
 	  int i;
@@ -1968,9 +1981,10 @@
 
       /* Wait till there is something to do */
 
-      Available = input_wait_mask;
       if (! XINT (read_kbd) && wait_for_cell == 0)
-	FD_CLR (keyboard_descriptor, &Available);
+	Available = non_keyboard_wait_mask;
+      else
+	Available = input_wait_mask;
 
       /* If frame size has changed or the window is newly mapped,
 	 redisplay now, before we start to wait.  There is a race
@@ -2036,7 +2050,7 @@
 	    error("select error: %s", strerror (xerrno));
 	}
 #if defined(sun) && !defined(USG5_4)
-      else if (nfds > 0 && FD_ISSET (keyboard_descriptor, &Available)
+      else if (nfds > 0 && keyboard_bit_set (&Available)
 	       && interrupt_input)
 	/* System sometimes fails to deliver SIGIO.
 
@@ -2073,7 +2087,7 @@
 	 but select says there is input.  */
 
       if (XINT (read_kbd) && interrupt_input
-	  && (FD_ISSET (keyboard_descriptor, &Available)))
+	  && (keyboard_bit_set (&Available)))
 	kill (0, SIGIO);
 #endif
 
@@ -2088,10 +2102,10 @@
       /* Check for data from a process.  */
       /* Really FIRST_PROC_DESC should be 0 on Unix,
 	 but this is safer in the short run.  */
-      for (channel = keyboard_descriptor == 0 ? FIRST_PROC_DESC : 0;
-	   channel <= max_process_desc; channel++)
+      for (channel = 0; channel <= max_process_desc; channel++)
 	{
-	  if (FD_ISSET (channel, &Available))
+	  if (FD_ISSET (channel, &Available)
+	      && FD_ISSET (channel, &non_keyboard_wait_mask))
 	    {
 	      int nread;
 
@@ -3058,7 +3072,10 @@
 	  /* If process has terminated, stop waiting for its output.  */
 	  if (WIFSIGNALED (w) || WIFEXITED (w))
 	    if (XINT (p->infd) >= 0)
-	      FD_CLR (XINT (p->infd), &input_wait_mask);
+	      {
+		FD_CLR (XINT (p->infd), &input_wait_mask);
+		FD_CLR (XINT (p->infd), &non_keyboard_wait_mask);
+	      }
 
 	  /* Tell wait_reading_process_input that it needs to wake up and
 	     look around.  */
@@ -3279,6 +3296,60 @@
   UNGCPRO;
 }
 
+/* The first time this is called, assume keyboard input comes from DESC
+   instead of from where we used to expect it.
+   Subsequent calls mean assume input keyboard can come from DESC
+   in addition to other places.  */
+
+static int add_keyboard_wait_descriptor_called_flag;
+
+void
+add_keyboard_wait_descriptor (desc)
+     int desc;
+{
+  if (! add_keyboard_wait_descriptor_called_flag)
+    FD_CLR (0, &input_wait_mask);
+  add_keyboard_wait_descriptor_called_flag = 1;
+  FD_SET (desc, &input_wait_mask);
+  if (desc > max_keyboard_desc)
+    max_keyboard_desc = desc;
+}
+
+/* From now on, do not expect DESC to give keyboard input.  */
+
+void
+delete_keyboard_wait_descriptor (desc)
+     int desc;
+{
+  int fd;
+  int lim = max_keyboard_desc;
+
+  FD_CLR (desc, &input_wait_mask);
+
+  if (desc == max_keyboard_desc)
+    for (fd = 0; fd < lim; fd++)
+      if (FD_ISSET (fd, &input_wait_mask)
+	  && !FD_ISSET (fd, &non_keyboard_wait_mask))
+	max_keyboard_desc = fd;
+}
+
+/* Return nonzero if *MASK has a bit set
+   that corresponds to one of the keyboard input descriptors.  */
+
+int
+keyboard_bit_set (mask)
+     SELECT_TYPE *mask;
+{
+  int fd;
+
+  for (fd = 0; fd < max_keyboard_desc; fd++)
+    if (FD_ISSET (fd, mask) && FD_ISSET (fd, &input_wait_mask)
+	&& !FD_ISSET (fd, &non_keyboard_wait_mask))
+      return 1;
+
+  return 0;
+}
+
 init_process ()
 {
   register int i;
@@ -3291,10 +3362,10 @@
 #endif
 
   FD_ZERO (&input_wait_mask);
+  FD_ZERO (&non_keyboard_wait_mask);
   max_process_desc = 0;
 
-  keyboard_descriptor = 0;
-  FD_SET (keyboard_descriptor, &input_wait_mask);
+  FD_SET (0, &input_wait_mask);
 
   Vprocess_alist = Qnil;
   for (i = 0; i < MAXDESC; i++)
@@ -3304,17 +3375,6 @@
     }
 }
 
-/* From now on, assume keyboard input comes from descriptor DESC.  */
-
-void
-change_keyboard_wait_descriptor (desc)
-     int desc;
-{
-  FD_CLR (keyboard_descriptor, &input_wait_mask);
-  keyboard_descriptor = desc;
-  FD_SET (keyboard_descriptor, &input_wait_mask);
-}
-
 syms_of_process ()
 {
 #ifdef HAVE_SOCKETS