Package: emacs;
Reported by: Ioannis Kappas <ioannis.kappas <at> gmail.com>
Date: Mon, 8 Feb 2021 21:22:02 UTC
Severity: normal
Found in version 27.1
Done: Paul Eggert <eggert <at> cs.ucla.edu>
Bug is archived. No further changes may be made.
Message #17 received at 46388 <at> debbugs.gnu.org (full text, mbox):
From: Ioannis Kappas <ioannis.kappas <at> gmail.com> To: Eli Zaretskii <eliz <at> gnu.org> Cc: 46388 <at> debbugs.gnu.org Subject: Re: bug#46388: 27.1; emacs -batch does not output messages immediately when invoked outside of the command prompt Date: Tue, 9 Feb 2021 20:15:34 +0000
Hi Eli, thanks for taking the time to look into this bug report! (my apologies for the long reply that follows) I understand there are two concerns: 1. stderr could be connected to a file, in which case we do want it to be buffered for efficiency. 2. If stderr is forced to unbuffered, this will make it behave differently from posix systems. I had a look around #2 in the posix standard. The section under stderr, stdin, stdout at https://pubs.opengroup.org/onlinepubs/9699919799/functions/stdin.html reads: """At program start-up, three streams shall be predefined and need not be opened explicitly: standard input (for reading conventional input), standard output (for writing conventional output), and standard error (for writing diagnostic output). When opened, the standard error stream is not fully buffered; the standard input and standard output streams are fully buffered if and only if the stream can be determined not to refer to an interactive device. """ Thus, at open (I assume this to mean at program invocation), the posix spec suggests that stderr is not "fully buffered". The section under setvbuf under the same spec at https://pubs.opengroup.org/onlinepubs/009695399/functions/setvbuf.html differentiates between the three different buffering regimes: """ {_IOFBF} shall cause input/output to be fully buffered. {_IOLBF} shall cause input/output to be line buffered. {_IONBF} shall cause input/output to be unbuffered. """ So, if stderr is not "fully buffered", it can be either "line buffered" or "unbuffered". (This does make some sense to me, since stderr is usually for urgent messages and thus any messages are needed to be readily available to the recipients. Fully buffered defeats the purpose?). How does Linux conforms to the posix standard? Having a look at stderr(3) in the foot note, it reads: """ Notes The stream stderr is unbuffered. The stream stdout is line-buffered when it points to a terminal. Partial lines will not appear until fflush(3) or exit(3) is called, or a newline is printed. This can produce unexpected results, especially with debugging output. The buffering mode of the standard streams (or any other stream) can be changed using the setbuf(3) or setvbuf(3) call. Note that in case stdin is associated with a terminal, there may also be input buffering in the terminal driver, entirely unrelated to stdio buffering. (Indeed, normally terminal input is line buffered in the kernel.) This kernel input handling can be modified using calls like tcsetattr(3); see also stty(1), and termios(3). """ Which appears to suggests that stderr always starts as "unbuffered" when a program starts, irrespective of how it was invoked? If so, then it conforms to the posix standard of not being "fully buffered" at open, by always being "unbuffered" (this behavior has also been seen in all tests mentioned so far). If this is the case, then the desired buffering efficiency as mentioned in concern #1, does not exist in Linux. I have also conducted an additional test to check Linux behavior when stderr is redirected to a file (using the same c program that I mentioned in the original bug report): : ./fwrite-a-character-to-stderr-and-sleep-for-two-seconds 2> io.txt while at around the same time in another terminal I read from that file: : cat io.txt The result is that cat outputs "t", the character the fwrite program has written to stderr, i.e. the io.txt file, proving that no buffering has being utilized by the fwrite process. The result is the same when I try the same experiment from inside an emacs shell. Back to the windows behavior at hand, the simple test conducted with fwrite as the bug report mentioned, has a 2048 bytes associated with it which I will consider it to be categorized as "fully buffered", which brings it further away to the posix standard and even more further away from Linux being on the other end (always unbuffered). (There is also this thread on stackoverlow quoting the following from comp.lang.c: """ Unix convention is that stdin and stdout are line-buffered when associated with a terminal, and fully-buffered (aka block-buffered) otherwise. stderr is always unbuffered. """ emphasis on *Unix convention ... stderr .. always unbuffered*, though it will be difficult to confirm this claim for all *nices) Thus, if we assume the above interpretation given so far to be correct, then both of the concerns can be addressed as such: For #1, we can use Linux as a benchmark of established behavior. There is no efficiency in Linux with regards to buffering when stderr is redirected to files, thus having emacs batch mode on windows being on par with Linux should be good enough in this respect. For #2, emacs batch stderr behavior when invoked from outside the command line is not compatible with the posix standard, since it uses "fully buffered" mode, which actually makes it behave very differently from Linux (which is posix compliant by always having stderr as being unbuffered). Thus, the suggested patch actually addresses this concern, rather than invalidating it. (I understand ConPTY is the long term solution looking for a hacker, though I still do suppose the current behavior on windows is odd and needs to be addressed until that time). Sincerely On Tue, Feb 9, 2021 at 5:36 AM Eli Zaretskii <eliz <at> gnu.org> wrote: > > > From: Ioannis Kappas <ioannis.kappas <at> gmail.com> > > Date: Mon, 8 Feb 2021 21:42:09 +0000 > > > > A solution thus to correct this behavior in emacs -batch on > > windows-nt would be to check if it is connected to the console, > > and when not, set stderr mode to unbuffered. > > Thanks for the analysis and the patch proposal. However, I don't > think this is a good idea. For starters, stderr could be connected to > a file, in which case we do want it to be buffered. More generally, > stderr could be used for something other than outputting urgent > messages, in which case making it unbuffered will make I/O less > efficient for no good reason. And this would make Emacs on Windows > behave differently from Posix systems, which is also a downside. > > I think a much better way forward in this area is to teach Emacs to > use the Pseudo Consoles introduced in recent Windows versions. That > would allow us to support subprocess communications via PTYs on > MS-Windows, and thus will solve this and other similar issues. > > Patches to support PTYs on Windows are welcome.
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.