(status_notify): Test p->infd > 0
[bpt/emacs.git] / src / process.c
index af82f56..e902cc7 100644 (file)
@@ -73,12 +73,12 @@ Boston, MA 02111-1307, USA.  */
 #define NUMERIC_ADDR_ERROR (numeric_addr == -1)
 #endif
 
-#if defined(BSD) || defined(STRIDE)
+#if defined(BSD_SYSTEM) || defined(STRIDE)
 #include <sys/ioctl.h>
 #if !defined (O_NDELAY) && defined (HAVE_PTYS) && !defined(USG5)
 #include <fcntl.h>
 #endif /* HAVE_PTYS and no O_NDELAY */
-#endif /* BSD or STRIDE */
+#endif /* BSD_SYSTEM || STRIDE */
 
 #ifdef BROKEN_O_NONBLOCK
 #undef O_NONBLOCK
@@ -110,13 +110,10 @@ Lisp_Object Qlast_nonmenu_event;
 /* Qexit is declared and initialized in eval.c.  */
 
 /* a process object is a network connection when its childp field is neither
-   Qt nor Qnil but is instead a string (name of foreign host we
-   are connected to + name of port we are connected to) */
+   Qt nor Qnil but is instead a cons cell (HOSTNAME PORTNUM).  */
 
 #ifdef HAVE_SOCKETS
-static Lisp_Object stream_process;
-
-#define NETCONN_P(p) (GC_STRINGP (XPROCESS (p)->childp))
+#define NETCONN_P(p) (GC_CONSP (XPROCESS (p)->childp))
 #else
 #define NETCONN_P(p) 0
 #endif /* HAVE_SOCKETS */
@@ -848,6 +845,17 @@ Value is t if a query was formerly required.")
   return Fnull (tem);
 }
 
+DEFUN ("process-contact", Fprocess_contact, Sprocess_contact,
+  1, 1, 0,
+  "Return the contact info of PROCESS; t for a real child.\n\
+For a net connection, the value is a cons cell of the form (HOST SERVICE).")
+  (process)
+     register Lisp_Object process;
+{
+  CHECK_PROCESS (process, 0);
+  return XPROCESS (process)->childp;
+}
+
 #if 0 /* Turned off because we don't currently record this info
         in the process.  Perhaps add it.  */
 DEFUN ("process-connection", Fprocess_connection, Sprocess_connection, 1, 1, 0,
@@ -958,7 +966,7 @@ Proc         Status   Buffer         Tty         Command\n\
       if (NETCONN_P (proc))
         {
          sprintf (tembuf, "(network stream connection to %s)\n",
-                  XSTRING (p->childp)->data);
+                  XSTRING (XCONS (p->childp)->car)->data);
          insert_string (tembuf);
         }
       else 
