From: Lars Ingebrigtsen <larsi@gnus.org>
To: Hendrik Tews <tews@os.inf.tu-dresden.de>
Cc: 12440@debbugs.gnu.org
Subject: bug#12440: 24.2; process-send-string only sends 4K for long strings
Date: Mon, 07 Oct 2019 16:53:24 +0200 [thread overview]
Message-ID: <87ftk47gkb.fsf@gnus.org> (raw)
In-Reply-To: <6xzk4tvuof.fsf@blau.inf.tu-dresden.de> (Hendrik Tews's message of "Fri, 14 Sep 2012 11:08:00 +0200")
Hendrik Tews <tews@os.inf.tu-dresden.de> writes:
> in Emacs 24.2, the following code
>
> (let* ((process-connection-type t)
> (process (start-process "cat" (current-buffer) "cat")))
> (process-send-string process (format "%s\n" (make-string 6000 ?a))))
>
> inserts only 4095 characters in the current buffer. Setting
> process-connection-type to nil will insert all characters.
I can confirm that this bug is still present in Emacs 27.
It's odd that this doesn't cause more problems than it does in practice,
but I guess it's rare that we talk to processes this way.
The bug was apparently introduced by the patch below, but I have to
admit when reading it, I don't quite understand what's going on...
commit 2b0a91e78f83fb446cc38efb99399e83ad2cded3
Author: Stefan Monnier <monnier@iro.umontreal.ca>
Date: Mon Apr 12 22:07:48 2010 -0400
Try to solve the problem of spurious EOF chars in long lines of text
sent to interactive subprocesses.
* sysdep.c (child_setup_tty): Do not enable ICANON any more.
(system_process_attributes): Remove unused var `ttotal'.
* process.c (send_process): Don't bother breaking long line with EOF
chars when talking to ttys any more.
(wait_reading_process_output): Output a warning when called in such
a way that it could block without being interruptible.
diff --git a/src/ChangeLog b/src/ChangeLog
index ad88dc8311..f9567b1308 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,14 @@
2010-04-13 Stefan Monnier <monnier@iro.umontreal.ca>
+ Try to solve the problem of spurious EOF chars in long lines of text
+ sent to interactive subprocesses.
+ * sysdep.c (child_setup_tty): Do not enable ICANON any more.
+ (system_process_attributes): Remove unused var `ttotal'.
+ * process.c (send_process): Don't bother breaking long line with EOF
+ chars when talking to ttys any more.
+ (wait_reading_process_output): Output a warning when called in such
+ a way that it could block without being interruptible.
+
Try to detect file modification within the same second.
* buffer.h (struct buffer): New field modtime_size.
* buffer.c (reset_buffer): Initialize it.
diff --git a/src/process.c b/src/process.c
index 34aa2c4fcf..7e8f4cc57b 100644
--- a/src/process.c
+++ b/src/process.c
@@ -4643,6 +4643,10 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
FD_ZERO (&Connecting);
#endif
+ if (time_limit == 0 && wait_proc && !NILP (Vinhibit_quit)
+ && !(CONSP (wait_proc->status) && EQ (XCAR (wait_proc->status), Qexit)))
+ message ("Blocking call to accept-process-output with quit inhibited!!");
+
/* If wait_proc is a process to watch, set wait_channel accordingly. */
if (wait_proc != NULL)
wait_channel = wait_proc->infd;
@@ -5768,34 +5772,6 @@ send_process (proc, buf, len, object)
{
int this = len;
- /* Decide how much data we can send in one batch.
- Long lines need to be split into multiple batches. */
- if (p->pty_flag)
- {
- /* 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;
- unsigned char *ptr = (unsigned char *) buf;
- unsigned char *end = (unsigned char *) 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)
{
@@ -5899,11 +5875,6 @@ send_process (proc, buf, len, object)
len -= rv;
this -= rv;
}
-
- /* If we sent just part of the string, put in an EOF (C-d)
- to force it through, before we send the rest. */
- if (len > 0)
- Fprocess_send_eof (proc);
}
}
else
diff --git a/src/sysdep.c b/src/sysdep.c
index 37e7dfbaf9..506af23ef3 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -529,8 +529,6 @@ child_setup_tty (out)
#endif
s.main.c_oflag &= ~TAB3; /* Disable tab expansion */
s.main.c_cflag = (s.main.c_cflag & ~CSIZE) | CS8; /* Don't strip 8th bit */
- s.main.c_lflag |= ICANON; /* Enable erase/kill and eof processing */
- s.main.c_cc[VEOF] = 04; /* insure that EOF is Control-D */
s.main.c_cc[VERASE] = CDISABLE; /* disable erase processing */
s.main.c_cc[VKILL] = CDISABLE; /* disable kill processing */
@@ -560,7 +558,6 @@ child_setup_tty (out)
/* rms: Formerly it set s.main.c_cc[VINTR] to 0377 here
unconditionally. Then a SIGNALS_VIA_CHARACTERS conditional
would force it to 0377. That looks like duplicated code. */
- s.main.c_cc[VEOL] = CDISABLE;
s.main.c_cflag = (s.main.c_cflag & ~CBAUD) | B9600; /* baud rate sanity */
#endif /* AIX */
@@ -573,6 +570,18 @@ child_setup_tty (out)
s.main.sg_kill = 0377;
s.lmode = LLITOUT | s.lmode; /* Don't strip 8th bit */
+ /* We used to enable ICANON (and set VEOF to 04), but this leads to
+ problems where process.c wants to send EOFs every once in a while
+ to force the output, which leads to weird effects when the
+ subprocess has disabled ICANON and ends up seeing those spurious
+ extra EOFs. So we don't send EOFs any more in
+ process.c:send_process, and instead we disable ICANON by default,
+ so if a subsprocess sets up ICANON, it's his problem (or the Elisp
+ package that talks to it) to deal with lines that are too long. */
+ s.main.c_lflag &= ~ICANON; /* Disable line editing and eof processing */
+ s.main.c_cc[VMIN] = 1;
+ s.main.c_cc[VTIME] = 0;
+
#endif /* not HAVE_TERMIO */
EMACS_SET_TTY (out, &s, 0);
@@ -3344,7 +3353,7 @@ system_process_attributes (Lisp_Object pid)
unsigned long minflt, majflt, cminflt, cmajflt, vsize;
time_t sec;
unsigned usec;
- EMACS_TIME tnow, tstart, tboot, telapsed,ttotal;
+ EMACS_TIME tnow, tstart, tboot, telapsed;
double pcpu, pmem;
Lisp_Object attrs = Qnil;
Lisp_Object cmd_str, decoded_cmd, tem;
--
(domestic pets only, the antidote for overdose, milk.)
bloggy blog: http://lars.ingebrigtsen.no
next prev parent reply other threads:[~2019-10-07 14:53 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-09-14 9:08 bug#12440: 24.2; process-send-string only sends 4K for long strings Hendrik Tews
2019-10-07 14:53 ` Lars Ingebrigtsen [this message]
2019-10-07 16:45 ` Eli Zaretskii
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87ftk47gkb.fsf@gnus.org \
--to=larsi@gnus.org \
--cc=12440@debbugs.gnu.org \
--cc=tews@os.inf.tu-dresden.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.