Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

[bug report] prompt can erase messages written on the terminal by background processes



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
#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;
}


Messages sorted by: Reverse Date, Date, Thread, Author