(Faref): Use SPLIT_CHAR instead of SPLIT_NON_ASCII_CHAR.
[bpt/emacs.git] / src / process.c
index e201ca4..8b23d2f 100644 (file)
@@ -20,8 +20,8 @@ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.  */
 
 
+#define _GNU_SOURCE            /* to get strsignal declared with glibc 2 */
 #include <config.h>
-
 #include <signal.h>
 
 /* This file is split into two parts by the following preprocessor
@@ -43,9 +43,6 @@ Boston, MA 02111-1307, USA.  */
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
 
 #ifdef WINDOWSNT
 #include <stdlib.h>
@@ -62,7 +59,7 @@ Boston, MA 02111-1307, USA.  */
 #endif /* NEED_NET_ERRNO_H */
 #endif /* HAVE_SOCKETS */
 
-/* TERM is a poor-man's SLIP, used on Linux.  */
+/* TERM is a poor-man's SLIP, used on GNU/Linux.  */
 #ifdef TERM
 #include <client.h>
 #endif
@@ -111,6 +108,8 @@ Boston, MA 02111-1307, USA.  */
 #include "blockinput.h"
 #include "keyboard.h"
 #include "dispextern.h"
+#include "composite.h"
+#include "atimer.h"
 
 #define max(a, b) ((a) > (b) ? (a) : (b))
 
@@ -149,7 +148,6 @@ Lisp_Object Qlast_nonmenu_event;
 extern void set_waiting_for_input P_ ((EMACS_TIME *));
 
 extern int errno;
-extern char *strerror ();
 #ifdef VMS
 extern char *sys_errlist[];
 #endif
@@ -158,50 +156,6 @@ extern char *sys_errlist[];
 extern int h_errno;
 #endif
 
-#ifndef HAVE_STRSIGNAL
-#ifndef SYS_SIGLIST_DECLARED
-#ifndef VMS
-#ifndef BSD4_1
-#ifndef WINDOWSNT
-#ifndef LINUX
-extern char *sys_siglist[];
-#endif /* not LINUX */
-#else /* BSD4_1 */
-char *sys_siglist[] =
-  {
-    "bum signal!!",
-    "hangup",
-    "interrupt",
-    "quit",
-    "illegal instruction",
-    "trace trap",
-    "iot instruction",
-    "emt instruction",
-    "floating point exception",
-    "kill",
-    "bus error",
-    "segmentation violation",
-    "bad argument to system call",
-    "write on a pipe with no one to read it",
-    "alarm clock",
-    "software termination signal from kill",
-    "status signal",
-    "sendable stop signal not from tty",
-    "stop signal from tty",
-    "continue a stopped process",
-    "child status has changed",
-    "background read attempted from control tty",
-    "background write attempted from control tty",
-    "input record available at control tty",
-    "exceeded CPU time limit",
-    "exceeded file size limit"
-    };
-#endif /* not WINDOWSNT */
-#endif
-#endif /* VMS */
-#endif /* ! SYS_SIGLIST_DECLARED */
-#endif /* ! HAVE_STRSIGNAL */
-
 /* t means use pty, nil means use a pipe,
    maybe other values to come.  */
 static Lisp_Object Vprocess_connection_type;
