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

Ability to customize event source #694

Open
KernelErr opened this issue Jul 29, 2022 · 4 comments
Open

Ability to customize event source #694

KernelErr opened this issue Jul 29, 2022 · 4 comments

Comments

@KernelErr
Copy link

Hi, I am current making an SSH server. After user logged in, they will get a UI based on tui and crossterm.

However, it seems that crossterm relies on getting input from a specific file descriptor in Unix. That's somehow difficult for me to use, as we are not in a real terminal.

But we do could get user inputs with a format of [u8] array, so I am wondering if I can create my own input parser and a custom event source. Currently, crossterm may not have the ability to allow me to do it.

So should the custom event source be a feature for crossterm, or I just fork one to modify some code?

@TimonPost
Copy link
Member

TimonPost commented Jul 29, 2022

I think that this PR is trying to achieve that: #407. It will allow someone to just write anything to dev/tty and crossterm would interpret that. Right?

@KernelErr
Copy link
Author

Thanks for your reply. My SSH server will directly receive and send data from the TCP connection. The rendering work will happen in the client's terminal. So /dev/tty may be the server's terminal, not the client's. I may still need to create a custom event source rather than use /dev/tty.

@KernelErr
Copy link
Author

Currently, I just implemented std::io::Write trait for the SSH connection. So crossterm could send data to the client. I am finding a way to handle coming input.

@jocutajar
Copy link

Hi there, I'd like to add that when you try to create the EventStream in an environment without a tty, it simply panics. This is very unfortunate, because that prevents me from handling it gracefully to say at least run without input at all or invent my own. Additionally, there is no way to reliably determine if the EventStream creation will fail other than reverse engineering and matching the logic. This will break eventually, right...

No TTY is essential in containers, here as OP in remote conns and for automated testing, too...

Try this:

(echo ahoj | RUST_BACKTRACE=1 setsid cargo run 2>err.log > out.log)
let events = EventStream::default();

Please, at least return a result at creation, instead of panic on reading:

See how an error to get a tty is silently ignored:

        let source = source.ok().map(|x| Box::new(x) as Box<dyn EventSource>);

Which later leads to panic:

        self.source.as_ref().expect("reader source not set").waker()

Or not to break the API, add a method on EventStream to check if it indeed has the source. Or a reliable way to check whether crossterm assumes there's a tty?

Ideally we would be able to create EventStream over arbitrary std::io::Read as OP suggests. I understand that that would mean the poll would not be possible, so perhaps a non-poll flavor of it or better yet, an async flavor with async-std::io::Read which can be polled.

I'm willing to put some work into it if you're interested.

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

No branches or pull requests

3 participants