From: Ioannis Kappas <ioannis.kappas@gmail.com>
To: Eli Zaretskii <eliz@gnu.org>
Cc: 46388@debbugs.gnu.org
Subject: bug#46388: 27.1; emacs -batch does not output messages immediately when invoked outside of the command prompt
Date: Thu, 11 Feb 2021 08:10:34 +0000 [thread overview]
Message-ID: <CAMRHuGBP=UqDiBBJ18BWASmFwLTgx3WkQ50CrQK6B2t6K2mUbw@mail.gmail.com> (raw)
In-Reply-To: <83pn17j4pw.fsf@gnu.org>
On Wed, Feb 10, 2021 at 3:57 PM Eli Zaretskii <eliz@gnu.org> wrote:
> >
> > | # | System | emacs -batch invoked from | MESSAGE behavior
> >
> > |
> > |---+------------+---------------------------+----------------------------------------------------------------------------------------------------|
> > | 1 | Linux | bash | any MESSAGE is
> > immediately printed, i.e. stderr is unbuffered
> > |
> > | 2 | Linux | emacs eshell/shell etc | >>
>
> Did you try this 2nd item when the connection type for the subprocess
> is 'pipe'? Because otherwise we are comparing apples to oranges.
I haven't, how do I do this? I was merely describing the plain user
experience of running emacs -batch from a shell.
for case #2 for example:
1. On Linux, open emacs
2. M-x eshell
3. at the eshell prompt type the following command:
3.1 emacs -Q --batch --eval="(progn (message \"hi\") (sit-for 5))"
4. observe the result
4.1 "hi" is printed immediately, emacs -batch exits after five seconds.
In my tests, the second command was ran in all five cases, without applying any
other configuration to the parent command prompt/shell/eshell process.
Apologies if this was not clear.
> > I think I've just realized what you were saying from the
> > beginning. That the difference in behavior is expected, since
> > it is the parent process which decides the buffering regime to be
> > used for the subprocess. Thus in #5, it is emacs on windows that
> > decided to invoke emacs -batch as a subprocess using pipes, which
> > has resulted in emacs -batch's stderr to be buffered.
>
> That is correct. As we don't support PTYs on Windows, we can only use
> pipes for communicating with subprocesses there.
>
> Btw, did you try to play with the value of w32-pipe-buffer-size,
> e.g. setting it to a small value?
No, I haven't experimented with pipes yet, my next plan is to study
how subprocess
are invoked from within emacs and mintty (since both demonstrate the
same behavior).
> > If the current behavior is indeed the correct expected behavior, how do I
> > flush text message to stderr (or even stdout) from an emacs
> > -batch script/eval?
>
> My reading of the code is that we already fflush stderr after emitting
> a message, so this should already happen. See message_to_stderr. If
> that still doesn't help, then there's some buffering in the OS (for
> example, in the pipe machinery itself), which we cannot control.
the xdisp.c:message_to_stderr() is the first function i studied with
gdb when I started the investigation. Unless I've missed something,
it does not seem to lead to calling fflush (under windows at least):
1. it will sysdep.c:errwrite() the message
1.1 errwrite() will call sysdep.c:errstream() to get stderr
1.1.1 errstream() *may* call fflush on stderr in some system (via
buferr static variable), but this does not happen under windows-nt at
least.
1.2 will call fwrite to write the message
2. it may call sysdep.c:errputc() to to append a newline, following
exactly the same logic as for errwrite(), but using fputc() instead
/* Log the message M to stderr. Log an empty line if M is not a string. */
static void
message_to_stderr (Lisp_Object m)
{
if (noninteractive_need_newline)
{
noninteractive_need_newline = false;
errputc ('\n');
}
if (STRINGP (m))
{
Lisp_Object coding_system = Vlocale_coding_system;
Lisp_Object s;
if (!NILP (Vcoding_system_for_write))
coding_system = Vcoding_system_for_write;
if (!NILP (coding_system))
s = code_convert_string_norecord (m, coding_system, true);
else
s = m;
errwrite (SDATA (s), SBYTES (s));
}
if (STRINGP (m) || !cursor_in_echo_area)
errputc ('\n');
}
void
errputc (int c)
{
fputc_unlocked (c, errstream ());
}
void
errwrite (void const *buf, ptrdiff_t nbuf)
{
fwrite_unlocked (buf, 1, nbuf, errstream ());
}
/* Return the error output stream. */
static FILE *
errstream (void)
{
FILE *err = buferr;
if (!err)
return stderr;
fflush_unlocked (stderr);
return err;
}
in sysdep.c:init_standard_fds()
...
/* Set buferr if possible on platforms defining _PC_PIPE_BUF, as
they support the notion of atomic writes to pipes. */
#ifdef _PC_PIPE_BUF
buferr = fdopen (STDERR_FILENO, "w");
if (buferr)
setvbuf (buferr, NULL, _IOLBF, 0);
#endif
...
> There were some changes in this area lately (that's the discussion
> from 2019 I mentioned before): we now try to make a buffered variant
> of stderr, and use that for error messages. The reason, in a
> nutshell, is that when you build Emacs with "make -jN", several copies
> of the Emacs process can work in parallel, so it was deemed better to
> have their messages be emitted atomically, instead of being
> interspersed with one another, which produces an illegible mess.
> However, that change makes a line-buffered variant of stderr, and on
> Windows line buffering is the same as full buffering. So maybe we
> would need more changes in that area, for example some variable to
> control this behavior instead of making it unconditional.
Noted, thanks again!
next prev parent reply other threads:[~2021-02-11 8:10 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-02-08 21:20 bug#46388: 27.1; emacs -batch does not output messages immediately when invoked outside of the command prompt Ioannis Kappas
2021-02-08 21:42 ` Ioannis Kappas
2021-02-09 5:36 ` Eli Zaretskii
2021-02-09 20:15 ` Ioannis Kappas
2021-02-09 20:52 ` Eli Zaretskii
2021-02-09 21:14 ` Eli Zaretskii
[not found] ` <CAMRHuGC_p59uw_hmCL65Z0F1ZdFbVAf9MHcB-sX88bW6jchC-Q@mail.gmail.com>
2021-02-10 12:48 ` Ioannis Kappas
2021-02-10 15:57 ` Eli Zaretskii
2021-02-11 8:10 ` Ioannis Kappas [this message]
2021-02-11 14:09 ` Eli Zaretskii
2021-02-11 19:25 ` Ioannis Kappas
2021-02-11 19:55 ` Eli Zaretskii
2021-02-12 19:59 ` Ioannis Kappas
2021-02-12 20:03 ` Eli Zaretskii
2021-03-06 15:00 ` Ioannis Kappas
2021-03-08 4:05 ` Paul Eggert
2021-03-08 7:56 ` Ioannis Kappas
2021-03-11 14:27 ` Eli Zaretskii
2021-03-11 18:43 ` Paul Eggert
2021-02-11 21:15 ` Paul Eggert
2021-02-09 3:38 ` 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='CAMRHuGBP=UqDiBBJ18BWASmFwLTgx3WkQ50CrQK6B2t6K2mUbw@mail.gmail.com' \
--to=ioannis.kappas@gmail.com \
--cc=46388@debbugs.gnu.org \
--cc=eliz@gnu.org \
/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.