🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: gnu.emacs.bug
Article #98871

18.57: PROCESS-SEND-STRING of large strings fails (sometimes)

#98871
From: Kevin Layer
Date: Fri, 22 Feb 1991 01:52
91 lines
3607 bytes
I've noticed that 18.57 often gives me the error

	writing to process: no more processes: ....

when I write large amounts of data to a process created with
OPEN-NETWORK-STREAM.  (The "no more processes" is a red herring, since
this is what errno==11 means to emacs, but it really is errno==EAGAIN.)

This did not happen in 18.55.

I tracked it down to the fact that write(2) can return -1 and set
errno to EAGAIN when the write is to a file descriptor which is setup
for non-blocking IO--if the write would block, this would happen (I
don't understand why, but this is what the manual page sez).
I verified that errno was being set to EAGAIN and write() was
returning -1.

The additional code below, added to send_process() in process.c, seems
to fix the problem:

   send_process (proc, buf, len)
	Lisp_Object proc;
	char *buf;
	int len;
   {
     /* Don't use register vars; longjmp can lose them.  */
     int rv;
     unsigned char *procname = XSTRING (XPROCESS (proc)->name)->data;

     if (!NULL (XPROCESS (proc)->raw_status_low))
       update_status (XPROCESS (proc));
     if (! EQ (XPROCESS (proc)->status, Qrun))
       error ("Process %s not running", procname);

     if (!setjmp (send_process_frame))
       while (len > 0)
	 {
	   signal (SIGPIPE, send_process_trap);
	   rv = write (XFASTINT (XPROCESS (proc)->outfd), buf, len);
	   signal (SIGPIPE, SIG_DFL);
	   if (rv < 0)
	     {
>> #if defined(O_NDELAY) || defined(O_NONBLOCK)
>>	       if (errno == EAGAIN)
>>		 {
>>		   /* It would be nice to accept process output here,
>>		      but that is difficult.  For example, it could
>>		      garbage what we are sending if that is from a buffer.  */
>>		   immediate_quit = 1;
>>		   QUIT;
>>		   sleep (1);
>>		   immediate_quit = 0;
>>		   continue;
>>		 }
>> #endif
   #ifdef EWOULDBLOCK
	       if (errno == EWOULDBLOCK)
		 {
		   /* It would be nice to accept process output here,
		      but that is difficult.  For example, it could
		      garbage what we are sending if that is from a buffer.  */
		   immediate_quit = 1;
		   QUIT;
		   sleep (1);
		   immediate_quit = 0;
		   continue;
		 }
   #endif
	       report_file_error ("writing to process", Fcons (proc, Qnil));
	     }
	   buf += rv;
	   len -= rv;
	 }
     else
       {
	 XPROCESS (proc)->raw_status_low = Qnil;
	 XPROCESS (proc)->raw_status_high = Qnil;
	 XPROCESS (proc)->status = Fcons (Qexit, Fcons (make_number (256), Qnil));
	 XSETINT (XPROCESS (proc)->tick, ++process_tick);
	 deactivate_process (proc);
	 error ("SIGPIPE raised on process %s; closed it", procname);
       }
   }


As the comment for the EWOULDBLOCK case sez, this is not optimal, but
it does work.

Kevin Layer, Franz Inc.         1995 University Avenue, Suite 275
layer@Franz.COM (internet)      Berkeley, CA  94704
uunet!franz!layer (uucp)        Phone: (415) 548-3600; FAX: (415) 548-8253
Technical Details
Message-ID: <9102220152.AA06046@vapor.Franz.COM>
Path: arc1-ca.pugleaf.net!gmdzi!unido!fauern!ira.uka.de!sol.ctr.columbia.edu!caen!sdd.hp.com!usc!rutgers!tut.cis.ohio-state.edu!unreplyable!garbage

Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: fb2f1,797fb98ace93f553
X-Google-Attributes: gidfb2f1,public
X-Google-ArrivalTime: 1991-02-22 16:04:10 PST
Path: arc1-ca.pugleaf.net!gmdzi!unido!fauern!ira.uka.de!sol.ctr.columbia.edu!caen!sdd.hp.com!usc!rutgers!tut.cis.ohio-state.edu!unreplyable!garbage
From: layer@franz.com (Kevin Layer)
Newsgroups: gnu.emacs.bug
Subject: 18.57: PROCESS-SEND-STRING of large strings fails (sometimes)
Message-ID: <9102220152.AA06046@vapor.Franz.COM>
Date: 22 Feb 91 01:52:29 GMT
Sender: daemon@tut.cis.ohio-state.edu
Distribution: gnu
Organization: GNUs Not Usenet
Lines: 91
Approved: bug-gnu-emacs@prep.ai.mit.edu