exec-rs
exec-rs copied to clipboard
Implement for Windows
Windows has the _wexecvp function in the C runtime which is the same as Unix's execvp but takes Windows wide strings for arguments instead.
The biggest difference is that instead of using CString to make FFI-ready strings, we use std::os::windows::ffi::OsStrExt::encode_wide which builds a Vec<u16> for us, but we need to check for interior nulls manually, and can't return the same NulError that comes from CString. So I've changed the error type slightly on Windows accordingly.
This isn't a breaking change because this crate didn't build on Windows before anyway :)
Unix functionality is unaffected.
As a slight drive-by improvement, I fixed up the std::error::Error method implementations to remove the deprecated description() implementation and use source() instead of the deprecated cause().
re: #3
Thanks for the review! I'll address your main points:
This is a fairly old library, and since Rust 1.9.0,
exechas been built into Rust, but only for Unix-like systems. So this library had been largely deprecated. (I somehow missed updating theCargo.tomlfile to indicate this.)
I was in the process of upgrading a program which used this crate, and discovered precisely what you point out, that the functionality in std is Unix-only, which means this crate has an opportunity to implement cross-platform functionality beyond what the standard library provides, making it useful again! :)
1. The [docs say that](https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/execvp-wexecvp?view=vs-2019) "This API cannot be used in applications that execute in the Windows Runtime. For more information, see CRT functions not supported in Universal Windows Platform apps." Are normal Rust Windows apps supposed to work with the Windows Runtime? Are there any special `cfg` flags that we need to check or document?
Windows is one platform as far as Rust's cfg flags are concerned, even though Win32 and UWP are quite different. The main difference is that programs get linked with different libraries for the different environments. Win32 programs get the C runtime and other win32 DLLs, whereas UWP gets a whole different set of things.
The effect of trying to build this code on UWP will be to get a linker error when it can't find any library that implements the _wexecvp function.
2. Would it make sense to propose this feature for the Rust standard library, because Rust already supports `exec` on Unix systems? If it doesn't make sense to propose this for the Rust standard library, would it make sense to convert all the Unix code in this library to a thin wrapper over the standard library version?
Ideally yes, this functionality would be in the standard library, but adding things to the standard library is a really high bar that I don't think I'm up to meeting :P
Implementing the functionality in an external crate is often a desirable first step before proposing standard library changes anyway.
3. On Unix, if process A runs process B, and process B execs process C, then the final exit code of process C will be returned to process A as if it were the exit code of process B. This is a key feature of `exec`. Does this work the same on Windows?
Yes, the behavior is just as in Unix, including propagation of the exec'd process' exit code.
I've added wexecvp (and family) to libc. Once it is released, I can remove it from here and update the libc dependency.
This is great! Thank you for your responses.
Obviously we're going to want to remove the Unix implementation as well, and replace it with a call to Rust's standard library version.
Congratulations to developed this wrapper about the execvp function. I used it in a project, and it worked perfectly. The use of the lib is very simple. But, I faced a limit that the lib just work to Linux OS. So I found this PR implementing the function to Windows OS. Do you have any prevision to merge this PR and homologate the changes to use in production?
@emk have you a prevision to review this PR?
@wfraser @emk