Subject: Re: bug#24531: process-send-string seems to truncate lines over 4096 characters

From: Spencer Baugh <[email-masked]>
Date: Fri, 21 Jul 2023 09:58:38 -0400

Eli Zaretskii <[email-masked]> writes:

>> Cc: [email-masked], [email-masked], [email-masked]
>> Date: Thu, 20 Jul 2023 17:21:53 -0400
>> From:  Stefan Monnier via "Bug reports for GNU Emacs,
>>  the Swiss army knife of text editors" <[email-masked]>
>> 
>> > I see that this bug is about 13 years old.  I think there's a pretty
>> > obvious solution: process-connection-type should default to nil.
>> 
>> In practice, that can't fly because it'll break existing code.
>
> Indeed.

I agree that we probably can't change the default.  However...

> A large portion (I think the majority, but I'm not sure) of
> Lisp programs that use bidirectional communications with async
> subprocesses actually _want_ the PTY interface, because they act as
> GUI front-ends to other programs.  Think "M-x term", "M-x gdb",
> inferior-python-mode, etc.  Even "M-x grep" and the likes need that
> because they rely on default color output, which only happens if Grep
> is connected to a terminal device.  Some of the Emacs features based
> on this don't work or don't work well on MS-Windows because Windows
> only supports pipes.  Do we really want such semi-broken behavior on
> GNU and Unix systems?
>
> The number of applications that (a) don't need console-like behavior
> and (b) need to send larger-than-4KB buffers to sub-processes is quite
> small.  Which is why this issue comes up only very rarely.  So making
> pipes the default will fix a very small fraction of applications, and
> break the vast majority -- clearly a wrong balance.

I see your point, but at the same time, the PTY interface on its own is
not sufficient to make these applications work, not at all.  Specialized
modes are necessary to make M-x term (to implement a terminal) and M-x
grep (to parse ANSI color codes) and other such programs work.  Running
things in a PTY without such specialized code doesn't give you anything,
AFAIK, because a PTY alone is far from enough to make the Emacs end
behave like a terminal.  So such programs need to be aware and careful
about such things anyway, and need additional infrastructure on top of
make-process.  So the default being "pty" gives such programs very
little: it doesn't save them any complexity.

Programs that just want to do some data processing with a subprocess, on
the other hand, work fine with just make-process alone, they need no
additional infrastructure, just process-send-string and reading directly
from the process buffer.  The default being "pipe" would take away a big
footgun for such programs, since it's easy to forget that and then have
a silently wrong program which will fail once you get large input.

>> Also I don't think either value of `process-connection-type` is a good
>> option.  IOW, I think that the connection type should be a mandatory
>> argument when creating an async process (except maybe for those
>> processes with no input/output).
>
> If we go that way, we should start by specifying :connection-type for
> all the uses of make-process and start-process we have in the core.
> It's a large job, but before it is done we cannot in good faith make
> such an incompatible transition.

I can do that.

However, what about my patch adding a warning about this to
process-send-string?  I think that is independently valuable.  Right now
we have no documentation of this problem...

>> So maybe, the default value of `process-connection-type` should be
>> `unspecified` and the process creation code should emit a warning when
>> creating a process whose connection type is `unspecified` (just
>> a warning, tho: it should then pursue execution as if that value was t,
>> as usual, so as to preserve compatibility).
>
> Something like that, yes.
>
> But I'm actually wondering how come modern Linux kernels don't have a
> way of lifting this restriction, or at least enlarging the limit so it
> makes the problem even less frequent.  Is there some inherent
> limitation that this must be 4KB and nothing larger?

Unfortunately from looking at Linux the limit of 4096 seems to be
hardcoded.