zsh-workers
 help / color / mirror / code / Atom feed
From: Godmar Back <godmar@gmail.com>
To: zsh-workers@zsh.org
Subject: support for POSIX job control terminal management in zsh
Date: Mon, 22 Jun 2020 21:39:40 -0400	[thread overview]
Message-ID: <CAB4+JYJft=Cc7nEvqsyTJwix-1HCc0jooBDvDy8N2MT_x2hecQ@mail.gmail.com> (raw)

Hi,

I noticed that zsh does not implement POSIX.1 when it comes to
saving/restoring the terminal state of processes suspended with
SIGTSTP.  (The same applies to bash, btw, but not to ksh.)  Shells
like tcsh or ash/dash also do not implement it.

POSIX.1 asks that:

"When a foreground (not background) job stops, the shell must sample
and remember the current terminal settings so that it can restore them
later when it continues the stopped job in the foreground (via the
tcgetattr( ) and tcsetattr( ) functions)."

Consequently, a program such as the one attached below should not fail
any assertions.
However, it does not appear to work when run under zsh.

I've had an illuminating discussion with Chet Ramey, the author of
bash, regarding bash's behavior. He pointed out that applications
historically could never rely on the shell provided job control in a
manner that they could be oblivious to being suspended/resumed, and
therefore always had to handle the saving/restoring of the terminal
state upon suspend/restore themselves, rather than relying on the job
control shell as POSIX asks.

Still, at least one shell (ksh) does appear to implement it.

Hence my question, out of curiosity, is: why does zsh not follow
POSIX.1 semantics in this regard?

Thanks.

 - Godmar

// ts_test.c
/* Test that terminal state is properly restored when a process is
stopped and restored. */
#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>
#include <assert.h>
#include <signal.h>

#define CTRL_D  4
#define CTRL_E  5

int
main()
{
    int terminal_fd = open(ctermid(NULL), O_RDWR);
    assert (terminal_fd != -1);

    // Step 1. make a change to the terminal state:
    // change VEOF from Ctrl-D to Ctrl-E
    struct termios saved_tty_state;
    int rc = tcgetattr(terminal_fd, &saved_tty_state);
    assert (rc == 0);

    assert (saved_tty_state.c_cc[VEOF] == CTRL_D);       // ^D
    saved_tty_state.c_cc[VEOF] = CTRL_E;                 // ^E
    rc = tcsetattr(terminal_fd, TCSANOW, &saved_tty_state);
    assert (rc == 0);

    // Step 2.  Suspend and let user resume
    printf("This job should now stop, please run 'fg' to continue it\n");
    raise(SIGTSTP);
    printf("Job now continuing...\n");

    // Step 3.
    // Expect that job control shell saved the terminal state
    rc = tcgetattr(terminal_fd, &saved_tty_state);
    assert (rc == 0);
    if (saved_tty_state.c_cc[VEOF] != CTRL_E) {
        printf("I expected a POSIX job control shell to preserve my
terminal settings\n");
        printf("VEOF was not saved, it is %d...\n", saved_tty_state.c_cc[VEOF]);
    }

    assert (saved_tty_state.c_cc[VEOF] == CTRL_E);       // ^E
}

             reply	other threads:[~2020-06-23  1:40 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-06-23  1:39 Godmar Back [this message]
2020-06-23  1:53 ` Bart Schaefer

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='CAB4+JYJft=Cc7nEvqsyTJwix-1HCc0jooBDvDy8N2MT_x2hecQ@mail.gmail.com' \
    --to=godmar@gmail.com \
    --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).