XEmacs 21.4.18 (Social Property).
[chise/xemacs-chise.git.1] / src / process-unix.c
index c0d1989..05b5046 100644 (file)
@@ -892,6 +892,7 @@ unix_create_process (Lisp_Process *p,
 #endif
 
   set_descriptor_non_blocking (inchannel);
+  set_descriptor_non_blocking (outchannel);
 
   /* Record this as an active process, with its channels.
      As a result, child_setup will close Emacs's side of the pipes.  */
@@ -914,6 +915,10 @@ unix_create_process (Lisp_Process *p,
        int xforkin = forkin;
        int xforkout = forkout;
 
+       /* Checking for quit in the child is bad because that will 
+          cause I/O, and that, in turn, can confuse the X connection. */
+       begin_dont_check_for_quit();
+
        /* Disconnect the current controlling terminal, pursuant to
           making the pty be the controlling terminal of the process.
           Also put us in our own process group. */
@@ -1288,26 +1293,38 @@ unix_send_process (Lisp_Object proc, struct lstream* lstream)
       Bufbyte chunkbuf[512];
       Bytecount chunklen;
 
-      while (1)
+      do
        {
          Lstream_data_count writeret;
 
          chunklen = Lstream_read (lstream, chunkbuf, 512);
-         if (chunklen <= 0)
-           break; /* perhaps should abort() if < 0?
-                     This should never happen. */
          old_sigpipe =
            (SIGTYPE (*) (int)) signal (SIGPIPE, send_process_trap);
-         /* Lstream_write() will never successfully write less than
-            the amount sent in.  In the worst case, it just buffers
-            the unwritten data. */
-         writeret = Lstream_write (XLSTREAM (DATA_OUTSTREAM(p)), chunkbuf,
-                                   chunklen);
-         signal (SIGPIPE, old_sigpipe);
-         if (writeret < 0)
-           /* This is a real error.  Blocking errors are handled
-              specially inside of the filedesc stream. */
-           report_file_error ("writing to process", list1 (proc));
+         if (chunklen > 0)
+           {
+             int save_errno;
+
+             /* Lstream_write() will never successfully write less than
+                the amount sent in.  In the worst case, it just buffers
+                the unwritten data. */
+             writeret = Lstream_write (XLSTREAM (DATA_OUTSTREAM(p)), chunkbuf,
+                                       chunklen);
+             save_errno = errno;
+             signal (SIGPIPE, old_sigpipe);
+             errno = save_errno;
+             if (writeret < 0)
+               /* This is a real error.  Blocking errors are handled
+                  specially inside of the filedesc stream. */
+               report_file_error ("writing to process", list1 (proc));
+           }
+         else
+           {
+             /* Need to make sure that everything up to and including the
+                last chunk is flushed, even when the pipe is currently
+                blocked. */
+             Lstream_flush (XLSTREAM (DATA_OUTSTREAM(p)));
+             signal (SIGPIPE, old_sigpipe);
+           }
          while (Lstream_was_blocked_p (XLSTREAM (p->pipe_outstream)))
            {
              /* Buffer is full.  Wait, accepting input;
@@ -1322,7 +1339,9 @@ unix_send_process (Lisp_Object proc, struct lstream* lstream)
              Lstream_flush (XLSTREAM (p->pipe_outstream));
              signal (SIGPIPE, old_sigpipe);
            }
+         /* Perhaps should abort() if < 0?  This should never happen. */
        }
+      while (chunklen > 0);
     }
   else
     { /* We got here from a longjmp() from the SIGPIPE handler */
@@ -1331,6 +1350,9 @@ unix_send_process (Lisp_Object proc, struct lstream* lstream)
       /* #### There is controversy over whether this might cause fd leakage */
       /*      my tests say no. -slb */
       XLSTREAM (p->pipe_outstream)->flags &= ~LSTREAM_FL_IS_OPEN;
+#ifdef FILE_CODING
+      XLSTREAM (p->coding_outstream)->flags &= ~LSTREAM_FL_IS_OPEN;
+#endif
       p->status_symbol = Qexit;
       p->exit_code = 256; /* #### SIGPIPE ??? */
       p->core_dumped = 0;
@@ -1662,13 +1684,13 @@ unix_open_network_stream (Lisp_Object name, Lisp_Object host, Lisp_Object servic
     volatile int xerrno = 0;
     volatile int failed_connect = 0;
     char *ext_host;
+    char portbuf[sizeof(long)*3 + 2];
     /*
      * Caution: service can either be a string or int.
      * Convert to a C string for later use by getaddrinfo.
      */
     if (INTP (service))
       {
-       char portbuf[128];
        snprintf (portbuf, sizeof (portbuf), "%ld", (long) XINT (service));
        portstring = portbuf;
        port = htons ((unsigned short) XINT (service));