zsh-workers
 help / color / mirror / code / Atom feed
From: Millian Poquet <millian.poquet@irit.fr>
To: zsh-workers@zsh.org
Subject: [bug report] prompt can erase messages written on the terminal by background processes
Date: Wed, 7 Dec 2022 20:02:18 +0100	[thread overview]
Message-ID: <9e3026aa-39a1-dd50-4d29-a64724d4eaaf@irit.fr> (raw)


[-- Attachment #1.1: Type: text/plain, Size: 3020 bytes --]

Hi,

I think that I found a zsh prompt display bug that can hide the messages 
printed by some processes on the terminal to end users.
(Please tell me if I should report the bug elsewhere, I sent it to this 
mailing list because 1. I could not find an active zsh bug tracker and 
2. both https://github.com/zsh-users/zsh's README and 
https://sourceforge.net/p/zsh/bugs/ told me to write the bug report here.)

I am no zsh expert so please tell me if this behavior is expected and if 
a configuration option exists to prevent such message loss.


*# Bug description*
It seems that the way zsh displays its prompt enables the loss of 
messages written on the terminal in some cases.
As the bug is visual, I recorded what has been printed on terminal 
session there: https://asciinema.org/a/543461

The attached MWE program `nowait.c` can be compiled with `gcc -std=c11 
-D_POSIX_C_SOURCE=199309L -Wall -Wextra -O2 -o nowait nowait.c` and 
enables to reproduce the error. It has the following behavior.
- The initial process writes a message on the terminal, then creates a 
subprocess (via libc `fork()`), then exits.
- The subprocess sleeps for a given number of milliseconds (or does not 
sleep at all if `argv[1] == 0`), then writes another message on the 
terminal. The written message is terminated by a newline if and only if 
`argv[2] == 1`.

If the subprocess writes on the terminal between the termination of the 
initial process and the writing of the prompt, the content of its 
message is erased by the prompt.
If the message is newline-terminated this is not a big deal, but 
otherwise the whole message will be hidden from the end user of the 
terminal.

I had the issue on the theme I use regularly (that uses `prompt_subst`), 
but I could also reproduce the issue from the default theme.
To do so, I made the prompt message generation slow by setting 
`PROMPT="prompt $(sleep 2)"` and by enabling `prompt_subst`.

*# Desired behavior*
I think that messages displayed by processes on the terminal should not 
be hidden by the shell.

IMHO keeping the printed messages before the prompt would be reasonable, 
but anything that prevents message loss would be an improvement (e.g., 
to copy the messages after erasing the prompt then writing the prompt if 
you think this is better).

*# Execution environment*
I could reproduce the problem on several environments.

On my laptop (dell latitude 3420, x86-64, linux-5.15.72, NixOS 22.05, 
zsh-5.9) both on a tty and on the kitty-0.26.2 graphical terminal 
emulator. Zsh used my configuration there.

On a [Grid'5000 econome 
machine](https://www.grid5000.fr/w/Nantes:Hardware#econome), x86-64, 
linux-5.10.0-19-amd64, Debian 5.10.149-2 (2022-10-21), zsh-5.9. This 
machine has an empty zsh configuration. I was connected on the machine 
remotely via ssh.


Best regards,

-- 
Millian Poquet, MCF (Associate Prof), Univ. Toulouse III
FSI, Dpt. INFO ; IRIT, Sepia team
https://mpoquet.github.io
Room 469, IRIT2, cours Rose Dieng-Kuntz, Campus Univ. Toulouse III

[-- Attachment #1.2: Type: text/html, Size: 4166 bytes --]

[-- Attachment #2: nowait.c --]
[-- Type: text/x-csrc, Size: 789 bytes --]

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
  if (argc != 3) {
    fprintf(stderr, "usage: nowait <DELAY-MILLISECONDS> <CHILD-NEWLINE>\n");
    exit(1);
  }

  unsigned int delay_ms = atoi(argv[1]);
  int child_newline = atoi(argv[2]);

  struct timespec delay;
  delay.tv_sec = delay_ms / 1000;
  delay.tv_nsec = (delay_ms % 1000) * 1000000;

  printf("msg from parent process\n");
  fflush(stdout);

  switch(fork()) {
    case -1:
      perror("fork");
      return 1;
    case 0:
      if (delay_ms > 0)
        nanosleep(&delay, NULL);
      if (child_newline)
        printf("msg from child process\n");
      else
        printf("msg from child process");
      fflush(stdout);
      return 0;
  }

  return 0;
}

             reply	other threads:[~2022-12-07 19:04 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-12-07 19:02 Millian Poquet [this message]
2022-12-07 22:55 ` Roman Perepelitsa
2022-12-08  3:46   ` Bart Schaefer
2022-12-08  8:21     ` Get cursor position (Was: [bug report] prompt can erase messages written on the terminal by background processes) Stephane Chazelas
2022-12-08  8:34       ` Roman Perepelitsa
2022-12-08 10:02         ` Stephane Chazelas
2022-12-08 10:10           ` Stephane Chazelas
2022-12-08 10:19           ` Mikael Magnusson
2022-12-09  2:19           ` Bart Schaefer
2022-12-09 12:46             ` Philippe Altherr
2022-12-10  4:30               ` Bart Schaefer
2022-12-10 14:55                 ` Private variables not private enough? (Was: Get cursor position (Was: [bug report] prompt can erase messages written on the terminal by background processes)) Philippe Altherr
2022-12-10 17:36                   ` Bart Schaefer
2022-12-10 20:38                     ` Bart Schaefer
2022-12-11 18:00               ` Get cursor position (Was: [bug report] prompt can erase messages written on the terminal by background processes) Stephane Chazelas
2022-12-09  1:39       ` Bart Schaefer
2022-12-08  8:45     ` [bug report] prompt can erase messages written on the terminal by background processes Roman Perepelitsa
2022-12-08 15:03     ` Oliver Kiddle

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=9e3026aa-39a1-dd50-4d29-a64724d4eaaf@irit.fr \
    --to=millian.poquet@irit.fr \
    --cc=zsh-workers@zsh.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 public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).