Skip to content

Disable DSUSP (Ctrl+Y) on macOS/BSD to prevent session termination (#29)#143

Open
nix-tkobayashi wants to merge 1 commit into
aws:mainlinefrom
nix-tkobayashi:fix/issue-29-bsd-dsusp-ctrl-y
Open

Disable DSUSP (Ctrl+Y) on macOS/BSD to prevent session termination (#29)#143
nix-tkobayashi wants to merge 1 commit into
aws:mainlinefrom
nix-tkobayashi:fix/issue-29-bsd-dsusp-ctrl-y

Conversation

@nix-tkobayashi

Copy link
Copy Markdown

Issue

Fixes #29

On BSD-derived systems, including macOS, pressing Ctrl+Y while a shell / SSM
session is connected terminates the session with:

Cannot perform start session: read /dev/stdin: resource temporarily unavailable

This also affects aws ecs execute-command --interactive, which uses Session
Manager under the hood. Linux and Windows are not affected.

Root cause

disableEchoAndInputBuffering puts the terminal into cbreak -echo, but on BSD
terminals the driver still acts on the DSUSP (delayed suspend) special
character, whose default binding is Ctrl+Y. When pressed, the kernel performs a
delayed suspend and the plugin's Stdin read fails with EAGAIN
("resource temporarily unavailable"), which tears down the session.

The documented workaround in #29 is to run stty dsusp undef locally before
connecting. This PR applies the equivalent setting from within the plugin.

Change

  • Add a per-OS disableDelayedSuspend():
    • darwin / freebsd / netbsd / openbsd (shellsession_bsd.go): runs
      stty dsusp undef.
    • linux (shellsession_linux.go): no-op, because Linux does not implement
      DSUSP and stty rejects the dsusp operand.
  • Call it from disableEchoAndInputBuffering (BSD/macOS only).
  • setState now splits its buffer with strings.Fields, so multi-token operands
    such as dsusp undef are passed to stty as separate arguments. Existing
    callers pass single tokens (cbreak, -echo, echo, and the stty -g blob),
    so their behavior is unchanged.

Windows is untouched (separate shellsession_windows.go).

Testing

  • go build for linux, darwin (amd64/arm64), freebsd, netbsd, openbsd — all pass.
  • go vet and gofmt clean.
  • go test ./src/sessionmanagerplugin/session/shellsession/ passes.

Licensing

I confirm this contribution is made under the terms of the Apache 2.0 license.

On BSD-derived systems, including macOS, the terminal driver treats Ctrl+Y
as the DSUSP (delayed suspend) special character even in cbreak mode. While
a shell/SSM session is connected, pressing Ctrl+Y triggers a delayed suspend
that makes the Stdin read fail with "read /dev/stdin: resource temporarily
unavailable", terminating the session. Linux does not implement DSUSP, so it
is unaffected.

Disable the DSUSP control character (equivalent to the documented
`stty dsusp undef` workaround) on darwin/freebsd/netbsd/openbsd via a new
per-OS disableDelayedSuspend(), called from disableEchoAndInputBuffering. It
is a no-op on linux, where stty rejects the `dsusp` operand.

setState now splits its buffer with strings.Fields so multi-token operands
like "dsusp undef" are passed to stty as separate arguments; existing callers
pass single tokens and are unaffected.

Fixes aws#29

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Problem interpreting signals emitted by terminal on BSD systems properly

1 participant