@@ -1167,7 +1175,7 @@ SIGTYPE
 create_process_1 (signo)
      int signo;
 {
-#ifdef USG
+#if defined (USG) && !defined (POSIX_SIGNALS)
   /* USG systems forget handlers when they are used;
      must reestablish each time */
   signal (signo, create_process_1);
@@ -1326,7 +1334,7 @@ create_process (process, new_argv, current_dir)
 #ifdef BSD4_1
   sighold (SIGCHLD);
 #else /* not BSD4_1 */
-#if defined (BSD) || defined (UNIPLUS) || defined (HPUX)
+#if defined (BSD_SYSTEM) || defined (UNIPLUS) || defined (HPUX)
   sigsetmask (sigmask (SIGCHLD));
 #else /* ordinary USG */
 #if 0
@@ -1427,7 +1435,7 @@ create_process (process, new_argv, current_dir)
            /* In order to get a controlling terminal on some versions
               of BSD, it is necessary to put the process in pgrp 0
               before it opens the terminal.  */
-#ifdef OSF1
+#ifdef HAVE_SETPGID
            setpgid (0, 0);
 #else
            setpgrp (0, 0);
@@ -1438,7 +1446,11 @@ create_process (process, new_argv, current_dir)
 
 #if !defined (RTU) && !defined (UNIPLUS) && !defined (DONT_REOPEN_PTY)
 /*** There is a suggestion that this ought to be a
-     conditional on TIOCSPGRP.  */
+     conditional on TIOCSPGRP,
+     or !(defined (HAVE_SETSID) && defined (TIOCSCTTY)).
+     Trying the latter gave the wrong results on Debian GNU/Linux 1.1;
+     that system does seem to need this code, even though
+     both HAVE_SETSID and TIOCSCTTY are defined.  */
        /* Now close the pty (if we had it open) and reopen it.
           This makes the pty the controlling terminal of the subprocess.  */
        if (pty_flag)
@@ -1492,7 +1504,7 @@ create_process (process, new_argv, current_dir)
 #ifdef BSD4_1
        sigrelse (SIGCHLD);
 #else /* not BSD4_1 */
-#if defined (BSD) || defined (UNIPLUS) || defined (HPUX)
+#if defined (BSD_SYSTEM) || defined (UNIPLUS) || defined (HPUX)
        sigsetmask (SIGEMPTYMASK);
 #else /* ordinary USG */
 #if 0
@@ -1573,7 +1585,7 @@ create_process (process, new_argv, current_dir)
 #ifdef BSD4_1
   sigrelse (SIGCHLD);
 #else /* not BSD4_1 */
-#if defined (BSD) || defined (UNIPLUS) || defined (HPUX)
+#if defined (BSD_SYSTEM) || defined (UNIPLUS) || defined (HPUX)
   sigsetmask (SIGEMPTYMASK);
 #else /* ordinary USG */
 #if 0
@@ -1789,7 +1801,7 @@ Fourth arg SERVICE is name of the service desired, or an integer\n\
 #endif
 #endif
 
-  XPROCESS (proc)->childp = host;
+  XPROCESS (proc)->childp = Fcons (host, Fcons (service, Qnil));
   XPROCESS (proc)->command_channel_p = Qnil;
   XPROCESS (proc)->buffer = buffer;
   XPROCESS (proc)->sentinel = Qnil;
@@ -2500,6 +2512,7 @@ read_process_output (proc, channel)
       int count = specpdl_ptr - specpdl;
       Lisp_Object odeactivate;
       Lisp_Object obuffer, okeymap;
+      int outer_running_asynch_code = running_asynch_code;
 
       /* No need to gcpro these, because all we do with them later
         is test them for EQness, and none of them should be a string.  */
@@ -2510,7 +2523,24 @@ read_process_output (proc, channel)
       specbind (Qinhibit_quit, Qt);
       specbind (Qlast_nonmenu_event, Qt);
 
+      /* In case we get recursively called,
+        and we already saved the match data nonrecursively,
+        save the same match data in safely recursive fashion.  */
+      if (outer_running_asynch_code)
+       {
+         Lisp_Object tem;
+         /* Don't clobber the CURRENT match data, either!  */
+         tem = Fmatch_data ();
+         restore_match_data ();
+         record_unwind_protect (Fstore_match_data, Fmatch_data ());
+         Fstore_match_data (tem);
+       }
+
+      /* For speed, if a search happens within this code,
+        save the match data in a special nonrecursive fashion.  */
       running_asynch_code = 1;
+
+      /* Read and dispose of the process output.  */
       internal_condition_case_1 (read_process_output_call,
                                 Fcons (outstream,
                                        Fcons (proc,
@@ -2519,8 +2549,10 @@ read_process_output (proc, channel)
                                                      Qnil))),
                                 !NILP (Vdebug_on_error) ? Qnil : Qerror,
                                 read_process_output_error_handler);
-      running_asynch_code = 0;
+
+      /* If we saved the match data nonrecursively, restore it now.  */
       restore_match_data ();
+      running_asynch_code = outer_running_asynch_code;
 
       /* Handling the process output should not deactivate the mark.  */
       Vdeactivate_mark = odeactivate;
@@ -2554,7 +2586,7 @@ read_process_output (proc, channel)
       odeactivate = Vdeactivate_mark;
 
       Fset_buffer (p->buffer);
-      opoint = point;
+      opoint = PT;
       old_read_only = current_buffer->read_only;
       XSETFASTINT (old_begv, BEGV);
       XSETFASTINT (old_zv, ZV);
@@ -2571,24 +2603,24 @@ read_process_output (proc, channel)
 
       /* If the output marker is outside of the visible region, save
         the restriction and widen.  */
-      if (! (BEGV <= point && point <= ZV))
+      if (! (BEGV <= PT && PT <= ZV))
        Fwiden ();
 
       /* Make sure opoint floats ahead of any new text, just as point
         would.  */
-      if (point <= opoint)
+      if (PT <= opoint)
        opoint += nchars;
 
       /* Insert after old_begv, but before old_zv.  */
-      if (point < XFASTINT (old_begv))
+      if (PT < XFASTINT (old_begv))
        XSETFASTINT (old_begv, XFASTINT (old_begv) + nchars);
-      if (point <= XFASTINT (old_zv))
+      if (PT <= XFASTINT (old_zv))
        XSETFASTINT (old_zv, XFASTINT (old_zv) + nchars);
 
       /* Insert before markers in case we are inserting where
         the buffer's mark is, and the user's next command is Meta-y.  */
       insert_before_markers (chars, nchars);
-      Fset_marker (p->mark, make_number (point), p->buffer);
+      Fset_marker (p->mark, make_number (PT), p->buffer);
 
       update_mode_lines++;
 
@@ -3357,7 +3389,7 @@ sigchld_handler (signo)
 
          /* USG systems forget handlers when they are used;
             must reestablish each time */
-#ifdef USG
+#if defined (USG) && !defined (POSIX_SIGNALS)
          signal (signo, sigchld_handler);   /* WARNING - must come after wait3() */
 #endif
 #ifdef  BSD4_1
