Mercurial > emacs
changeset 8063:30861f2f4f84
(send_process): Major rewrite.
Don't put in a C-d unless a single line is too long.
Read process input whenever output gets stuck.
Relocate BUF if we read input. New arg OBJECT.
Fprocess_send_region, Fprocess_send_string, process_send_signal)
(Fprocess_send_eof): Pass new arg OBJECT.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Sat, 25 Jun 1994 22:35:28 +0000 |
parents | ad595e4e165c |
children | d04a39ce4f1d |
files | src/process.c |
diffstat | 1 files changed, 114 insertions(+), 70 deletions(-) [+] |
line wrap: on
line diff
--- a/src/process.c Sat Jun 25 22:34:52 1994 +0000 +++ b/src/process.c Sat Jun 25 22:35:28 1994 +0000 @@ -2337,16 +2337,20 @@ longjmp (send_process_frame, 1); } -send_process (proc, buf, len) +/* Send some data to process PROC. + BUF is the beginning of the data; LEN is the number of characters. + OBJECT is the Lisp object that the data comes from. */ + +send_process (proc, buf, len, object) Lisp_Object proc; char *buf; int len; + Lisp_Object object; { /* Don't use register vars; longjmp can lose them. */ int rv; unsigned char *procname = XSTRING (XPROCESS (proc)->name)->data; - #ifdef VMS struct Lisp_Process *p = XPROCESS (proc); VMS_PROC_STUFF *vs, *get_vms_process_pointer(); @@ -2364,6 +2368,21 @@ else if (write_to_vms_process (vs, buf, len)) ; #else + + if (pty_max_bytes == 0) + { +#if defined (HAVE_FPATHCONF) && defined (_PC_MAX_CANON) + pty_max_bytes = fpathconf (XFASTINT (XPROCESS (proc)->outfd), + _PC_MAX_CANON); + if (pty_max_bytes < 0) + pty_max_bytes = 250; +#else + pty_max_bytes = 250; +#endif + /* Deduct one, to leave space for the eof. */ + pty_max_bytes--; + } + if (!setjmp (send_process_frame)) while (len > 0) { @@ -2371,65 +2390,89 @@ SIGTYPE (*old_sigpipe)(); int flush_pty = 0; - if (pty_max_bytes == 0) + /* 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)) { -#if defined (HAVE_FPATHCONF) && defined (_PC_MAX_CANON) - pty_max_bytes = fpathconf (XFASTINT (XPROCESS (proc)->outfd), - _PC_MAX_CANON); - if (pty_max_bytes < 0) - pty_max_bytes = 250; -#else - pty_max_bytes = 250; + /* 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; + char *ptr = buf; + 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 = write (XINT (XPROCESS (proc)->outfd), buf, this); + signal (SIGPIPE, old_sigpipe); + + if (rv < 0) + { + if (0 +#ifdef EWOULDBLOCK + || errno == EWOULDBLOCK #endif +#ifdef 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; + + /* Running filters might relocate buffers or strings. + Arrange to relocate BUF. */ + if (BUFFERP (object)) + offset = BUF_PTR_CHAR_POS (XBUFFER (object), + (unsigned char *) buf); + else if (STRINGP (object)) + offset = buf - (char *) XSTRING (object)->data; + + XFASTINT (zero) = 0; + wait_reading_process_input (1, 0, zero, 0); + + if (BUFFERP (object)) + buf = (char *) BUF_CHAR_ADDRESS (XBUFFER (object), offset); + else if (STRINGP (object)) + buf = offset + (char *) 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; } - /* Don't send more than pty_max_bytes bytes at a time. */ - /* Subtract 1 to leave room for the EOF. */ - if (this >= pty_max_bytes && !NILP (XPROCESS (proc)->pty_flag)) - this = pty_max_bytes - 1; - - old_sigpipe = (SIGTYPE (*) ()) signal (SIGPIPE, send_process_trap); - rv = write (XINT (XPROCESS (proc)->outfd), buf, this); - /* If we sent just part of the string, put in an EOF to force it through, before we send the rest. */ - if (this < len) + if (len > 0) Fprocess_send_eof (proc); - - signal (SIGPIPE, old_sigpipe); - if (rv < 0) - { - if (0 -#ifdef EWOULDBLOCK - || errno == EWOULDBLOCK -#endif -#ifdef EAGAIN - || errno == EAGAIN -#endif - ) - { - /* 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; - } - report_file_error ("writing to process", Fcons (proc, Qnil)); - } - buf += rv; - len -= rv; - /* Allow input from processes between bursts of sending. - Otherwise things may get stopped up. */ - if (len > 0) - { - Lisp_Object zero; - - XFASTINT (zero) = 0; - wait_reading_process_input (-1, 0, zero, 0); - } } #endif else @@ -2469,7 +2512,8 @@ move_gap (start); start1 = XINT (start); - send_process (proc, &FETCH_CHAR (start1), XINT (end) - XINT (start)); + send_process (proc, &FETCH_CHAR (start1), XINT (end) - XINT (start), + Fcurrent_buffer ()); return Qnil; } @@ -2488,7 +2532,7 @@ Lisp_Object proc; CHECK_STRING (string, 1); proc = get_process (process); - send_process (proc, XSTRING (string)->data, XSTRING (string)->size); + send_process (proc, XSTRING (string)->data, XSTRING (string)->size, string); return Qnil; } @@ -2544,20 +2588,20 @@ { case SIGINT: tcgetattr (XINT (p->infd), &t); - send_process (proc, &t.c_cc[VINTR], 1); + send_process (proc, &t.c_cc[VINTR], 1, Qnil); return; case SIGQUIT: tcgetattr (XINT (p->infd), &t); - send_process (proc, &t.c_cc[VQUIT], 1); + send_process (proc, &t.c_cc[VQUIT], 1, Qnil); return; case SIGTSTP: tcgetattr (XINT (p->infd), &t); #if defined (VSWTCH) && !defined (PREFER_VSUSP) - send_process (proc, &t.c_cc[VSWTCH], 1); + send_process (proc, &t.c_cc[VSWTCH], 1, Qnil); #else - send_process (proc, &t.c_cc[VSUSP], 1); + send_process (proc, &t.c_cc[VSUSP], 1, Qnil); #endif return; } @@ -2575,16 +2619,16 @@ { case SIGINT: ioctl (XINT (p->infd), TIOCGETC, &c); - send_process (proc, &c.t_intrc, 1); + send_process (proc, &c.t_intrc, 1, Qnil); return; case SIGQUIT: ioctl (XINT (p->infd), TIOCGETC, &c); - send_process (proc, &c.t_quitc, 1); + send_process (proc, &c.t_quitc, 1, Qnil); return; #ifdef SIGTSTP case SIGTSTP: ioctl (XINT (p->infd), TIOCGLTC, &lc); - send_process (proc, &lc.t_suspc, 1); + send_process (proc, &lc.t_suspc, 1, Qnil); return; #endif /* ! defined (SIGTSTP) */ } @@ -2599,16 +2643,16 @@ { case SIGINT: ioctl (XINT (p->infd), TCGETA, &t); - send_process (proc, &t.c_cc[VINTR], 1); + send_process (proc, &t.c_cc[VINTR], 1, Qnil); return; case SIGQUIT: ioctl (XINT (p->infd), TCGETA, &t); - send_process (proc, &t.c_cc[VQUIT], 1); + send_process (proc, &t.c_cc[VQUIT], 1, Qnil); return; #ifdef SIGTSTP case SIGTSTP: ioctl (XINT (p->infd), TCGETA, &t); - send_process (proc, &t.c_cc[VSWTCH], 1); + send_process (proc, &t.c_cc[VSWTCH], 1, Qnil); return; #endif /* ! defined (SIGTSTP) */ } @@ -2669,12 +2713,12 @@ #endif /* ! defined (SIGCONT) */ case SIGINT: #ifdef VMS - send_process (proc, "\003", 1); /* ^C */ + send_process (proc, "\003", 1, Qnil); /* ^C */ goto whoosh; #endif case SIGQUIT: #ifdef VMS - send_process (proc, "\031", 1); /* ^Y */ + send_process (proc, "\031", 1, Qnil); /* ^Y */ goto whoosh; #endif case SIGKILL: @@ -2815,10 +2859,10 @@ } #else /* did not do TOICREMOTE */ #ifdef VMS - send_process (proc, "\032", 1); /* ^z */ + send_process (proc, "\032", 1, Qnil); /* ^z */ #else if (!NILP (XPROCESS (proc)->pty_flag)) - send_process (proc, "\004", 1); + send_process (proc, "\004", 1, Qnil); else { close (XINT (XPROCESS (proc)->outfd));