Skip to content

Commit 51b9fb2

Browse files
committed
---
yaml --- r: 5677 b: refs/heads/master c: a8ce543 h: refs/heads/master i: 5675: 2c5a93e v: v3
1 parent 5d239ef commit 51b9fb2

File tree

6 files changed

+69
-3
lines changed

6 files changed

+69
-3
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: a0a4d34e141a7a6445457e27fe18d875fb57d9d5
2+
refs/heads/master: a8ce543dc937043f2988a856c0c43339eadf8d69

trunk/src/lib/ctypes.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
type size_t = uint;
33
type ssize_t = int;
44

5+
type uint32_t = u32;

trunk/src/lib/linux_os.rs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
2-
31
// FIXME Somehow merge stuff duplicated here and macosx_os.rs. Made difficult
42
// by https://github.com/graydon/rust/issues#issue/268
53
native "cdecl" mod libc = "" {
@@ -28,6 +26,8 @@ native "cdecl" mod libc = "" {
2826
fn unsetenv(n: str::sbuf) -> int;
2927
fn pipe(buf: *mutable int) -> int;
3028
fn waitpid(pid: int, &status: int, options: int) -> int;
29+
fn readlink(path: str::sbuf, buf: str::sbuf,
30+
bufsize: ctypes::size_t) -> ctypes::ssize_t;
3131
}
3232

3333
mod libc_constants {
@@ -78,6 +78,21 @@ native "rust" mod rustrt {
7878

7979
fn getcwd() -> str { ret rustrt::rust_getcwd(); }
8080

81+
/// Returns the directory containing the running program
82+
/// followed by a path separator
83+
fn get_exe_path() -> option::t<fs::path> {
84+
let bufsize = 1023u;
85+
let path = str::unsafe_from_bytes(vec::init_elt(0u8, bufsize));
86+
ret str::as_buf("/proc/self/exe", { |proc_self_buf|
87+
str::as_buf(path, { |path_buf|
88+
if libc::readlink(proc_self_buf, path_buf, bufsize) != -1 {
89+
option::some(fs::dirname(path) + fs::path_sep())
90+
} else {
91+
option::none
92+
}
93+
})
94+
});
95+
}
8196

8297
// Local Variables:
8398
// mode: rust;

trunk/src/lib/macos_os.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ native "cdecl" mod libc = "" {
2525
fn unsetenv(n: str::sbuf) -> int;
2626
fn pipe(buf: *mutable int) -> int;
2727
fn waitpid(pid: int, &status: int, options: int) -> int;
28+
fn _NSGetExecutablePath(buf: str::sbuf,
29+
bufsize: *mutable ctypes::uint32_t) -> int;
2830
}
2931

3032
mod libc_constants {
@@ -75,6 +77,18 @@ native "rust" mod rustrt {
7577

7678
fn getcwd() -> str { ret rustrt::rust_getcwd(); }
7779

80+
fn get_exe_path() -> option::t<fs::path> {
81+
// FIXME: This doesn't handle the case where the buffer is too small
82+
let bufsize = 1023u32;
83+
let path = str::unsafe_from_bytes(vec::init_elt(0u8, bufsize as uint));
84+
ret str::as_buf(path, { |path_buf|
85+
if libc::_NSGetExecutablePath(path_buf, ptr::addr_of(bufsize)) == 0 {
86+
option::some(fs::dirname(path) + fs::path_sep())
87+
} else {
88+
option::none
89+
}
90+
});
91+
}
7892

7993
// Local Variables:
8094
// mode: rust;

trunk/src/lib/win32_os.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,17 @@ mod libc_constants {
3939
}
4040
}
4141

42+
type DWORD = u32;
43+
type HMODULE = uint;
44+
type LPTSTR = str::sbuf;
45+
4246
native "x86stdcall" mod kernel32 {
4347
fn GetEnvironmentVariableA(n: str::sbuf, v: str::sbuf, nsize: uint) ->
4448
uint;
4549
fn SetEnvironmentVariableA(n: str::sbuf, v: str::sbuf) -> int;
50+
fn GetModuleFileNameA(hModule: HMODULE,
51+
lpFilename: LPTSTR,
52+
nSize: DWORD) -> DWORD;
4653
}
4754

4855
fn exec_suffix() -> str { ret ".exe"; }
@@ -81,6 +88,20 @@ fn waitpid(pid: int) -> int { ret rustrt::rust_process_wait(pid); }
8188

8289
fn getcwd() -> str { ret rustrt::rust_getcwd(); }
8390

91+
fn get_exe_path() -> option::t<fs::path> {
92+
// FIXME: This doesn't handle the case where the buffer is too small
93+
let bufsize = 1023u;
94+
let path = str::unsafe_from_bytes(vec::init_elt(0u8, bufsize));
95+
ret str::as_buf(path, { |path_buf|
96+
if kernel32::GetModuleFileNameA(0u, path_buf,
97+
bufsize as u32) != 0u32 {
98+
option::some(fs::dirname(path) + fs::path_sep())
99+
} else {
100+
option::none
101+
}
102+
});
103+
}
104+
84105
// Local Variables:
85106
// mode: rust;
86107
// fill-column: 78;

trunk/src/test/stdtest/os.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,21 @@ fn test_getenv_big() {
2828
assert (getenv("NAME3") == option::some(s));
2929
}
3030

31+
#[test]
32+
fn get_exe_path() {
33+
let path = std::os::get_exe_path();
34+
assert option::is_some(path);
35+
let path = option::get(path);
36+
log path;
37+
38+
// Hard to test this function
39+
if std::os::target_os() != "win32" {
40+
assert std::str::starts_with(path, std::fs::path_sep());
41+
} else {
42+
assert path[1] == ':' as u8;
43+
}
44+
}
45+
3146
// Local Variables:
3247
// mode: rust;
3348
// fill-column: 78;

0 commit comments

Comments
 (0)