Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pty command doesn't handle SIGTSTP correctly #375

Closed
krader1961 opened this issue Jan 19, 2018 · 3 comments
Closed

pty command doesn't handle SIGTSTP correctly #375

krader1961 opened this issue Jan 19, 2018 · 3 comments
Labels
Milestone

Comments

@krader1961
Copy link
Contributor

While working on changing the Meson build system to also build the pty command so its associated unit tests could be run I noticed something interesting. There is one test for \cZ to suspend the current process. The ksh command handles that situation correctly. That is, if you run something like /bin/sleep 30 and press \cZ the sleep is suspended. The standalone pty command results in the blocking syscall of the command being resumed rather than suspending the process.

Here is a strace of /bin/sleep (substituted for the less command in that unit test to simplify the problem):

1516334684.166476 restart_syscall(<... resuming interrupted nanosleep ...>) = ? ERESTART_RESTARTBLOCK (Interrupted by signal)
1516334685.650671 --- SIGTSTP {si_signo=SIGTSTP, si_code=SI_USER, si_pid=95709, si_uid=1000} ---
1516334685.650699 restart_syscall(<... resuming interrupted restart_syscall ...>) = ? ERESTART_RESTARTBLOCK (Interrupted by signal)
1516334692.311947 --- SIGSTOP {si_signo=SIGSTOP, si_code=SI_USER, si_pid=95727, si_uid=1000} ---
1516334692.312118 --- stopped by SIGSTOP ---
1516334695.540488 --- SIGHUP {si_signo=SIGHUP, si_code=SI_KERNEL} ---
1516334695.541189 +++ killed by SIGHUP +++

Notice that the nanosleep is restarted. What should happen is this:

1516335967.922413 restart_syscall(<... resuming interrupted nanosleep ...>) = ? ERESTART_RESTARTBLOCK (Interrupted by signal)
1516335970.061081 --- SIGTSTP {si_signo=SIGTSTP, si_code=SI_KERNEL} ---
1516335970.061546 --- stopped by SIGTSTP ---

TBD is what pty is doing wrong in setting up the environment such that the libc syscall trampoline code is incorrectly deciding to restart the interrupted syscall. Note that this happens on both BSD and GNU Linux.

@krader1961 krader1961 added the bug label Jan 19, 2018
@krader1961
Copy link
Contributor Author

I double-checked the beta branch and using the legacy build system the same failure occurs:

test pty begins at 2018-01-19+12:36:58
        pty.sh[431]: process/terminal group exercise: line 435: expected ":$|:\E|lines", got EOF
test pty failed at 2018-01-19+12:37:13 with exit code 1 [ 20 tests 1 error ]

@kernigh
Copy link
Contributor

kernigh commented Apr 21, 2018

I expect the test in pty.sh to fail in OpenBSD because it uses $(seq 100), but OpenBSD has no seq command. (GNU coreutils, FreeBSD, NetBSD have seq. OpenBSD doesn't. Illumos doesn't have seq, or has no manual for seq.)

I tried and failed to write a test that would reproduce the problem where /bin/sleep restarts nanosleep() after SIGTSTP. I did have trouble getting pty to send ^Z at the correct time. It is possible for pty to type ^Z before sleep becomes the terminal's foreground process. This ^Z sends SIGTSTP to ksh, before or after ksh sets its SIGTSTP handler. If before, then ksh gets suspended and /bin/sleep never runs. If after, then ksh ignores SIGTSTP and runs /bin/sleep.

I sent ^Z at the correct time with this test. First, I put ksh and pty in PATH, then I run ktrace -i ksh try.sh, where try.sh is

ENV=/./ pty -w 100 -d ksh <<EOF
u \$
w /bin/sleep 30
c \cZ
u Stopped
EOF

I need ^Z to suspend /bin/sleep, so I use -w 100 to wait between typing /bin/sleep 30 and typing ^Z. I also use u \$ to wait for a shell prompt. I view the trace with kdump -R | less. The trace suggests that SIGTSTP stops /bin/sleep. The trace doesn't show the SIGTSTP, but I can see ksh catching SIGCHLD (as if for a stopped child) and wait4(2) telling ksh that something happened to /bin/sleep. Then ksh exits and SIGHUP terminates /bin/sleep.

ENV=/./ is so ksh doesn't run /etc/ksh.kshrc. I used ENV=/./ to get fewer systems calls in the trace. The test pty.sh seems not to disable /etc/ksh.kshrc, so the presence of /etc/ksh.kshrc in some systems may cause failures in pty.sh.

kernigh added a commit to kernigh/ast that referenced this issue Jun 7, 2018
Disable /etc/ksh.kshrc so it can't change PS1 or other environment
variables; such changes can break the tests.  Switch from `seq 100` to
`{1..100}` because OpenBSD has no seq(1) command.  Remove TODO
comments and enable tests in pty.sh.  Some tests use stty(1); these
should work even if stty(1) is not a builtin.

This enables the test for att#375
@krader1961 krader1961 added this to the will-not-fix milestone Jul 24, 2018
@krader1961
Copy link
Contributor Author

This is moot since we've decided to drop the pty command from the project per issue #634.

McDutchie added a commit to ksh93/ksh that referenced this issue Jul 4, 2020
Apparently, pty doens't handle SIGTSTP correctly:
att#375
#45 (comment)

src/cmd/ksh93/tests/pty.sh:
- Disable the 'process/terminal group exercise' regression test,
  which depends on correct SIGTSTP handling, until pty can be
  fixed.

Closes #45.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants