aboutsummaryrefslogtreecommitdiffstats
path: root/src/process.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/process.c')
-rw-r--r--src/process.c137
1 files changed, 104 insertions, 33 deletions
diff --git a/src/process.c b/src/process.c
index 4d59ff0d452..cb89cae99fe 100644
--- a/src/process.c
+++ b/src/process.c
@@ -93,8 +93,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
93#include "systty.h" 93#include "systty.h"
94 94
95#include "window.h" 95#include "window.h"
96#include "buffer.h"
97#include "character.h" 96#include "character.h"
97#include "buffer.h"
98#include "coding.h" 98#include "coding.h"
99#include "process.h" 99#include "process.h"
100#include "frame.h" 100#include "frame.h"
@@ -638,6 +638,7 @@ make_process (Lisp_Object name)
638 p->status = Qrun; 638 p->status = Qrun;
639 p->mark = Fmake_marker (); 639 p->mark = Fmake_marker ();
640 p->kill_without_query = 0; 640 p->kill_without_query = 0;
641 p->write_queue = Qnil;
641 642
642#ifdef ADAPTIVE_READ_BUFFERING 643#ifdef ADAPTIVE_READ_BUFFERING
643 p->adaptive_read_buffering = 0; 644 p->adaptive_read_buffering = 0;
@@ -5371,6 +5372,78 @@ send_process_trap (int ignore)
5371 longjmp (send_process_frame, 1); 5372 longjmp (send_process_frame, 1);
5372} 5373}
5373 5374
5375/* In send_process, when a write fails temporarily,
5376 wait_reading_process_output is called. It may execute user code,
5377 e.g. timers, that attempts to write new data to the same process.
5378 We must ensure that data is sent in the right order, and not
5379 interspersed half-completed with other writes (Bug#10815). This is
5380 handled by the write_queue element of struct process. It is a list
5381 with each entry having the form
5382
5383 (string . (offset . length))
5384
5385 where STRING is a lisp string, OFFSET is the offset into the
5386 string's byte sequence from which we should begin to send, and
5387 LENGTH is the number of bytes left to send. */
5388
5389/* Create a new entry in write_queue.
5390 INPUT_OBJ should be a buffer, string Qt, or Qnil.
5391 BUF is a pointer to the string sequence of the input_obj or a C
5392 string in case of Qt or Qnil. */
5393
5394static void
5395write_queue_push (struct Lisp_Process *p, Lisp_Object input_obj,
5396 const char *buf, ptrdiff_t len, int front)
5397{
5398 ptrdiff_t offset;
5399 Lisp_Object entry, obj;
5400
5401 if (STRINGP (input_obj))
5402 {
5403 offset = buf - SSDATA (input_obj);
5404 obj = input_obj;
5405 }
5406 else
5407 {
5408 offset = 0;
5409 obj = make_unibyte_string (buf, len);
5410 }
5411
5412 entry = Fcons (obj, Fcons (make_number (offset), make_number (len)));
5413
5414 if (front)
5415 p->write_queue = Fcons (entry, p->write_queue);
5416 else
5417 p->write_queue = nconc2 (p->write_queue, Fcons (entry, Qnil));
5418}
5419
5420/* Remove the first element in the write_queue of process P, put its
5421 contents in OBJ, BUF and LEN, and return non-zero. If the
5422 write_queue is empty, return zero. */
5423
5424static int
5425write_queue_pop (struct Lisp_Process *p, Lisp_Object *obj,
5426 const char **buf, ptrdiff_t *len)
5427{
5428 Lisp_Object entry, offset_length;
5429 ptrdiff_t offset;
5430
5431 if (NILP (p->write_queue))
5432 return 0;
5433
5434 entry = XCAR (p->write_queue);
5435 p->write_queue = XCDR (p->write_queue);
5436
5437 *obj = XCAR (entry);
5438 offset_length = XCDR (entry);
5439
5440 *len = XINT (XCDR (offset_length));
5441 offset = XINT (XCAR (offset_length));
5442 *buf = SSDATA (*obj) + offset;
5443
5444 return 1;
5445}
5446
5374/* Send some data to process PROC. 5447/* Send some data to process PROC.
5375 BUF is the beginning of the data; LEN is the number of characters. 5448 BUF is the beginning of the data; LEN is the number of characters.
5376 OBJECT is the Lisp object that the data comes from. If OBJECT is 5449 OBJECT is the Lisp object that the data comes from. If OBJECT is
@@ -5389,11 +5462,8 @@ send_process (volatile Lisp_Object proc, const char *volatile buf,
5389 struct Lisp_Process *p = XPROCESS (proc); 5462 struct Lisp_Process *p = XPROCESS (proc);
5390 ssize_t rv; 5463 ssize_t rv;
5391 struct coding_system *coding; 5464 struct coding_system *coding;
5392 struct gcpro gcpro1;
5393 void (*volatile old_sigpipe) (int); 5465 void (*volatile old_sigpipe) (int);
5394 5466
5395 GCPRO1 (object);
5396
5397 if (p->raw_status_new) 5467 if (p->raw_status_new)
5398 update_status (p); 5468 update_status (p);
5399 if (! EQ (p->status, Qrun)) 5469 if (! EQ (p->status, Qrun))
@@ -5505,22 +5575,37 @@ send_process (volatile Lisp_Object proc, const char *volatile buf,
5505 if (!setjmp (send_process_frame)) 5575 if (!setjmp (send_process_frame))
5506 { 5576 {
5507 p = XPROCESS (proc); /* Repair any setjmp clobbering. */ 5577 p = XPROCESS (proc); /* Repair any setjmp clobbering. */
5508
5509 process_sent_to = proc; 5578 process_sent_to = proc;
5510 while (len > 0) 5579
5580 /* If there is already data in the write_queue, put the new data
5581 in the back of queue. Otherwise, ignore it. */
5582 if (!NILP (p->write_queue))
5583 write_queue_push (p, object, buf, len, 0);
5584
5585 do /* while !NILP (p->write_queue) */
5511 { 5586 {
5512 ptrdiff_t this = len; 5587 ptrdiff_t cur_len = -1;
5588 const char *cur_buf;
5589 Lisp_Object cur_object;
5590
5591 /* If write_queue is empty, ignore it. */
5592 if (!write_queue_pop (p, &cur_object, &cur_buf, &cur_len))
5593 {
5594 cur_len = len;
5595 cur_buf = buf;
5596 cur_object = object;
5597 }
5513 5598
5514 /* Send this batch, using one or more write calls. */ 5599 while (cur_len > 0)
5515 while (this > 0)
5516 { 5600 {
5601 /* Send this batch, using one or more write calls. */
5517 ptrdiff_t written = 0; 5602 ptrdiff_t written = 0;
5518 int outfd = p->outfd; 5603 int outfd = p->outfd;
5519 old_sigpipe = (void (*) (int)) signal (SIGPIPE, send_process_trap); 5604 old_sigpipe = (void (*) (int)) signal (SIGPIPE, send_process_trap);
5520#ifdef DATAGRAM_SOCKETS 5605#ifdef DATAGRAM_SOCKETS
5521 if (DATAGRAM_CHAN_P (outfd)) 5606 if (DATAGRAM_CHAN_P (outfd))
5522 { 5607 {
5523 rv = sendto (outfd, buf, this, 5608 rv = sendto (outfd, cur_buf, cur_len,
5524 0, datagram_address[outfd].sa, 5609 0, datagram_address[outfd].sa,
5525 datagram_address[outfd].len); 5610 datagram_address[outfd].len);
5526 if (0 <= rv) 5611 if (0 <= rv)
@@ -5537,10 +5622,10 @@ send_process (volatile Lisp_Object proc, const char *volatile buf,
5537 { 5622 {
5538#ifdef HAVE_GNUTLS 5623#ifdef HAVE_GNUTLS
5539 if (p->gnutls_p) 5624 if (p->gnutls_p)
5540 written = emacs_gnutls_write (p, buf, this); 5625 written = emacs_gnutls_write (p, cur_buf, cur_len);
5541 else 5626 else
5542#endif 5627#endif
5543 written = emacs_write (outfd, buf, this); 5628 written = emacs_write (outfd, cur_buf, cur_len);
5544 rv = (written ? 0 : -1); 5629 rv = (written ? 0 : -1);
5545#ifdef ADAPTIVE_READ_BUFFERING 5630#ifdef ADAPTIVE_READ_BUFFERING
5546 if (p->read_output_delay > 0 5631 if (p->read_output_delay > 0
@@ -5568,8 +5653,6 @@ send_process (volatile Lisp_Object proc, const char *volatile buf,
5568 that may allow the program 5653 that may allow the program
5569 to finish doing output and read more. */ 5654 to finish doing output and read more. */
5570 { 5655 {
5571 ptrdiff_t offset = 0;
5572
5573#ifdef BROKEN_PTY_READ_AFTER_EAGAIN 5656#ifdef BROKEN_PTY_READ_AFTER_EAGAIN
5574 /* A gross hack to work around a bug in FreeBSD. 5657 /* A gross hack to work around a bug in FreeBSD.
5575 In the following sequence, read(2) returns 5658 In the following sequence, read(2) returns
@@ -5595,35 +5678,25 @@ send_process (volatile Lisp_Object proc, const char *volatile buf,
5595 } 5678 }
5596#endif /* BROKEN_PTY_READ_AFTER_EAGAIN */ 5679#endif /* BROKEN_PTY_READ_AFTER_EAGAIN */
5597 5680
5598 /* Running filters might relocate buffers or strings. 5681 /* Put what we should have written in wait_queue. */
5599 Arrange to relocate BUF. */ 5682 write_queue_push (p, cur_object, cur_buf, cur_len, 1);
5600 if (BUFFERP (object))
5601 offset = BUF_PTR_BYTE_POS (XBUFFER (object),
5602 (unsigned char *) buf);
5603 else if (STRINGP (object))
5604 offset = buf - SSDATA (object);
5605
5606#ifdef EMACS_HAS_USECS 5683#ifdef EMACS_HAS_USECS
5607 wait_reading_process_output (0, 20000, 0, 0, Qnil, NULL, 0); 5684 wait_reading_process_output (0, 20000, 0, 0, Qnil, NULL, 0);
5608#else 5685#else
5609 wait_reading_process_output (1, 0, 0, 0, Qnil, NULL, 0); 5686 wait_reading_process_output (1, 0, 0, 0, Qnil, NULL, 0);
5610#endif 5687#endif
5611 5688 /* Reread queue, to see what is left. */
5612 if (BUFFERP (object)) 5689 break;
5613 buf = (char *) BUF_BYTE_ADDRESS (XBUFFER (object),
5614 offset);
5615 else if (STRINGP (object))
5616 buf = offset + SSDATA (object);
5617 } 5690 }
5618 else 5691 else
5619 /* This is a real error. */ 5692 /* This is a real error. */
5620 report_file_error ("writing to process", Fcons (proc, Qnil)); 5693 report_file_error ("writing to process", Fcons (proc, Qnil));
5621 } 5694 }
5622 buf += written; 5695 cur_buf += written;
5623 len -= written; 5696 cur_len -= written;
5624 this -= written;
5625 } 5697 }
5626 } 5698 }
5699 while (!NILP (p->write_queue));
5627 } 5700 }
5628 else 5701 else
5629 { 5702 {
@@ -5636,8 +5709,6 @@ send_process (volatile Lisp_Object proc, const char *volatile buf,
5636 deactivate_process (proc); 5709 deactivate_process (proc);
5637 error ("SIGPIPE raised on process %s; closed it", SDATA (p->name)); 5710 error ("SIGPIPE raised on process %s; closed it", SDATA (p->name));
5638 } 5711 }
5639
5640 UNGCPRO;
5641} 5712}
5642 5713
5643DEFUN ("process-send-region", Fprocess_send_region, Sprocess_send_region, 5714DEFUN ("process-send-region", Fprocess_send_region, Sprocess_send_region,