console-rs / console-rs/console

On macOS, prompt exits if background command terminates

Open
#211 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
1.2k
Forks
144
Avg merge
8h 24m
Merged PRs (30d)
4

Description

I'm experience a strange interaction between console (used via dialoguer) and tokio's Command interface. I've done my best to debug it, but please let me know if there are more steps I can take that would be helpful.

Reproduction

Here's a simple reproduction (I've uploaded the full thing as a repo if that's easier):

use console::Term;
use std::process::Stdio;
use tokio::process::Command;

#[tokio::main(flavor = "current_thread")]
async fn main() {
    let term = Term::stderr();
    let mut child = Command::new("sleep")
        .arg("2")
        .stdin(Stdio::null())
        .stdout(Stdio::null())
        .stderr(Stdio::null())
        .spawn()
        .unwrap();
    let response = term.read_line().unwrap();
    child.wait().await.unwrap();
    println!("{response}");
}

Desired Behavior

The prompt should remain open indefinitely, until the user hits Enter. At that point, it should echo back whatever input was given.

Observed Behavior

The prompt remains open for 2 seconds, then closes and the program terminates with exit code 130 (indicating SIGINT).

  • If you type something then hit Enter before the background command exits, you'll see it pause until the 2 second sleep is complete, then output is echoed back as expected.
  • If you type something but do not hit enter before the background command exits, you will not see the echoed output. It exits immediately, as if SIGINT was received.

While waiting for input, console is blocked on this call to libc::select in select_fd, which explains why this issue is specific to macOS.

Other Context

The error does not occur in the following scenarios:

  • Using std::process::Command instead of tokio's Command (even if you spawn the process in the background while running the prompt)
  • Using term.read_secure_line()
  • On Linux, according to a user of my app. This is consistent with the fact that console is stopped in macos-only code at the time of termination.

Versions

I am running:

  • MacOS 14.4.1
  • iTerm2 3.4.23
  • console 0.15.8
  • tokio 1.37.0

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the macOS behavior with the provided Tokio Command example and compare it with std::process::Command, read src/unix_term.rs around select_fd and its macOS-only path. Done means the prompt remains open after the background command exits and still echoes input entered afterward.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
cli, operating-systems
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.