@@ -363,7 +317,7 @@ status_message (status)
   if (EQ (symbol, Qsignal) || EQ (symbol, Qstop))
     {
       char *signame;
-      synchronize_messages_locale ();
+      synchronize_system_messages_locale ();
       signame = strsignal (code);
       if (signame == 0)
        signame = "unknown";
@@ -1069,7 +1023,6 @@ static Lisp_Object start_process_unwind ();
 
 DEFUN ("start-process", Fstart_process, Sstart_process, 3, MANY, 0,
   "Start a program in a subprocess.  Return the process object for it.\n\
-Args are NAME BUFFER PROGRAM &rest PROGRAM-ARGS\n\
 NAME is name for process.  It is modified if necessary to make it unique.\n\
 BUFFER is the buffer or (buffer-name) to associate with the process.\n\
  Process output goes at end of that buffer, unless you specify\n\
@@ -1284,18 +1237,14 @@ start_process_unwind (proc)
   return Qnil;
 }
 
-
-SIGTYPE
-create_process_1 (signo)
-     int signo;
+void
+create_process_1 (timer)
+     struct atimer *timer;
 {
-#if defined (USG) && !defined (POSIX_SIGNALS)
-  /* USG systems forget handlers when they are used;
-     must reestablish each time */
-  signal (signo, create_process_1);
-#endif /* USG */
+  /* Nothing to do.  */
 }
 
+
 #if 0  /* This doesn't work; see the note before sigchld_handler.  */
 #ifdef USG
 #ifdef SIGCHLD
@@ -1732,14 +1681,22 @@ create_process (process, new_argv, current_dir)
       /* If the subfork execv fails, and it exits,
         this close hangs.  I don't know why.
         So have an interrupt jar it loose.  */
-      stop_polling ();
-      signal (SIGALRM, create_process_1);
-      alarm (1);
-      XPROCESS (process)->subtty = Qnil;
-      if (forkin >= 0)
-       emacs_close (forkin);
-      alarm (0);
-      start_polling ();
+      {
+       struct atimer *timer;
+       EMACS_TIME offset;
+       
+       stop_polling ();
+       EMACS_SET_SECS_USECS (offset, 1, 0);
+       timer = start_atimer (ATIMER_RELATIVE, offset, create_process_1, 0);
+       
+       XPROCESS (process)->subtty = Qnil;
+       if (forkin >= 0)
+         emacs_close (forkin);
+
+       cancel_atimer (timer);
+       start_polling ();
+      }
+      
       if (forkin != forkout && forkout >= 0)
        emacs_close (forkout);
 
@@ -1878,6 +1835,7 @@ Fourth arg SERVICE is name of the service desired, or an integer\n\
      Some kernels have a bug which causes retrying connect to fail
      after a connect.  Polling can interfere with gethostbyname too.  */
 #ifdef POLL_FOR_INPUT
+  record_unwind_protect (unwind_stop_other_atimers, Qnil);
   bind_polling_period (10);
 #endif
 
@@ -2416,18 +2374,13 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
      Causes "poll: interrupted system call" messages when Emacs is run
      in an X window
      Turn off periodic alarms (in case they are in use) */
-  stop_polling ();
+  turn_on_atimers (0);
 #endif
 
   while (1)
     {
       int timeout_reduced_for_timers = 0;
 
-#ifdef HAVE_X_WINDOWS
-      if (display_busy_cursor_p)
-       Fx_hide_busy_cursor (Qnil);
-#endif
-
       /* If calling from keyboard input, do not quit
         since we want to return C-g as an input character.
         Otherwise, do pending quit if requested.  */
@@ -2851,12 +2804,6 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
   start_polling ();
 #endif
 
-#ifdef HAVE_X_WINDOWS
-  if (display_busy_cursor_p)
-    if (!inhibit_busy_cursor)
-      Fx_show_busy_cursor ();
-#endif
-   
   return got_some_input;
 }
 \f
@@ -2877,6 +2824,7 @@ read_process_output_error_handler (error)
   Vinhibit_quit = Qt;
   update_echo_area ();
   Fsleep_for (make_number (2), Qnil);
+  return Qt;
 }
 
 /* Read pending output from the process channel,
@@ -3228,7 +3176,8 @@ read_process_output (proc, channel)
       else
        {
          insert_1_both (chars, nchars, nbytes, 0, 1, 1);
-         signal_after_change (opoint, 0, PT - opoint);
+         signal_after_change (before, 0, PT - before);
+         update_compositions (before, PT, CHECK_BORDER);
        }
       set_marker_both (p->mark, p->buffer, PT, PT_BYTE);
 
@@ -3300,7 +3249,9 @@ send_process_trap ()
    is sent.  But if the data ends at the middle of multi-byte
    representation, that incomplete sequence of bytes are sent without
    being encoded.  Should we store them in a buffer to prepend them to
-   the data send later?  */
+   the data send later? 
+
+   This function can evaluate Lisp code and can garbage collect.  */
 
 void
 send_process (proc, buf, len, object)