@@ -3465,7 +3497,7 @@ sigchld_handler (signo)
         Otherwise (on systems that have WNOHANG), loop around
         to use up all the processes that have something to tell us.  */
 #if defined (USG) && ! (defined (HPUX) && defined (WNOHANG)) || defined (WINDOWSNT)
-#ifdef USG
+#if defined (USG) && ! defined (POSIX_SIGNALS)
       signal (signo, sigchld_handler);
 #endif
       errno = old_errno;
@@ -3500,6 +3532,7 @@ exec_sentinel (proc, reason)
   Lisp_Object sentinel, obuffer, odeactivate, okeymap;
   register struct Lisp_Process *p = XPROCESS (proc);
   int count = specpdl_ptr - specpdl;
+  int outer_running_asynch_code = running_asynch_code;
 
   /* No need to gcpro these, because all we do with them later
      is test them for EQness, and none of them should be a string.  */
@@ -3519,14 +3552,31 @@ exec_sentinel (proc, reason)
   specbind (Qinhibit_quit, Qt);
   specbind (Qlast_nonmenu_event, Qt);
 
+  /* In case we get recursively called,
+     and we already saved the match data nonrecursively,
+     save the same match data in safely recursive fashion.  */
+  if (outer_running_asynch_code)
+    {
+      Lisp_Object tem;
+      tem = Fmatch_data ();
+      restore_match_data ();
+      record_unwind_protect (Fstore_match_data, Fmatch_data ());
+      Fstore_match_data (tem);
+    }
+
+  /* For speed, if a search happens within this code,
+     save the match data in a special nonrecursive fashion.  */
   running_asynch_code = 1;
+
   internal_condition_case_1 (read_process_output_call,
                             Fcons (sentinel,
                                    Fcons (proc, Fcons (reason, Qnil))),
                             !NILP (Vdebug_on_error) ? Qnil : Qerror,
                             exec_sentinel_error_handler);
-  running_asynch_code = 0;
+
+  /* If we saved the match data nonrecursively, restore it now.  */
   restore_match_data ();
+  running_asynch_code = outer_running_asynch_code;
 
   Vdeactivate_mark = odeactivate;
 #if 0
@@ -3577,9 +3627,9 @@ status_notify ()
          XSETINT (p->update_tick, XINT (p->tick));
 
          /* If process is still active, read any output that remains.  */
-         if (XINT (p->infd) >= 0)
-           while (! EQ (p->filter, Qt)
-                  && read_process_output (proc, XINT (p->infd)) > 0);
+         while (! EQ (p->filter, Qt)
+                && XINT (p->infd) >= 0
+                && read_process_output (proc, XINT (p->infd)) > 0);
 
          buffer = p->buffer;
 
@@ -3602,6 +3652,11 @@ status_notify ()
                deactivate_process (proc);
            }
 
+         /* The actions above may have further incremented p->tick.
+            So set p->update_tick again
+            so that an error in the sentinel will not cause
+            this code to be run again.  */
+         XSETINT (p->update_tick, XINT (p->tick));
          /* Now output the message suitably.  */
          if (!NILP (p->sentinel))
            exec_sentinel (proc, msg);
@@ -3620,7 +3675,7 @@ status_notify ()
              if (NILP (XBUFFER (buffer)->name))
                continue;
              Fset_buffer (buffer);
-             opoint = point;
+             opoint = PT;
              /* Insert new output into buffer
                 at the current end-of-output marker,
                 thus preserving logical ordering of input and output.  */
@@ -3628,7 +3683,7 @@ status_notify ()
                SET_PT (marker_position (p->mark));
              else
                SET_PT (ZV);
-             if (point <= opoint)
+             if (PT <= opoint)
                opoint += XSTRING (msg)->size + XSTRING (p->name)->size + 10;
 
              tem = current_buffer->read_only;
@@ -3638,7 +3693,7 @@ status_notify ()
              insert_string (" ");
              Finsert (1, &msg);
              current_buffer->read_only = tem;
-             Fset_marker (p->mark, make_number (point), p->buffer);
+             Fset_marker (p->mark, make_number (PT), p->buffer);
 
              SET_PT (opoint);
              set_buffer_internal (old);
@@ -3733,9 +3788,6 @@ init_process ()
 
 syms_of_process ()
 {
-#ifdef HAVE_SOCKETS
-  stream_process = intern ("stream");
-#endif
   Qprocessp = intern ("processp");
   staticpro (&Qprocessp);
   Qrun = intern ("run");
@@ -3791,9 +3843,10 @@ The value takes effect when `start-process' is called.");
   defsubr (&Sset_process_filter);
   defsubr (&Sprocess_filter);
   defsubr (&Sset_process_sentinel);
-  defsubr (&Sset_process_window_size);
   defsubr (&Sprocess_sentinel);
+  defsubr (&Sset_process_window_size);
   defsubr (&Sprocess_kill_without_query);
+  defsubr (&Sprocess_contact);
   defsubr (&Slist_processes);
   defsubr (&Sprocess_list);
   defsubr (&Sstart_process);