io::process::Command: add fine-grained env builder

This commit changes the `io::process::Command` API to provide
fine-grained control over the environment:

* The `env` method now inserts/updates a key/value pair.
* The `env_remove` method removes a key from the environment.
* The old `env` method, which sets the entire environment in one shot,
  is renamed to `env_set_all`. It can be used in conjunction with the
  finer-grained methods. This renaming is a breaking change.

To support these new methods, the internal `env` representation for
`Command` has been changed to an optional `HashMap` holding owned
`CString`s (to support non-utf8 data). The `HashMap` is only
materialized if the environment is updated. The implementation does not
try hard to avoid allocation, since the cost of launching a process will
dwarf any allocation cost.

This patch also adds `PartialOrd`, `Eq`, and `Hash` implementations for
`CString`.

[breaking-change]
This commit is contained in:
Aaron Turon 2014-07-02 13:50:45 -07:00
parent f9fe251777
commit bfa853f8ed
11 changed files with 137 additions and 72 deletions

View file

@ -729,7 +729,7 @@ fn with_argv<T>(prog: &CString, args: &[CString],
}
#[cfg(unix)]
fn with_envp<T>(env: Option<&[(CString, CString)]>,
fn with_envp<T>(env: Option<&[(&CString, &CString)]>,
cb: proc(*const c_void) -> T) -> T {
// On posixy systems we can pass a char** for envp, which is a
// null-terminated array of "k=v\0" strings. Since we must create
@ -762,7 +762,7 @@ fn with_envp<T>(env: Option<&[(CString, CString)]>,
}
#[cfg(windows)]
fn with_envp<T>(env: Option<&[(CString, CString)]>, cb: |*mut c_void| -> T) -> T {
fn with_envp<T>(env: Option<&[(&CString, &CString)]>, cb: |*mut c_void| -> T) -> T {
// On win32 we pass an "environment block" which is not a char**, but
// rather a concatenation of null-terminated k=v\0 sequences, with a final
// \0 to terminate.