Skip to content

8s hang on pty #1318

Description

@Shiftwell-Jon

brush version

brush 0.4.0 (cargo:0.4.0)

bash version (for comparison)

GNU bash, version 3.2.57(1)-release (arm64-apple-darwin24)

Platform / OS

macOS

Steps to reproduce

Ran terminal command: sw_vers; echo "---"; uname -a; echo "---"; brush --version; echo "---"; brew info brush 2>&1 | head -10; echo "---"; echo $TERM_PROGRAM; echo $TERM

Bug Report: brush hangs indefinitely in any interactive session attached to a real controlling terminal (pty)

Project: brush-shell (brush)
Version: 0.4.0 (brush 0.4.0 (cargo:0.4.0)), installed via Homebrew (homebrew-core, bottled)

Environment

  • OS: macOS 15.8 (Build 24H20)
  • Kernel: Darwin 24.6.0, arm64 (Apple Silicon, T8103)
  • Install path: brush (Homebrew brush formula)
  • Reproduced both as the account's login shell (dscl UserShell) and by invoking the binary directly

Summary

brush hangs forever (never prints a prompt, never returns) whenever it is started as an interactive shell attached to a real controlling terminal (pty) — regardless of whether it's invoked as a login shell (-l), a plain interactive shell (-i), or with no flags at all. It only works correctly when stdin is a pipe (non-tty), which masked the bug during quick manual testing (echo cmd | brush works fine).

This makes brush completely unusable as an interactive/login shell today: setting it as the macOS login shell (chsh -s /opt/homebrew/bin/brush) causes every new Terminal window/tab to hang on open.

Reproduction

Using macOS script to allocate a real pty (a plain pipe does not reproduce the bug):

# Hangs (killed by timeout, exit 124):
script -q /dev/null bash -c 'timeout 8 brush -l'      # login shell
script -q /dev/null bash -c 'timeout 8 brush -i'      # interactive shell
script -q /dev/null bash -c 'timeout 8 brush'         # plain invocation

# Works fine (no real tty attached):
( echo 'echo hi'; sleep 1 ) | timeout 5 brush -i      # prints "hi", exits 0
( echo 'echo hi'; sleep 1 ) | timeout 5 brush -l      # prints "hi", exits 0
brush -c 'echo hello'                                  # prints "hello", exits 0

All three real-pty invocations above ran for the full 8-second timeout with zero output (no prompt, no echoed input) before being killed.

Isolation — not caused by rc files / dotfiles

To rule out shell startup files, I reran the login-shell case with a completely empty $HOME (no .bash_profile, .bashrc, .profile, or any other dotfile):

mkdir -p /tmp/emptyhome
script -q /dev/null bash -c 'HOME=/tmp/emptyhome timeout 8 brush -l'
# still hangs — exit 124

The hang still occurs, so it is not related to parsing any user rc/profile content — it happens during core interactive/login startup (likely job-control / terminal ownership setup, e.g. tcsetpgrp/process-group handling) before any rc file would even be read.

Impact

  • Cannot use brush as an interactive or login shell in any real terminal (Terminal.app, iTerm2, etc.) — this is likely brush's primary intended use case.
  • Particularly dangerous because a user can set it as their macOS login shell (chsh -s) and then be locked into a hanging shell on every new terminal window, with no rc-file explanation to fall back on for debugging.

Suggested next steps for investigation

  • Check job-control initialization on shell startup (tcsetpgrp/setpgid/signal handling for SIGTTIN/SIGTTOU) when a controlling terminal is present — the tty-vs-pipe behavior split strongly points here.
  • Compare behavior across platforms (Linux vs macOS) and terminal emulators to see if this is macOS/pty-specific.

Actual behavior (brush)

The process hangs indefinitely with no output, no prompt, and does not respond to normal input; it only terminates when killed (e.g. via timeout).

Expected behavior

brush -l / brush -i / brush should print an interactive prompt and accept input when attached to a real controlling terminal, just as it does when stdin is piped.

Additional context

No response

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: compatRelated to compatibility with standard shellsarea: usabilityPertaining to usability / user experiencebugSomething isn't workingplatform: macOSSpecific to macOS platformsstate: info neededAn issue that requires additional info from the submitter

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions