crossterm icon indicating copy to clipboard operation
crossterm copied to clipboard

Always read user input from /dev/tty

Open lotabout opened this issue 4 years ago • 13 comments

Is your feature request related to a problem? Please describe. I'm trying to port my CLI util skim to crossterm for windows support. And one of the use cases of skim is to accept piped input:

echo "input" | sk

In this case the stdin do not generate user inputs while I still hope the user inputs are handled correctly.

Describe the solution you'd like When creating file descriptor, use /dev/tty all the time.

lotabout avatar Mar 10 '20 13:03 lotabout

We already use /dev/tty, this one is not supported for windows of course. There we use winapi. Crossterm can be used through a pipe, please see this example for a demo.

TimonPost avatar Mar 10 '20 14:03 TimonPost

@TimonPost Not sure if I understand correctly. I believe the example shows how to write to stderr instead of stdout. While I am trying to do is to read piped input(stdin).

For example, expecting the following example to work:

$ echo "abc"| cargo run --example event-read
    Finished dev [unoptimized + debuginfo] target(s) in 0.05s
     Running `target/debug/examples/event-read`
Blocking read()
 - Keyboard, mouse and terminal resize events enabled
 - Hit "c" to print current cursor position
 - Use Esc to quit

Error: IoError(Os { code: 25, kind: Other, message: "Inappropriate ioctl for device" })

lotabout avatar Mar 10 '20 14:03 lotabout

I've tried to always use /dev/tty here:

/// Creates a file descriptor pointing to the standard input or `/dev/tty`.
pub fn tty_fd() -> Result<FileDesc> {
    let (fd, close_on_drop) = (
        fs::OpenOptions::new()
            .read(true)
            .write(true)
            .open("/dev/tty")?
            .into_raw_fd(),
        true,
    );

    Ok(FileDesc::new(fd, close_on_drop))
}

But doesn't seem to fix the issue. Any idea why it might not detect an IOCTL device while using a pipe ?

TimonPost avatar Mar 24 '20 20:03 TimonPost

In fact, this resulted in an error for ITerm terminals. #404. On Linux, it seems to behave just fine, but on macos no input can be read anymore.

TimonPost avatar Mar 28 '20 15:03 TimonPost

@TimonPost Just to make sure, were tcgetattr and tcsetattr operated on /dev/tty as well?

(Disclaimer: I haven't checked the solution)

  • https://github.com/crossterm-rs/crossterm/blob/master/src/terminal/sys/unix.rs#L121
  • https://github.com/crossterm-rs/crossterm/blob/master/src/terminal/sys/unix.rs#L127

lotabout avatar Mar 29 '20 10:03 lotabout

Ah, no they did not, I will open a branch with those changes. If someone can validate the working on mac os we can merge it.

TimonPost avatar Mar 29 '20 11:03 TimonPost

@TimonPost I can test it on Mac, let me know

extrawurst avatar Mar 30 '20 18:03 extrawurst

Can someone try this branch on mac os: https://github.com/crossterm-rs/crossterm/pull/407

TimonPost avatar Mar 31 '20 15:03 TimonPost

@TimonPost - I can give it a try. Is there something in particular that needs testing?

sophiajt avatar Apr 06 '20 17:04 sophiajt

You could run the interactive example in the examples folder. And in there run the input demo. It should work. Though on the PR #407 and #406 there are people who did the testing already. They reported invalid input. I left a comment with some ideas on there.

TimonPost avatar Apr 08 '20 05:04 TimonPost

@TimonPost I noticed with the latest master that #406 is fixed but I do still see the issue that @lotabout mentions in the comment above:

% echo "abc" | cargo run --example event-read
   Compiling crossterm v0.17.3 (/Users/test/Source/crossterm)
    Finished dev [unoptimized + debuginfo] target(s) in 3.42s
     Running `target/debug/examples/event-read`
Blocking read()
 - Keyboard, mouse and terminal resize events enabled
 - Hit "c" to print current cursor position
 - Use Esc to quit

Error: IoError(Os { code: 25, kind: Other, message: "Inappropriate ioctl for device" })

sophiajt avatar Apr 10 '20 19:04 sophiajt

Yea, there is someplace some argument is given, I supposed to libc, which is invalid. I haven't found that place yet. Regarding @Iotabout his comment, his ideas are implemented by this PR.

TimonPost avatar Apr 11 '20 05:04 TimonPost

I ran into this issue in the tab terminal multiplexer. I was trying to add support for stdin input in a raw mode app:

echo query | tab

I hit the same error as described above.

austinjones avatar Jan 24 '21 06:01 austinjones