diff options
author | Richard M. Stallman <rms@gnu.org> | 1994-06-25 22:35:28 +0000 |
---|---|---|
committer | Richard M. Stallman <rms@gnu.org> | 1994-06-25 22:35:28 +0000 |
commit | 39de1924483366963013b9dcd9141619e9bc0de4 (patch) | |
tree | d5bb444147d8ab0d82dbc13c2023cc3fd8fbe7f8 /src/process.c | |
parent | f6569ed381c9e91721efe5d5b35d55d2ddf8202d (diff) | |
download | emacs-39de1924483366963013b9dcd9141619e9bc0de4.tar.gz |
(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.
Diffstat (limited to 'src/process.c')
-rw-r--r-- | src/process.c | 178 |
1 files changed, 111 insertions, 67 deletions
diff --git a/src/process.c b/src/process.c index 66e21c1dc2e..9f740e4d026 100644 --- a/src/process.c +++ b/src/process.c @@ -2337,16 +2337,20 @@ send_process_trap () 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 @@ send_process (proc, buf, len) 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 @@ send_process (proc, buf, len) 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; -#endif + /* 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; } - /* 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) - Fprocess_send_eof (proc); - - signal (SIGPIPE, old_sigpipe); - if (rv < 0) + /* Send this batch, using one or more write calls. */ + while (this > 0) { - if (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 + || 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; + || 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)); } - report_file_error ("writing to process", Fcons (proc, Qnil)); + buf += rv; + len -= rv; + this -= rv; } - 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); - } + /* 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 else @@ -2469,7 +2512,8 @@ Output from processes can arrive in between bunches.") 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 @@ Output from processes can arrive in between bunches.") 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 @@ process_send_signal (process, signo, current_group, nomsg) { 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 @@ process_send_signal (process, signo, current_group, nomsg) { 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 @@ process_send_signal (process, signo, current_group, nomsg) { 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 @@ process_send_signal (process, signo, current_group, nomsg) #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 @@ text to PROCESS after you call this function.") } #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)); |