@@ -3311,7 +3262,6 @@ send_process (proc, buf, len, object)
 {
   /* Use volatile to protect variables from being clobbered by longjmp.  */
   int rv;
-  volatile unsigned char *procname = XSTRING (XPROCESS (proc)->name)->data;
   struct coding_system *coding;
   struct gcpro gcpro1;
   int carryover = XINT (XPROCESS (proc)->encoding_carryover);
@@ -3326,9 +3276,11 @@ send_process (proc, buf, len, object)
   if (! NILP (XPROCESS (proc)->raw_status_low))
     update_status (XPROCESS (proc));
   if (! EQ (XPROCESS (proc)->status, Qrun))
-    error ("Process %s not running", procname);
+    error ("Process %s not running",
+          XSTRING (XPROCESS (proc)->name)->data);
   if (XINT (XPROCESS (proc)->outfd) < 0)
-    error ("Output file descriptor of %s is closed", procname);
+    error ("Output file descriptor of %s is closed",
+          XSTRING (XPROCESS (proc)->name)->data);
 
   coding = proc_encode_coding_system[XINT (XPROCESS (proc)->outfd)];
   Vlast_coding_system_used = coding->symbol;
@@ -3471,6 +3423,32 @@ send_process (proc, buf, len, object)
                    Lisp_Object zero;
                    int offset;
 
+#ifdef BROKEN_PTY_READ_AFTER_EAGAIN
+                   /* A gross hack to work around a bug in FreeBSD.
+                      In the following sequence, read(2) returns
+                      bogus data:
+
+                      write(2)  1022 bytes
+                      write(2)   954 bytes, get EAGAIN
+                      read(2)   1024 bytes in process_read_output
+                      read(2)     11 bytes in process_read_output
+
+                      That is, read(2) returns more bytes than have
+                      ever been written successfully.  The 1033 bytes
+                      read are the 1022 bytes written successfully
+                      after processing (for example with CRs added if
+                      the terminal is set up that way which it is
+                      here).  The same bytes will be seen again in a
+                      later read(2), without the CRs.  */
+                   
+                   if (errno == EAGAIN)
+                     {
+                       int flags = FWRITE;
+                       ioctl (XINT (XPROCESS (proc)->outfd), TIOCFLUSH,
+                              &flags);
+                     }
+#endif /* BROKEN_PTY_READ_AFTER_EAGAIN */
+                   
                    /* Running filters might relocate buffers or strings.
                       Arrange to relocate BUF.  */
                    if (BUFFERP (object))
@@ -3515,9 +3493,11 @@ send_process (proc, buf, len, object)
       XSETINT (XPROCESS (proc)->tick, ++process_tick);
       deactivate_process (proc);
 #ifdef VMS
-      error ("Error writing to process %s; closed it", procname);
+      error ("Error writing to process %s; closed it", 
+            XSTRING (XPROCESS (proc)->name)->data);
 #else
-      error ("SIGPIPE raised on process %s; closed it", procname);
+      error ("SIGPIPE raised on process %s; closed it",
+            XSTRING (XPROCESS (proc)->name)->data);
 #endif
     }
 
@@ -4257,7 +4237,7 @@ sigchld_handler (signo)
              int code = WTERMSIG (w);
              char *signame;
 
-             synchronize_messages_locale ();
+             synchronize_system_messages_locale ();
              signame = strsignal (code);
 
              if (signame == 0)
@@ -4304,6 +4284,7 @@ exec_sentinel_error_handler (error)
   Vinhibit_quit = Qt;
   update_echo_area ();
   Fsleep_for (make_number (2), Qnil);
+  return Qt;
 }
 
 static void
@@ -4791,7 +4772,7 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
 
   /* Turn off periodic alarms (in case they are in use)
      because the select emulator uses alarms.  */
-  stop_polling ();
+  turn_on_atimers (0);
 
   while (1)
     {