Skip to content
This repository has been archived by the owner on Nov 9, 2019. It is now read-only.

Improvements to WasiCtxBuilder, and a couple bug fixes #175

Merged
merged 8 commits into from
Nov 7, 2019

Conversation

acfoltzer
Copy link
Collaborator

@acfoltzer acfoltzer commented Nov 6, 2019

Note that since this involves changes to the interface that downstream clients have to use, it requires a different commit of wasmtime for testing. That wasmtime commit is currently on my private fork, so I'm opening this as a draft, as it will need to be amended before merging (edit: see bytecodealliance/wasmtime#490).

Text from the commit messages follows:

This changes the fields on the builder to types that let the various .arg(), .env(), etc methods
infallible, so we don't have to worry about handling any errors till we actually build. This reduces
line noise when using a builder in a downstream application.

Deferring the processing of the builder fields also has the advantage of eliminating the opening and
closing of /dev/null for the default stdio file descriptors unless they're actually used by the
resulting WasiCtx.

Now that failures are deferred until WasiCtxBuilder::build(), we don't need to have Result types
on the other methods any longer.

Additionally, using IntoIterator rather than Iterator as the trait bound for these methods is
slightly more general, and saves the client some typing.

Unicode errors when inheriting arguments and environment variables no longer cause a panic, but
instead go through OsString. We return ENOTCAPABLE at the end if there are NULs, or if UTF-8
conversion fails on Windows.

This also changes the bounds on some of the methods from AsRef<str> to AsRef<[u8]>. This
shouldn't break any existing code, but allows more flexibility when providing arguments. Depending
on the outcome of WebAssembly/WASI#8 we may eventually want to require
these bytes be UTF-8, so we might want to revisit this later (edit: we now validate UTF-8 during build()).

Finally, this fixes a tiny bug that could arise if we had exactly the maximum number of file
descriptors when populating the preopens, and a bug in the Linux implementation of isatty().

@acfoltzer acfoltzer force-pushed the acf/ctxbuilder branch 2 times, most recently from f759503 to b4fe288 Compare November 6, 2019 20:48
@acfoltzer acfoltzer marked this pull request as ready for review November 6, 2019 21:21
@acfoltzer
Copy link
Collaborator Author

I'm marking this as ready for review, since it doesn't look like bytecodealliance/wasmtime#490 will pass until we have a final revision to use in wasmtime.

@acfoltzer
Copy link
Collaborator Author

Per discussion with @sunfishcode, WasiCtxBuilder::build() now enforces that arguments and environment variables are valid UTF-8, including from OsStrings inherited from the host process args/env.

Copy link
Member

@sunfishcode sunfishcode left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Deferring the error reporting until build time feels cleaner and more flexible.

src/ctx.rs Outdated Show resolved Hide resolved
src/ctx.rs Outdated Show resolved Hide resolved
src/ctx.rs Outdated Show resolved Hide resolved
src/ctx.rs Outdated Show resolved Hide resolved
@acfoltzer
Copy link
Collaborator Author

Got it! I thought ENOTCAPABLE was a strange choice there but am glad to know there's a purpose-built errno for this.

src/ctx.rs Outdated Show resolved Hide resolved
Copy link
Member

@kubkon kubkon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! If you could only fix the bug in the BSD usage of isatty that would be great! :-)

src/sys/unix/linux/mod.rs Show resolved Hide resolved
.args
.into_iter()
.map(|arg| arg.into_utf8_cstring())
.collect::<Result<Vec<CString>>>()?;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not a nitpick, just an FYI that you could have omitted the concrete type stored inside the container here, i.e., Result<Vec<_>> :-)

(Ok(k), Ok(v)) => Ok((k, v)),
_ => Err(Error::ENOTCAPABLE),
}
(k.as_ref().to_vec().into(), v.as_ref().to_vec().into())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the cleanup here :-)

Comment on lines +279 to +282
.args(args)
.inherit_stdio()
.inherit_env()
.build()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, from the code readability point of view, that's so much better. Well done!

This changes the fields on the builder to types that let the various `.arg()`, `.env()`, etc methods
infallible, so we don't have to worry about handling any errors till we actually build. This reduces
line noise when using a builder in a downstream application.

Deferring the processing of the builder fields also has the advantage of eliminating the opening and
closing of `/dev/null` for the default stdio file descriptors unless they're actually used by the
resulting `WasiCtx`.

Unicode errors when inheriting arguments and environment variables no longer cause a panic, but
instead go through `OsString`. We return `ENOTCAPABLE` at the end if there are NULs, or if UTF-8
conversion fails on Windows.

This also changes the bounds on some of the methods from `AsRef<str>` to `AsRef<[u8]>`. This
shouldn't break any existing code, but allows more flexibility when providing arguments. Depending
on the outcome of https://github.com/WebAssembly/WASI/issues/8 we may eventually want to require
these bytes be UTF-8, so we might want to revisit this later.

Finally, this fixes a tiny bug that could arise if we had exactly the maximum number of file
descriptors when populating the preopens.
This is a separate commit, since it changes the interface that downstream clients have to use, and
therefore requires a different commit of `wasmtime` for testing. That `wasmtime` commit is currently
on my private fork, so this will need to be amended before merging.

Now that failures are deferred until `WasiCtxBuilder::build()`, we don't need to have `Result` types
on the other methods any longer.

Additionally, using `IntoIterator` rather than `Iterator` as the trait bound for these methods is
slightly more general, and saves the client some typing.
@kubkon
Copy link
Member

kubkon commented Nov 7, 2019

I'm marking this as ready for review, since it doesn't look like CraneStation/wasmtime#490 will pass until we have a final revision to use in wasmtime.

Yeah, that's a real hassle, isn't it? For that very reason, I'll be trying my best to migrate wasi-common inside of wasmtime ASAP. I've already made some headway by incorporating tests in this repo in #174, and after it lands, I'll get my hands dirty in trying to migrate wasi-common over to wasmtime. Also, on that topic, if you could withhold from creating any new PRs until then, that'd be great. Having said that, if you find anything that's critical, then by all means, please feel free to open a new PR to this repo :-)

@kubkon kubkon merged commit 2fe3530 into master Nov 7, 2019
@acfoltzer
Copy link
Collaborator Author

Sorry I wasn't on the right time zone to offer more feedback here; thank you for merging and good catch with BSD!

@acfoltzer acfoltzer deleted the acf/ctxbuilder branch November 7, 2019 16:10
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants