Skip to content

Commit 6fb168b

Browse files
committed
Add setenv to standard library
1 parent c18127b commit 6fb168b

File tree

5 files changed

+113
-2
lines changed

5 files changed

+113
-2
lines changed

src/lib/generic_os.rs

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,53 @@
11

22

3+
#[cfg(target_os = "linux")]
4+
#[cfg(target_os = "macos")]
35
fn getenv(str n) -> option::t[str] {
46
auto s = os::libc::getenv(str::buf(n));
57
ret if (s as int == 0) {
68
option::none[str]
79
} else { option::some[str](str::str_from_cstr(s)) };
8-
}
10+
}
11+
12+
#[cfg(target_os = "linux")]
13+
#[cfg(target_os = "macos")]
14+
fn setenv(str n, str v) {
15+
auto nbuf = str::buf(n);
16+
auto vbuf = str::buf(v);
17+
os::libc::setenv(nbuf, vbuf, 1);
18+
}
19+
20+
#[cfg(target_os = "win32")]
21+
fn getenv(str n) -> option::t[str]{
22+
auto nbuf = str::buf(n);
23+
auto nsize = 256u;
24+
while (true) {
25+
auto vstr = str::alloc(nsize - 1u);
26+
auto vbuf = str::buf(vstr);
27+
auto res = os::rustrt::rust_GetEnvironmentVariable(nbuf, vbuf, nsize);
28+
if (res == 0u) {
29+
ret option::none;
30+
} else if (res < nsize) {
31+
ret option::some(str::str_from_cstr(vbuf));
32+
} else {
33+
nsize = res;
34+
}
35+
}
36+
fail;
37+
}
38+
39+
#[cfg(target_os = "win32")]
40+
fn setenv(str n, str v) {
41+
auto nbuf = str::buf(n);
42+
auto vbuf = str::buf(v);
43+
os::rustrt::rust_SetEnvironmentVariable(nbuf, vbuf);
44+
}
45+
46+
// Local Variables:
47+
// mode: rust;
48+
// fill-column: 78;
49+
// indent-tabs-mode: nil
50+
// c-basic-offset: 4
51+
// buffer-file-coding-system: utf-8-unix
52+
// compile-command: "make -k -C .. 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
53+
// End:

src/lib/win32_os.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ native "cdecl" mod libc = "" {
1818
fn fwrite(vbuf buf, uint size, uint n, FILE f) -> uint;
1919
fn fseek(FILE f, int offset, int whence) -> int;
2020
fn ftell(FILE f) -> int;
21-
fn getenv(sbuf n) -> sbuf;
2221
fn _pipe(*mutable int fds, uint size, int mode) -> int;
2322
}
2423

@@ -67,6 +66,8 @@ fn fd_FILE(int fd) -> libc::FILE { ret libc::_fdopen(fd, str::buf("r")); }
6766
native "rust" mod rustrt {
6867
fn rust_process_wait(int handle) -> int;
6968
fn rust_getcwd() -> str;
69+
fn rust_SetEnvironmentVariable(sbuf n, sbuf v) -> int;
70+
fn rust_GetEnvironmentVariable(sbuf n, sbuf v, uint nsize) -> uint;
7071
}
7172

7273
fn waitpid(int pid) -> int { ret rustrt::rust_process_wait(pid); }

src/rt/rust_builtin.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -650,6 +650,20 @@ rust_ptr_eq(rust_task *task, type_desc *t, rust_box *a, rust_box *b) {
650650
return a == b;
651651
}
652652

653+
#if defined(__WIN32__)
654+
extern "C" CDECL int32_t
655+
rust_SetEnvironmentVariable(rust_task *task,
656+
const char *name, const char *val) {
657+
return SetEnvironmentVariable(name, val);
658+
}
659+
660+
extern "C" CDECL uint32_t
661+
rust_GetEnvironmentVariable(rust_task *task,
662+
const char *name, char *buf, uint32_t size) {
663+
return GetEnvironmentVariable(name, buf, size);
664+
}
665+
#endif
666+
653667
#if defined(__WIN32__)
654668
extern "C" CDECL void
655669
get_time(rust_task *task, uint32_t *sec, uint32_t *usec) {

src/rt/rustrt.def.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ rust_ptr_eq
3535
rust_run_program
3636
rust_start
3737
rust_getcwd
38+
rust_SetEnvironmentVariable
39+
rust_GetEnvironmentVariable
3840
size_of
3941
squareroot
4042
str_alloc

src/test/run-pass/lib-os.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// xfail-stage0
2+
3+
use std;
4+
5+
import std::generic_os::setenv;
6+
import std::generic_os::getenv;
7+
import std::option;
8+
9+
#[test]
10+
fn test_setenv() {
11+
setenv("NAME", "VALUE");
12+
assert getenv("NAME") == option::some("VALUE");
13+
}
14+
15+
#[test]
16+
fn test_setenv_overwrite() {
17+
setenv("NAME", "1");
18+
setenv("NAME", "2");
19+
assert getenv("NAME") == option::some("2");
20+
}
21+
22+
// Windows GetEnvironmentVariable requires some extra work to make sure
23+
// the buffer the variable is copied into is the right size
24+
#[test]
25+
fn test_getenv_big() {
26+
auto s = "";
27+
auto i = 0;
28+
while (i < 100) {
29+
s += "aaaaaaaaaa";
30+
i += 1;
31+
}
32+
setenv("NAME", s);
33+
assert getenv("NAME") == option::some(s);
34+
}
35+
36+
fn main() {
37+
test_setenv();
38+
test_setenv_overwrite();
39+
test_getenv_big();
40+
}
41+
42+
// Local Variables:
43+
// mode: rust;
44+
// fill-column: 78;
45+
// indent-tabs-mode: nil
46+
// c-basic-offset: 4
47+
// buffer-file-coding-system: utf-8-unix
48+
// compile-command: "make -k -C .. 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
49+
// End:

0 commit comments

Comments
 (0)