Closed AnharMiah closed 4 years ago
Hey @AnharMiah ! Thanks for reporting this.
I'm not familiar with wasm32-wasi
. Does it has specific APIs for reading data from stdin
or from a TTY? Maybe you'd need to use those APIs to implement read_password_from_stdin
specifically for wasi
:thinking:
In any case, if you do find a fix, I'm happy to review and merge it. The goal is for rpassword
to be as compatible as possible. If you do submit a PR, please include instructions as to how I can test the code on my machine (eg. tutorial to how to compile wasm32-wasi code).
hi @conradkleinespel
thanks for fast response!
according to the WASI official repo (https://github.com/bytecodealliance/wasi):
So from that since WASI supports Rust's standard library, STDIN should be totally fine to use.
I created a dummy hello world that took args from STDIN and it compiled fine with no issues (for both x86 as well as WASI)
@AnharMiah OK, sounds good!
From the looks of it, libc supports wasi
, so that's a good start because libc
is used in rpassword
's code for the unix
target. Have you tried replacing #[cfg(unix)]
with #[cfg(unix,wasm32-wasi)]
in src/lib.rs
? Does that work ?
@AnharMiah Sorry, that might actually not be what you need. Maybe you need #cfg(any(unix, target_arch=wasm32))
. I'm not sure, but playing with these things might get you what you want.
More information about that is here: https://doc.rust-lang.org/reference/conditional-compilation.html
@conradkleinespel thanks for the suggestion!
well I tried replacing #[cfg(unix)]
with #[cfg(any(unix, target_arch="wasm32"))]
and now is given far more build errors!:
error[E0433]: failed to resolve: could not find `unix` in `os`
--> src/lib.rs:52:18
|
52 | use std::os::unix::io::AsRawFd;
| ^^^^ could not find `unix` in `os`
error[E0432]: unresolved imports `libc::termios`, `libc::tcsetattr`, `libc::TCSANOW`, `libc::ECHO`, `libc::ECHONL`
--> src/lib.rs:49:23
|
49 | use libc::{c_int, termios, isatty, tcsetattr, TCSANOW, ECHO, ECHONL, STDIN_FILENO};
| ^^^^^^^ ^^^^^^^^^ ^^^^^^^ ^^^^ ^^^^^^ no `ECHONL` in the root
| | | | |
| | | | no `ECHO` in the root
| | | no `TCSANOW` in the root
| | no `tcsetattr` in the root
| no `termios` in the root
error[E0425]: cannot find function `tcgetattr` in crate `libc`
--> src/lib.rs:64:36
|
64 | io_result(unsafe { ::libc::tcgetattr(fd, term.as_mut_ptr()) })?;
| ^^^^^^^^^ not found in `libc`
<SNIPPED>
error: aborting due to 12 previous errors
Some errors have detailed explanations: E0425, E0432, E0433, E0599, E0658.
For more information about an error, try `rustc --explain E0425`.
error: could not compile `rpassword`.
sorry when I use #[cfg(any(unix, target_arch="wasm32-wasi"))]
I get only 3 errors, about not finding those specific function names:
--> src/lib.rs:254:17
|
254 | None => read_password_from_stdin(false),
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: a function with a similar name exists: `read_password_from_tty`
...
259 | / pub fn read_password_from_tty(prompt: Option<&str>)
260 | | -> ::std::io::Result<String> {
261 | | if let Some(prompt) = prompt {
262 | | display_on_tty(prompt)?;
263 | | }
264 | | read_password_from_stdin(true)
265 | | }
| |_- similarly named function `read_password_from_tty` defined here
error[E0425]: cannot find function `display_on_tty` in this scope
--> src/lib.rs:262:9
|
262 | display_on_tty(prompt)?;
| ^^^^^^^^^^^^^^ not found in this scope
error[E0425]: cannot find function `read_password_from_stdin` in this scope
--> src/lib.rs:264:5
|
259 | / pub fn read_password_from_tty(prompt: Option<&str>)
260 | | -> ::std::io::Result<String> {
261 | | if let Some(prompt) = prompt {
262 | | display_on_tty(prompt)?;
263 | | }
264 | | read_password_from_stdin(true)
| | ^^^^^^^^^^^^^^^^^^^^^^^^ help: a function with a similar name exists: `read_password_from_tty`
265 | | }
| |_- similarly named function `read_password_from_tty` defined here
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0425`.
error: could not compile `rpassword`.
OK, from what you're saying #[cfg(any(unix, target_arch="wasm32"))]
seems to be the way to go about debugging this. Most errors have a reason, I'll get to that in a minute.
#[cfg(any(unix, target_arch="wasm32-wasi")))
doesn't work because wasm32-wasi
is not an "arch", so "target_arch" doesn't work with "wasm32-wasi" it only work with "wasm32" (which is an arch).
Can you tell me something : does wasm32-wasi
work in a web browser only ? never in a terminal ?
Also, feel free to hop onto Discord if you want a bit more speed in the discussion: https://discord.com/invite/9zXtYqQ
oh ok yes that makes sense,
Can you tell me something : does wasm32-wasi work in a web browser only ? never in a terminal ?
so WASI basically allows WASM to run on the server or basically anything that implements a WASM runtime with "sys calls", there are many projects that use WASI to basically run on many platform see:
https://github.com/bytecodealliance/wasmtime
https://github.com/wasm3/wasm3
What this means is that if you can compile your Rust to wasm, then you can use the WASM(I) runtime across many many architecture without any further compilation (a new kind modern JVM if you will) so from everything from a tiny ESP8266 microcontoller all the way to satellite STBs etc
So, back to the first output, the one with #[cfg(any(unix, target_arch="wasm32"))]
.
The first error is about use std::os::unix::io::AsRawFd
. Probably because there is no RawFd
for WASI: have a look here => https://github.com/rust-lang/libc/blob/master/src/wasi.rs
If wasm32-wasi
is meant to work in a web browser, try to remove all code from src/lib.rs
that has to do with tty
. The read_password_from_stdin
function would look somewhat like this:
/// Reads a password from stdin
pub fn read_password_from_stdin(open_tty: bool) -> ::std::io::Result<String> {
let mut password = super::ZeroOnDrop::new();
io::stdin().read_line(&mut password)?
super::fixes_newline(&mut password);
Ok(password.into_inner())
}
ok thanks, I'll have a play, WASI is not intended for the browser its the opposite (i.e running WASM on the server)
UPDATE:
so after looking into the libc upstream repo, I think that's basically the problem, they just don't have bindings for those things for WASI hence the build failure, probably best to open an issue with the libc repo :)
Thanks again for all your help!
@AnharMiah Oh OK ! I'll go ahead and close this issue for now then. Feel free to re-open later or make a PR if you have a fix for this. Really sorry that you're unable to use rpassword
for now but I hope you find a way to create what you want.
Until then, feel free to copy any piece of code form rpassword
as long as you comply with the Apache license:
Best of luck to you!
hi, firstly thanks for creating this crate its highly appreciated!
Just some background, as part of a weekend hack I was playing around with the
wasm32-wasi
target, and I had a demo project that uses rpassword, however when usingwasm32-wasi
rpassword fails to buildwould this take much to get to build under that target?
I get a multiple errors saying that certain function names don't exist e.g
I'm not too clued about the
cfg
annotation, but in the source it appears you are doing some conditional code paths based on either Windows or Unix, would this be the case that this somehow needs to include the wasm32 as well?