summaryrefslogtreecommitdiff
path: root/src/process.c
diff options
context:
space:
mode:
authorRichard M. Stallman <rms@gnu.org>1994-06-25 22:35:28 +0000
committerRichard M. Stallman <rms@gnu.org>1994-06-25 22:35:28 +0000
commit39de1924483366963013b9dcd9141619e9bc0de4 (patch)
treed5bb444147d8ab0d82dbc13c2023cc3fd8fbe7f8 /src/process.c
parentf6569ed381c9e91721efe5d5b35d55d2ddf8202d (diff)
downloademacs-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.c178
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));