Subject: Re: bug#47299: 27.1; emacs --batch on MS-Windows does not immediately display `print'ed lines when invoked outside of the Command Prompt

From: Eli Zaretskii <[email-masked]>
Date: Tue, 23 Mar 2021 13:33:37 +0200

> From: Ioannis Kappas <[email-masked]>
> Date: Sun, 21 Mar 2021 21:06:28 +0000
> 
> Similar to bug#46388 (27.1; emacs -batch does not output messages
> immediately when invoked outside of the command prompt) the issue
> stems from the expectation that stdout buffering should behave like in
> POSIX systems, which is not necessarily the case on 'windows-nt.

How stdout is buffered when it is not connected to a console device is
system-dependent, and any program that relies on a specific buffering
has a bug.

> stdout on windows-nt is either always unbuffered (when attached to the
> console) or fully-buffered (otherwise), while on 'gnu/linux I have
> experimentally found it to be line-buffered when invoked from the
> terminal or from another program such as Emacs M-x shell. I consider 
> this line-buffered behavior of 'gnu/linux to fall under the "interactive 
> device" of the standard mentioned above.
> 
> (When stdout is redirected to a file on 'gnu/linux, I found stdout to
> be fully-buffered having a 4096 buffer size).
> 
> (See standard-streams-test report @
> https://github.com/ikappaki/standard-streams-test for a tool that was
> written to investigate the buffering behavior of stderr on MS-Windows,
> i.e. unbuffered when attached to console, fully buffered
> otherwise. The same tool was modified to test stdout on a similar
> manner, which yielded exactly the same result).
> 
> Thus the difference in behavior as described in the bug report is due
> to stdout on 'windows-nt being fully buffered, rather than being line
> buffered as in 'gnu/linux.

The difference you observe is because on Windows we use pipes to
communicate with subprocesses, while on Posix platforms we by default
use PTYs, which are a kind of console device.  You can try using pipes
on GNU/Linux (by setting the process-connection-type variable), and
you will then see that the behavior on these two systems is similar,
not different.

> As such, two likely fixes are presented below, one that flushes stdout
> on a newline only iff stdout is attached to a pipe (as if it is the
> "interactive device" of the POSIX standard) but staying fully buffered
> otherwise (e.g. when output was redirected to a pipe or a socket), while
> the other fix always flushing stdout on a newline (a much simpler and less
> involved solution -- similar to the one in bug#46388 suggested by Mr. Eggert
> -- though not optimized for redirections to files).

I'm against both these changes.  Unconditionally flushing stdout each
newline is a non-starter, because it will slow down Lisp programs that
aren't interactive and need to send large buffers both ways.  At this
low level it cannot be known whether "the other end" of the pipe
expects interactivity or not.

What I can offer is to add a Lisp function to flush the stdout stream.
Lisp programs that need to provide interactive experience could call
that function where appropriate.

I don't see any other solution; doing what we do with stderr is
certainly inappropriate.

Thanks.