changeset 31806:b148beb59511

(process_sent_to): New variable. (send_process): Workaround for a crash on sparc-sun-solaris-2.6 with GCC 2.95.2 caused by a parameter being clobbered by longjmp. Declare more parameters volatile.
author Gerd Moellmann <gerd@gnu.org>
date Thu, 21 Sep 2000 11:48:48 +0000
parents 5210694a17b4
children db5ea3d2a1b4
files src/process.c
diffstat 1 files changed, 123 insertions(+), 112 deletions(-) [+]
line wrap: on
line diff
--- a/src/process.c	Thu Sep 21 11:15:01 2000 +0000
+++ b/src/process.c	Thu Sep 21 11:48:48 2000 +0000
@@ -3138,6 +3138,7 @@
 /* Sending data to subprocess */
 
 jmp_buf send_process_frame;
+Lisp_Object process_sent_to;
 
 SIGTYPE
 send_process_trap ()
@@ -3164,9 +3165,9 @@
 void
 send_process (proc, buf, len, object)
      volatile Lisp_Object proc;
-     unsigned char *buf;
-     int len;
-     Lisp_Object object;
+     unsigned char *volatile buf;
+     volatile int len;
+     volatile Lisp_Object object;
 {
   /* Use volatile to protect variables from being clobbered by longjmp.  */
   int rv;
@@ -3219,7 +3220,7 @@
   if (CODING_REQUIRE_ENCODING (coding))
     {
       int require = encoding_buffer_size (coding, len);
-      int from_byte = -1, from, to;
+      int from_byte = -1, from = -1, to = -1;
       unsigned char *temp_buf = NULL;
 
       if (BUFFERP (object))
@@ -3247,7 +3248,7 @@
 	       : XSTRING (object)->data + from_byte);
 
       object = XPROCESS (proc)->encoding_buf;
-      encode_coding (coding, buf, XSTRING (object)->data,
+      encode_coding (coding, (char *) buf, XSTRING (object)->data,
 		     len, STRING_BYTES (XSTRING (object)));
       len = coding->produced;
       buf = XSTRING (object)->data;
@@ -3261,7 +3262,7 @@
     error ("Could not find this process: %x", p->pid);
   else if (write_to_vms_process (vs, buf, len))
     ;
-#else
+#else /* not VMS */
 
   if (pty_max_bytes == 0)
     {
@@ -3277,128 +3278,138 @@
       pty_max_bytes--;
     }
 
+  /* 2000-09-21: Emacs 20.7, sparc-sun-solaris-2.6, GCC 2.95.2,
+     CFLAGS="-g -O": The value of the parameter `proc' is clobbered
+     when returning with longjmp despite being declared volatile.  */
   if (!setjmp (send_process_frame))
-    while (len > 0)
-      {
-	int this = len;
-	SIGTYPE (*old_sigpipe)();
-
-	/* Decide how much data we can send in one batch.
-	   Long lines need to be split into multiple batches.  */
-	if (!NILP (XPROCESS (proc)->pty_flag))
-	  {
-	    /* Starting this at zero is always correct when not the first iteration
-	       because the previous iteration ended by sending C-d.
-	       It may not be correct for the first iteration
-	       if a partial line was sent in a separate send_process call.
-	       If that proves worth handling, we need to save linepos
-	       in the process object.  */
-	    int linepos = 0;
-	    unsigned char *ptr = buf;
-	    unsigned char *end = buf + len;
-
-	    /* Scan through this text for a line that is too long.  */
-	    while (ptr != end && linepos < pty_max_bytes)
-	      {
-		if (*ptr == '\n')
-		  linepos = 0;
-		else
-		  linepos++;
-		ptr++;
-	      }
-	    /* If we found one, break the line there
-	       and put in a C-d to force the buffer through.  */
-	    this = ptr - buf;
-	  }
-
-	/* Send this batch, using one or more write calls.  */
-	while (this > 0)
-	  {
-	    old_sigpipe = (SIGTYPE (*) ()) signal (SIGPIPE, send_process_trap);
-	    rv = emacs_write (XINT (XPROCESS (proc)->outfd), buf, this);
-	    signal (SIGPIPE, old_sigpipe);
-
-	    if (rv < 0)
-	      {
-		if (0
+    {
+      process_sent_to = proc;
+      while (len > 0)
+	{
+	  int this = len;
+	  SIGTYPE (*old_sigpipe)();
+
+	  /* Decide how much data we can send in one batch.
+	     Long lines need to be split into multiple batches.  */
+	  if (!NILP (XPROCESS (proc)->pty_flag))
+	    {
+	      /* Starting this at zero is always correct when not the first iteration
+		 because the previous iteration ended by sending C-d.
+		 It may not be correct for the first iteration
+		 if a partial line was sent in a separate send_process call.
+		 If that proves worth handling, we need to save linepos
+		 in the process object.  */
+	      int linepos = 0;
+	      unsigned char *ptr = (unsigned char *) buf;
+	      unsigned char *end = (unsigned char *) buf + len;
+
+	      /* Scan through this text for a line that is too long.  */
+	      while (ptr != end && linepos < pty_max_bytes)
+		{
+		  if (*ptr == '\n')
+		    linepos = 0;
+		  else
+		    linepos++;
+		  ptr++;
+		}
+	      /* If we found one, break the line there
+		 and put in a C-d to force the buffer through.  */
+	      this = ptr - buf;
+	    }
+
+	  /* Send this batch, using one or more write calls.  */
+	  while (this > 0)
+	    {
+	      old_sigpipe = (SIGTYPE (*) ()) signal (SIGPIPE, send_process_trap);
+	      rv = emacs_write (XINT (XPROCESS (proc)->outfd),
+				(char *) buf, this);
+	      signal (SIGPIPE, old_sigpipe);
+
+	      if (rv < 0)
+		{
+		  if (0
 #ifdef EWOULDBLOCK
-		    || errno == EWOULDBLOCK
+		      || errno == EWOULDBLOCK
 #endif
 #ifdef EAGAIN
-		    || errno == EAGAIN
+		      || errno == EAGAIN
 #endif
-		    )
-		  /* Buffer is full.  Wait, accepting input; 
-		     that may allow the program
-		     to finish doing output and read more.  */
-		  {
-		    Lisp_Object zero;
-		    int offset;
+		      )
+		    /* Buffer is full.  Wait, accepting input; 
+		       that may allow the program
+		       to finish doing output and read more.  */
+		    {
+		      Lisp_Object zero;
+		      int offset = 0;
 
 #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.  */
+		      /* 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);
-		      }
+		      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))
-		      offset = BUF_PTR_BYTE_POS (XBUFFER (object), buf);
-		    else if (STRINGP (object))
-		      offset = buf - XSTRING (object)->data;
-
-		    XSETFASTINT (zero, 0);
+		      /* Running filters might relocate buffers or strings.
+			 Arrange to relocate BUF.  */
+		      if (BUFFERP (object))
+			offset = BUF_PTR_BYTE_POS (XBUFFER (object), buf);
+		      else if (STRINGP (object))
+			offset = buf - XSTRING (object)->data;
+
+		      XSETFASTINT (zero, 0);
 #ifdef EMACS_HAS_USECS
-		    wait_reading_process_input (0, 20000, zero, 0);
+		      wait_reading_process_input (0, 20000, zero, 0);
 #else
-		    wait_reading_process_input (1, 0, zero, 0);
+		      wait_reading_process_input (1, 0, zero, 0);
 #endif
 
-		    if (BUFFERP (object))
-		      buf = BUF_BYTE_ADDRESS (XBUFFER (object), offset);
-		    else if (STRINGP (object))
-		      buf = offset + XSTRING (object)->data;
-
-		    rv = 0;
-		  }
-		else
-		  /* This is a real error.  */
-		  report_file_error ("writing to process", Fcons (proc, Qnil));
-	      }
-	    buf += rv;
-	    len -= rv;
-	    this -= rv;
-	  }
-
-	/* If we sent just part of the string, put in an EOF
-	   to force it through, before we send the rest.  */
-	if (len > 0)
-	  Fprocess_send_eof (proc);
-      }
-#endif
+		      if (BUFFERP (object))
+			buf = BUF_BYTE_ADDRESS (XBUFFER (object), offset);
+		      else if (STRINGP (object))
+			buf = offset + XSTRING (object)->data;
+
+		      rv = 0;
+		    }
+		  else
+		    /* This is a real error.  */
+		    report_file_error ("writing to process", Fcons (proc, Qnil));
+		}
+	      buf += rv;
+	      len -= rv;
+	      this -= rv;
+	    }
+
+	  /* If we sent just part of the string, put in an EOF
+	     to force it through, before we send the rest.  */
+	  if (len > 0)
+	    Fprocess_send_eof (proc);
+	}
+    }
+#endif /* not VMS */
   else
     {
+#ifndef VMS
+      proc = process_sent_to;
+#endif
       XPROCESS (proc)->raw_status_low = Qnil;
       XPROCESS (proc)->raw_status_high = Qnil;
       XPROCESS (proc)->status = Fcons (Qexit, Fcons (make_number (256), Qnil));