Fix os::env race (#2870)

This commit is contained in:
Ben Blum
2012-07-25 17:37:40 -04:00
parent 43867bf6f3
commit 4378e7ead1

View File

@@ -41,7 +41,6 @@ export walk_dir;
export as_c_charp, fill_charp_buf; export as_c_charp, fill_charp_buf;
extern mod rustrt { extern mod rustrt {
fn rust_env_pairs() -> ~[~str];
fn rust_getcwd() -> ~str; fn rust_getcwd() -> ~str;
fn rust_path_is_dir(path: *libc::c_char) -> c_int; fn rust_path_is_dir(path: *libc::c_char) -> c_int;
fn rust_path_exists(path: *libc::c_char) -> c_int; fn rust_path_exists(path: *libc::c_char) -> c_int;
@@ -52,16 +51,6 @@ extern mod rustrt {
} }
fn env() -> ~[(~str,~str)] {
let mut pairs = ~[];
for vec::each(rustrt::rust_env_pairs()) |p| {
let vs = str::splitn_char(p, '=', 1u);
assert vec::len(vs) == 2u;
vec::push(pairs, (vs[0], vs[1]));
}
ret pairs;
}
const tmpbuf_sz : uint = 1000u; const tmpbuf_sz : uint = 1000u;
fn as_c_charp<T>(s: ~str, f: fn(*c_char) -> T) -> T { fn as_c_charp<T>(s: ~str, f: fn(*c_char) -> T) -> T {
@@ -130,11 +119,16 @@ fn setenv(n: ~str, v: ~str) {
global_env::setenv(n, v) global_env::setenv(n, v)
} }
fn env() -> ~[(~str,~str)] {
global_env::env()
}
mod global_env { mod global_env {
//! Internal module for serializing access to getenv/setenv //! Internal module for serializing access to getenv/setenv
export getenv; export getenv;
export setenv; export setenv;
export env;
extern mod rustrt { extern mod rustrt {
fn rust_global_env_chan_ptr() -> *libc::uintptr_t; fn rust_global_env_chan_ptr() -> *libc::uintptr_t;
@@ -142,7 +136,8 @@ mod global_env {
enum msg { enum msg {
msg_getenv(~str, comm::chan<option<~str>>), msg_getenv(~str, comm::chan<option<~str>>),
msg_setenv(~str, ~str, comm::chan<()>) msg_setenv(~str, ~str, comm::chan<()>),
msg_env(comm::chan<~[(~str,~str)]>)
} }
fn getenv(n: ~str) -> option<~str> { fn getenv(n: ~str) -> option<~str> {
@@ -159,6 +154,13 @@ mod global_env {
comm::recv(po) comm::recv(po)
} }
fn env() -> ~[(~str,~str)] {
let env_ch = get_global_env_chan();
let po = comm::port();
comm::send(env_ch, msg_env(comm::chan(po)));
comm::recv(po)
}
fn get_global_env_chan() -> comm::chan<msg> { fn get_global_env_chan() -> comm::chan<msg> {
let global_ptr = rustrt::rust_global_env_chan_ptr(); let global_ptr = rustrt::rust_global_env_chan_ptr();
let task_build_fn = || { let task_build_fn = || {
@@ -183,6 +185,9 @@ mod global_env {
either::left(msg_setenv(n, v, resp_ch)) { either::left(msg_setenv(n, v, resp_ch)) {
comm::send(resp_ch, impl::setenv(n, v)) comm::send(resp_ch, impl::setenv(n, v))
} }
either::left(msg_env(resp_ch)) {
comm::send(resp_ch, impl::env())
}
either::right(_) { either::right(_) {
break; break;
} }
@@ -193,6 +198,19 @@ mod global_env {
} }
mod impl { mod impl {
extern mod rustrt {
fn rust_env_pairs() -> ~[~str];
}
fn env() -> ~[(~str,~str)] {
let mut pairs = ~[];
for vec::each(rustrt::rust_env_pairs()) |p| {
let vs = str::splitn_char(p, '=', 1u);
assert vec::len(vs) == 2u;
vec::push(pairs, (vs[0], vs[1]));
}
ret pairs;
}
#[cfg(unix)] #[cfg(unix)]
fn getenv(n: ~str) -> option<~str> { fn getenv(n: ~str) -> option<~str> {