commit
f4dba956ec
11 changed files with 382 additions and 149 deletions
|
@ -58,6 +58,7 @@ Implicitly, all crates behave as if they included the following prologue:
|
|||
#[cfg(target_os = "linux")]
|
||||
pub mod linkhack {
|
||||
#[link_args="-lrustrt -lrt"]
|
||||
#[link_args = "-lpthread"]
|
||||
extern {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -534,6 +534,8 @@ pub mod types {
|
|||
|
||||
pub type LPCWSTR = *WCHAR;
|
||||
pub type LPCSTR = *CHAR;
|
||||
pub type LPCTSTR = *CHAR;
|
||||
pub type LPTCH = *CHAR;
|
||||
|
||||
pub type LPWSTR = *mut WCHAR;
|
||||
pub type LPSTR = *mut CHAR;
|
||||
|
@ -792,6 +794,7 @@ pub mod consts {
|
|||
|
||||
pub const ERROR_SUCCESS : int = 0;
|
||||
pub const ERROR_INSUFFICIENT_BUFFER : int = 122;
|
||||
pub const INVALID_HANDLE_VALUE: int = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1115,6 +1118,7 @@ pub mod funcs {
|
|||
pub mod string {
|
||||
use libc::types::common::c95::c_void;
|
||||
use libc::types::os::arch::c95::{c_char, c_int, size_t};
|
||||
use libc::types::os::arch::c95::{wchar_t};
|
||||
|
||||
pub extern {
|
||||
unsafe fn strcpy(dst: *c_char, src: *c_char) -> *c_char;
|
||||
|
@ -1138,6 +1142,7 @@ pub mod funcs {
|
|||
unsafe fn strtok(s: *c_char, t: *c_char) -> *c_char;
|
||||
unsafe fn strxfrm(s: *c_char, ct: *c_char, n: size_t)
|
||||
-> size_t;
|
||||
unsafe fn wcslen(buf: *wchar_t) -> size_t;
|
||||
|
||||
// These are fine to execute on the Rust stack. They must be,
|
||||
// in fact, because LLVM generates calls to them!
|
||||
|
@ -1381,9 +1386,28 @@ pub mod funcs {
|
|||
use libc::types::os::arch::c95::{c_char, c_int, c_long};
|
||||
|
||||
pub extern {
|
||||
// default bindings for opendir and readdir in
|
||||
// non-macos unix
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(target_os = "android")]
|
||||
#[cfg(target_os = "freebsd")]
|
||||
unsafe fn opendir(dirname: *c_char) -> *DIR;
|
||||
unsafe fn closedir(dirp: *DIR) -> c_int;
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(target_os = "android")]
|
||||
#[cfg(target_os = "freebsd")]
|
||||
unsafe fn readdir(dirp: *DIR) -> *dirent_t;
|
||||
// on OSX (particularly when running with a
|
||||
// 64bit kernel), we have an issue where there
|
||||
// are separate bindings for opendir and readdir,
|
||||
// which we have to explicitly link, as below.
|
||||
#[cfg(target_os = "macos")]
|
||||
#[link_name = "opendir$INODE64"]
|
||||
unsafe fn opendir(dirname: *c_char) -> *DIR;
|
||||
#[cfg(target_os = "macos")]
|
||||
#[link_name = "readdir$INODE64"]
|
||||
unsafe fn readdir(dirp: *DIR) -> *dirent_t;
|
||||
|
||||
unsafe fn closedir(dirp: *DIR) -> c_int;
|
||||
unsafe fn rewinddir(dirp: *DIR);
|
||||
unsafe fn seekdir(dirp: *DIR, loc: c_long);
|
||||
unsafe fn telldir(dirp: *DIR) -> c_long;
|
||||
|
@ -1594,8 +1618,9 @@ pub mod funcs {
|
|||
|
||||
pub mod kernel32 {
|
||||
use libc::types::os::arch::extra::{BOOL, DWORD, HMODULE};
|
||||
use libc::types::os::arch::extra::{LPCWSTR, LPWSTR};
|
||||
use libc::types::os::arch::extra::{LPCWSTR, LPWSTR, LPTCH};
|
||||
use libc::types::os::arch::extra::{LPSECURITY_ATTRIBUTES};
|
||||
use libc::types::os::arch::extra::{HANDLE};
|
||||
|
||||
#[abi = "stdcall"]
|
||||
pub extern {
|
||||
|
@ -1605,6 +1630,8 @@ pub mod funcs {
|
|||
-> DWORD;
|
||||
unsafe fn SetEnvironmentVariableW(n: LPCWSTR, v: LPCWSTR)
|
||||
-> BOOL;
|
||||
unsafe fn GetEnvironmentStringsA() -> LPTCH;
|
||||
unsafe fn FreeEnvironmentStringsA(env_ptr: LPTCH) -> BOOL;
|
||||
|
||||
unsafe fn GetModuleFileNameW(hModule: HMODULE,
|
||||
lpFilename: LPWSTR,
|
||||
|
@ -1623,6 +1650,13 @@ pub mod funcs {
|
|||
unsafe fn SetCurrentDirectoryW(lpPathName: LPCWSTR) -> BOOL;
|
||||
|
||||
unsafe fn GetLastError() -> DWORD;
|
||||
unsafe fn FindFirstFileW(fileName: *u16,
|
||||
findFileData: HANDLE)
|
||||
-> HANDLE;
|
||||
unsafe fn FindNextFileW(findFile: HANDLE,
|
||||
findFileData: HANDLE)
|
||||
-> BOOL;
|
||||
unsafe fn FindClose(findFile: HANDLE) -> BOOL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -58,20 +58,25 @@ pub mod rustrt {
|
|||
pub extern {
|
||||
unsafe fn rust_get_argc() -> c_int;
|
||||
unsafe fn rust_get_argv() -> **c_char;
|
||||
unsafe fn rust_getcwd() -> ~str;
|
||||
unsafe fn rust_path_is_dir(path: *libc::c_char) -> c_int;
|
||||
unsafe fn rust_path_exists(path: *libc::c_char) -> c_int;
|
||||
unsafe fn rust_list_files2(&&path: ~str) -> ~[~str];
|
||||
unsafe fn rust_process_wait(handle: c_int) -> c_int;
|
||||
unsafe fn rust_set_exit_status(code: libc::intptr_t);
|
||||
}
|
||||
}
|
||||
|
||||
pub const TMPBUF_SZ : uint = 1000u;
|
||||
const BUF_BYTES : uint = 2048u;
|
||||
|
||||
pub fn getcwd() -> Path {
|
||||
let buf = [0 as libc::c_char, ..BUF_BYTES];
|
||||
unsafe {
|
||||
Path(rustrt::rust_getcwd())
|
||||
if(0 as *libc::c_char == libc::getcwd(
|
||||
&buf[0],
|
||||
BUF_BYTES as libc::size_t)) {
|
||||
fail!();
|
||||
}
|
||||
Path(str::raw::from_c_str(&buf[0]))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -164,20 +169,68 @@ fn with_env_lock<T>(f: &fn() -> T) -> T {
|
|||
}
|
||||
|
||||
pub fn env() -> ~[(~str,~str)] {
|
||||
extern {
|
||||
unsafe fn rust_env_pairs() -> ~[~str];
|
||||
}
|
||||
|
||||
unsafe {
|
||||
do with_env_lock {
|
||||
#[cfg(windows)]
|
||||
unsafe fn get_env_pairs() -> ~[~str] {
|
||||
use libc::types::os::arch::extra::LPTCH;
|
||||
use libc::funcs::extra::kernel32::{
|
||||
GetEnvironmentStringsA,
|
||||
FreeEnvironmentStringsA
|
||||
};
|
||||
let ch = GetEnvironmentStringsA();
|
||||
if (ch as uint == 0) {
|
||||
fail!(fmt!("os::env() failure getting env string from OS: %s",
|
||||
os::last_os_error()));
|
||||
}
|
||||
let mut curr_ptr: uint = ch as uint;
|
||||
let mut result = ~[];
|
||||
while(*(curr_ptr as *libc::c_char) != 0 as libc::c_char) {
|
||||
let env_pair = str::raw::from_c_str(
|
||||
curr_ptr as *libc::c_char);
|
||||
result.push(env_pair);
|
||||
curr_ptr +=
|
||||
libc::strlen(curr_ptr as *libc::c_char) as uint
|
||||
+ 1;
|
||||
}
|
||||
FreeEnvironmentStringsA(ch);
|
||||
result
|
||||
}
|
||||
#[cfg(unix)]
|
||||
unsafe fn get_env_pairs() -> ~[~str] {
|
||||
extern mod rustrt {
|
||||
unsafe fn rust_env_pairs() -> **libc::c_char;
|
||||
}
|
||||
let environ = rustrt::rust_env_pairs();
|
||||
if (environ as uint == 0) {
|
||||
fail!(fmt!("os::env() failure getting env string from OS: %s",
|
||||
os::last_os_error()));
|
||||
}
|
||||
let mut result = ~[];
|
||||
ptr::array_each(environ, |e| {
|
||||
let env_pair = str::raw::from_c_str(e);
|
||||
log(debug, fmt!("get_env_pairs: %s",
|
||||
env_pair));
|
||||
result.push(env_pair);
|
||||
});
|
||||
result
|
||||
}
|
||||
|
||||
fn env_convert(input: ~[~str]) -> ~[(~str, ~str)] {
|
||||
let mut pairs = ~[];
|
||||
for vec::each(rust_env_pairs()) |p| {
|
||||
let vs = str::splitn_char(*p, '=', 1u);
|
||||
fail_unless!(vec::len(vs) == 2u);
|
||||
for input.each |p| {
|
||||
let vs = str::splitn_char(*p, '=', 1);
|
||||
log(debug,
|
||||
fmt!("splitting: len: %u",
|
||||
vs.len()));
|
||||
fail_unless!(vs.len() == 2);
|
||||
pairs.push((copy vs[0], copy vs[1]));
|
||||
}
|
||||
pairs
|
||||
}
|
||||
do with_env_lock {
|
||||
let unparsed_environ = get_env_pairs();
|
||||
env_convert(unparsed_environ)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -615,13 +668,97 @@ pub fn make_dir(p: &Path, mode: c_int) -> bool {
|
|||
#[allow(non_implicitly_copyable_typarams)]
|
||||
pub fn list_dir(p: &Path) -> ~[~str] {
|
||||
unsafe {
|
||||
#[cfg(unix)]
|
||||
fn star(p: &Path) -> Path { copy *p }
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(target_os = "android")]
|
||||
#[cfg(target_os = "freebsd")]
|
||||
#[cfg(target_os = "macos")]
|
||||
unsafe fn get_list(p: &Path) -> ~[~str] {
|
||||
use libc::{DIR, dirent_t};
|
||||
use libc::{opendir, readdir, closedir};
|
||||
extern mod rustrt {
|
||||
unsafe fn rust_list_dir_val(ptr: *dirent_t)
|
||||
-> *libc::c_char;
|
||||
}
|
||||
let input = p.to_str();
|
||||
let mut strings = ~[];
|
||||
let input_ptr = ::cast::transmute(&input[0]);
|
||||
log(debug, "os::list_dir -- BEFORE OPENDIR");
|
||||
let dir_ptr = opendir(input_ptr);
|
||||
if (dir_ptr as uint != 0) {
|
||||
log(debug, "os::list_dir -- opendir() SUCCESS");
|
||||
let mut entry_ptr = readdir(dir_ptr);
|
||||
while (entry_ptr as uint != 0) {
|
||||
strings.push(
|
||||
str::raw::from_c_str(
|
||||
rustrt::rust_list_dir_val(
|
||||
entry_ptr)));
|
||||
entry_ptr = readdir(dir_ptr);
|
||||
}
|
||||
closedir(dir_ptr);
|
||||
}
|
||||
else {
|
||||
log(debug, "os::list_dir -- opendir() FAILURE");
|
||||
}
|
||||
log(debug,
|
||||
fmt!("os::list_dir -- AFTER -- #: %?",
|
||||
strings.len()));
|
||||
strings
|
||||
}
|
||||
#[cfg(windows)]
|
||||
fn star(p: &Path) -> Path { p.push("*") }
|
||||
|
||||
do rustrt::rust_list_files2(star(p).to_str()).filtered |filename| {
|
||||
unsafe fn get_list(p: &Path) -> ~[~str] {
|
||||
use libc::types::os::arch::extra::{LPCTSTR, HANDLE, BOOL};
|
||||
use libc::consts::os::extra::INVALID_HANDLE_VALUE;
|
||||
use libc::wcslen;
|
||||
use libc::funcs::extra::kernel32::{
|
||||
FindFirstFileW,
|
||||
FindNextFileW,
|
||||
FindClose,
|
||||
};
|
||||
use os::win32::{
|
||||
as_utf16_p
|
||||
};
|
||||
use unstable::exchange_alloc::{malloc_raw, free_raw};
|
||||
#[nolink]
|
||||
extern mod rustrt {
|
||||
unsafe fn rust_list_dir_wfd_size() -> libc::size_t;
|
||||
unsafe fn rust_list_dir_wfd_fp_buf(wfd: *libc::c_void)
|
||||
-> *u16;
|
||||
}
|
||||
fn star(p: &Path) -> Path { p.push("*") }
|
||||
do as_utf16_p(star(p).to_str()) |path_ptr| {
|
||||
let mut strings = ~[];
|
||||
let wfd_ptr = malloc_raw(
|
||||
rustrt::rust_list_dir_wfd_size() as uint);
|
||||
let find_handle =
|
||||
FindFirstFileW(
|
||||
path_ptr,
|
||||
::cast::transmute(wfd_ptr));
|
||||
if find_handle as int != INVALID_HANDLE_VALUE {
|
||||
let mut more_files = 1 as libc::c_int;
|
||||
while more_files != 0 {
|
||||
let fp_buf = rustrt::rust_list_dir_wfd_fp_buf(
|
||||
wfd_ptr);
|
||||
if fp_buf as uint == 0 {
|
||||
fail!(~"os::list_dir() failure:"+
|
||||
~" got null ptr from wfd");
|
||||
}
|
||||
else {
|
||||
let fp_vec = vec::from_buf(
|
||||
fp_buf, wcslen(fp_buf) as uint);
|
||||
let fp_str = str::from_utf16(fp_vec);
|
||||
strings.push(fp_str);
|
||||
}
|
||||
more_files = FindNextFileW(
|
||||
find_handle,
|
||||
::cast::transmute(wfd_ptr));
|
||||
}
|
||||
FindClose(find_handle);
|
||||
free_raw(wfd_ptr);
|
||||
}
|
||||
strings
|
||||
}
|
||||
}
|
||||
do get_list(p).filtered |filename| {
|
||||
*filename != ~"." && *filename != ~".."
|
||||
}
|
||||
}
|
||||
|
@ -1274,9 +1411,8 @@ mod tests {
|
|||
setenv(~"USERPROFILE", ~"/home/PaloAlto");
|
||||
fail_unless!(os::homedir() == Some(Path("/home/MountainView")));
|
||||
|
||||
option::iter(&oldhome, |s| setenv(~"HOME", *s));
|
||||
option::iter(&olduserprofile,
|
||||
|s| setenv(~"USERPROFILE", *s));
|
||||
oldhome.each(|s| {setenv(~"HOME", *s);true});
|
||||
olduserprofile.each(|s| {setenv(~"USERPROFILE", *s);true});
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -19,6 +19,8 @@ use sys;
|
|||
#[cfg(test)] use vec;
|
||||
#[cfg(test)] use str;
|
||||
#[cfg(notest)] use cmp::{Eq, Ord};
|
||||
use debug;
|
||||
use uint;
|
||||
|
||||
pub mod libc_ {
|
||||
use libc::c_void;
|
||||
|
@ -181,6 +183,46 @@ pub pure fn ref_eq<T>(thing: &a/T, other: &b/T) -> bool {
|
|||
to_uint(thing) == to_uint(other)
|
||||
}
|
||||
|
||||
/**
|
||||
Given a **T (pointer to an array of pointers),
|
||||
iterate through each *T, up to the provided `len`,
|
||||
passing to the provided callback function
|
||||
|
||||
SAFETY NOTE: Pointer-arithmetic. Dragons be here.
|
||||
*/
|
||||
pub unsafe fn array_each_with_len<T>(arr: **T, len: uint, cb: &fn(*T)) {
|
||||
log(debug, "array_each_with_len: before iterate");
|
||||
if (arr as uint == 0) {
|
||||
fail!(~"ptr::array_each_with_len failure: arr input is null pointer");
|
||||
}
|
||||
//let start_ptr = *arr;
|
||||
uint::iterate(0, len, |e| {
|
||||
let n = offset(arr, e);
|
||||
cb(*n);
|
||||
true
|
||||
});
|
||||
log(debug, "array_each_with_len: after iterate");
|
||||
}
|
||||
|
||||
/**
|
||||
Given a null-pointer-terminated **T (pointer to
|
||||
an array of pointers), iterate through each *T,
|
||||
passing to the provided callback function
|
||||
|
||||
SAFETY NOTE: This will only work with a null-terminated
|
||||
pointer array. Barely less-dodgey Pointer Arithmetic.
|
||||
Dragons be here.
|
||||
*/
|
||||
pub unsafe fn array_each<T>(arr: **T, cb: &fn(*T)) {
|
||||
if (arr as uint == 0) {
|
||||
fail!(~"ptr::array_each_with_len failure: arr input is null pointer");
|
||||
}
|
||||
let len = buf_len(arr);
|
||||
log(debug, fmt!("array_each inferred len: %u",
|
||||
len));
|
||||
array_each_with_len(arr, len, cb);
|
||||
}
|
||||
|
||||
pub trait Ptr<T> {
|
||||
pure fn is_null(&self) -> bool;
|
||||
pure fn is_not_null(&self) -> bool;
|
||||
|
@ -389,3 +431,95 @@ pub fn test_is_null() {
|
|||
fail_unless!(!mq.is_null());
|
||||
fail_unless!(mq.is_not_null());
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub mod ptr_tests {
|
||||
use debug;
|
||||
use ptr;
|
||||
use str;
|
||||
use libc;
|
||||
use vec;
|
||||
#[test]
|
||||
pub fn test_ptr_array_each_with_len() {
|
||||
unsafe {
|
||||
let one = ~"oneOne";
|
||||
let two = ~"twoTwo";
|
||||
let three = ~"threeThree";
|
||||
let arr: ~[*i8] = ~[
|
||||
::cast::transmute(&one[0]),
|
||||
::cast::transmute(&two[0]),
|
||||
::cast::transmute(&three[0]),
|
||||
];
|
||||
let expected_arr = [
|
||||
one, two, three
|
||||
];
|
||||
let arr_ptr = &arr[0];
|
||||
let mut ctr = 0;
|
||||
let mut iteration_count = 0;
|
||||
ptr::array_each_with_len(arr_ptr, vec::len(arr),
|
||||
|e| {
|
||||
let actual = str::raw::from_c_str(e);
|
||||
let expected = copy expected_arr[ctr];
|
||||
log(debug,
|
||||
fmt!("test_ptr_array_each e: %s, a: %s",
|
||||
expected, actual));
|
||||
fail_unless!(actual == expected);
|
||||
ctr += 1;
|
||||
iteration_count += 1;
|
||||
});
|
||||
fail_unless!(iteration_count == 3u);
|
||||
}
|
||||
}
|
||||
#[test]
|
||||
pub fn test_ptr_array_each() {
|
||||
unsafe {
|
||||
let one = ~"oneOne";
|
||||
let two = ~"twoTwo";
|
||||
let three = ~"threeThree";
|
||||
let arr: ~[*i8] = ~[
|
||||
::cast::transmute(&one[0]),
|
||||
::cast::transmute(&two[0]),
|
||||
::cast::transmute(&three[0]),
|
||||
// fake a null terminator
|
||||
0 as *i8
|
||||
];
|
||||
let expected_arr = [
|
||||
one, two, three
|
||||
];
|
||||
let arr_ptr = &arr[0];
|
||||
let mut ctr = 0;
|
||||
let mut iteration_count = 0;
|
||||
ptr::array_each(arr_ptr, |e| {
|
||||
let actual = str::raw::from_c_str(e);
|
||||
let expected = copy expected_arr[ctr];
|
||||
log(debug,
|
||||
fmt!("test_ptr_array_each e: %s, a: %s",
|
||||
expected, actual));
|
||||
fail_unless!(actual == expected);
|
||||
ctr += 1;
|
||||
iteration_count += 1;
|
||||
});
|
||||
fail_unless!(iteration_count == 3);
|
||||
}
|
||||
}
|
||||
#[test]
|
||||
#[should_fail]
|
||||
#[ignore(cfg(windows))]
|
||||
pub fn test_ptr_array_each_with_len_null_ptr() {
|
||||
unsafe {
|
||||
ptr::array_each_with_len(0 as **libc::c_char, 1, |e| {
|
||||
str::raw::from_c_str(e);
|
||||
});
|
||||
}
|
||||
}
|
||||
#[test]
|
||||
#[should_fail]
|
||||
#[ignore(cfg(windows))]
|
||||
pub fn test_ptr_array_each_null_ptr() {
|
||||
unsafe {
|
||||
ptr::array_each(0 as **libc::c_char, |e| {
|
||||
str::raw::from_c_str(e);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,6 +41,17 @@ pub unsafe fn malloc(td: *TypeDesc, size: uint) -> *c_void {
|
|||
return transmute(box);
|
||||
}
|
||||
}
|
||||
/**
|
||||
Thin wrapper around libc::malloc, none of the box header
|
||||
stuff in exchange_alloc::malloc
|
||||
*/
|
||||
pub unsafe fn malloc_raw(size: uint) -> *c_void {
|
||||
let p = c_malloc(size as size_t);
|
||||
if p.is_null() {
|
||||
fail!(~"Failure in malloc_raw: result ptr is null");
|
||||
}
|
||||
p
|
||||
}
|
||||
|
||||
pub unsafe fn free(ptr: *c_void) {
|
||||
let exchange_count = &mut *rust_get_exchange_count_ptr();
|
||||
|
@ -49,6 +60,10 @@ pub unsafe fn free(ptr: *c_void) {
|
|||
fail_unless!(ptr.is_not_null());
|
||||
c_free(ptr);
|
||||
}
|
||||
///Thin wrapper around libc::free, as with exchange_alloc::malloc_raw
|
||||
pub unsafe fn free_raw(ptr: *c_void) {
|
||||
c_free(ptr);
|
||||
}
|
||||
|
||||
fn get_box_size(body_size: uint, body_align: uint) -> uint {
|
||||
let header_size = size_of::<BoxHeaderRepr>();
|
||||
|
|
|
@ -2692,6 +2692,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
#[should_fail]
|
||||
#[ignore(cfg(windows))]
|
||||
fn test_last_empty() {
|
||||
let a: ~[int] = ~[];
|
||||
a.last();
|
||||
|
|
|
@ -52,64 +52,18 @@ timegm(struct tm *tm)
|
|||
}
|
||||
#endif
|
||||
|
||||
extern "C" CDECL rust_str *
|
||||
rust_getcwd() {
|
||||
rust_task *task = rust_get_current_task();
|
||||
LOG(task, task, "rust_getcwd()");
|
||||
|
||||
char cbuf[BUF_BYTES];
|
||||
|
||||
#if defined(__WIN32__)
|
||||
if (!_getcwd(cbuf, sizeof(cbuf))) {
|
||||
#else
|
||||
if (!getcwd(cbuf, sizeof(cbuf))) {
|
||||
#endif
|
||||
task->fail();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return make_str(task->kernel, cbuf, strlen(cbuf), "rust_str(getcwd)");
|
||||
}
|
||||
|
||||
#if defined(__WIN32__)
|
||||
extern "C" CDECL rust_vec_box *
|
||||
extern "C" CDECL char**
|
||||
rust_env_pairs() {
|
||||
rust_task *task = rust_get_current_task();
|
||||
size_t envc = 0;
|
||||
LPTCH ch = GetEnvironmentStringsA();
|
||||
LPTCH c;
|
||||
for (c = ch; *c; c += strlen(c) + 1) {
|
||||
++envc;
|
||||
}
|
||||
c = ch;
|
||||
rust_vec_box *v = (rust_vec_box *)
|
||||
task->kernel->malloc(vec_size<rust_vec_box*>(envc),
|
||||
"str vec interior");
|
||||
v->body.fill = v->body.alloc = sizeof(rust_vec*) * envc;
|
||||
for (size_t i = 0; i < envc; ++i) {
|
||||
size_t n = strlen(c);
|
||||
rust_str *str = make_str(task->kernel, c, n, "str");
|
||||
((rust_str**)&v->body.data)[i] = str;
|
||||
c += n + 1;
|
||||
}
|
||||
if (ch) {
|
||||
FreeEnvironmentStrings(ch);
|
||||
}
|
||||
return v;
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
extern "C" CDECL rust_vec_box *
|
||||
extern "C" CDECL char**
|
||||
rust_env_pairs() {
|
||||
rust_task *task = rust_get_current_task();
|
||||
#ifdef __APPLE__
|
||||
char **environ = *_NSGetEnviron();
|
||||
#endif
|
||||
char **e = environ;
|
||||
size_t envc = 0;
|
||||
while (*e) {
|
||||
++envc; ++e;
|
||||
}
|
||||
return make_str_vec(task->kernel, envc, environ);
|
||||
return environ;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -293,49 +247,43 @@ debug_get_stk_seg() {
|
|||
return task->stk;
|
||||
}
|
||||
|
||||
extern "C" CDECL rust_vec_box*
|
||||
rust_list_files(rust_str *path) {
|
||||
rust_task *task = rust_get_current_task();
|
||||
array_list<rust_str*> strings;
|
||||
extern "C" CDECL char*
|
||||
#if defined(__WIN32__)
|
||||
WIN32_FIND_DATA FindFileData;
|
||||
HANDLE hFind = FindFirstFile((char*)path->body.data, &FindFileData);
|
||||
if (hFind != INVALID_HANDLE_VALUE) {
|
||||
do {
|
||||
rust_str *str = make_str(task->kernel, FindFileData.cFileName,
|
||||
strlen(FindFileData.cFileName),
|
||||
"list_files_str");
|
||||
strings.push(str);
|
||||
} while (FindNextFile(hFind, &FindFileData));
|
||||
FindClose(hFind);
|
||||
}
|
||||
rust_list_dir_val(WIN32_FIND_DATA* entry_ptr) {
|
||||
return entry_ptr->cFileName;
|
||||
}
|
||||
#else
|
||||
DIR *dirp = opendir((char*)path->body.data);
|
||||
if (dirp) {
|
||||
struct dirent *dp;
|
||||
while ((dp = readdir(dirp))) {
|
||||
rust_vec_box *str = make_str(task->kernel, dp->d_name,
|
||||
strlen(dp->d_name),
|
||||
"list_files_str");
|
||||
strings.push(str);
|
||||
}
|
||||
closedir(dirp);
|
||||
}
|
||||
rust_list_dir_val(dirent* entry_ptr) {
|
||||
return entry_ptr->d_name;
|
||||
}
|
||||
#endif
|
||||
|
||||
rust_vec_box *vec = (rust_vec_box *)
|
||||
task->kernel->malloc(vec_size<rust_vec_box*>(strings.size()),
|
||||
"list_files_vec");
|
||||
size_t alloc_sz = sizeof(rust_vec*) * strings.size();
|
||||
vec->body.fill = vec->body.alloc = alloc_sz;
|
||||
memcpy(&vec->body.data[0], strings.data(), alloc_sz);
|
||||
return vec;
|
||||
extern "C" CDECL size_t
|
||||
#if defined(__WIN32__)
|
||||
rust_list_dir_wfd_size() {
|
||||
return sizeof(WIN32_FIND_DATAW);
|
||||
}
|
||||
#else
|
||||
rust_list_dir_wfd_size() {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
extern "C" CDECL rust_vec_box*
|
||||
rust_list_files2(rust_str **path) {
|
||||
return rust_list_files(*path);
|
||||
extern "C" CDECL void*
|
||||
#if defined(__WIN32__)
|
||||
rust_list_dir_wfd_fp_buf(WIN32_FIND_DATAW* wfd) {
|
||||
if(wfd == NULL) {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
return wfd->cFileName;
|
||||
}
|
||||
}
|
||||
#else
|
||||
rust_list_dir_wfd_fp_buf(void* wfd) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
extern "C" CDECL int
|
||||
rust_path_is_dir(char *path) {
|
||||
|
|
|
@ -79,38 +79,6 @@ inline void reserve_vec_exact(rust_vec_box** vpp,
|
|||
|
||||
typedef rust_vec_box rust_str;
|
||||
|
||||
inline rust_str *
|
||||
make_str(rust_kernel* kernel, const char* c, size_t strlen,
|
||||
const char* name) {
|
||||
size_t str_fill = strlen + 1;
|
||||
size_t str_alloc = str_fill;
|
||||
rust_str *str = (rust_str *)
|
||||
kernel->malloc(vec_size<char>(str_fill), name);
|
||||
str->header.td = &str_body_tydesc;
|
||||
str->body.fill = str_fill;
|
||||
str->body.alloc = str_alloc;
|
||||
memcpy(&str->body.data, c, strlen);
|
||||
str->body.data[strlen] = '\0';
|
||||
return str;
|
||||
}
|
||||
|
||||
inline rust_vec_box *
|
||||
make_str_vec(rust_kernel* kernel, size_t nstrs, char **strs) {
|
||||
rust_vec_box *v = (rust_vec_box *)
|
||||
kernel->malloc(vec_size<rust_vec_box*>(nstrs),
|
||||
"str vec interior");
|
||||
// FIXME: should have a real td (Issue #2639)
|
||||
v->header.td = NULL;
|
||||
v->body.fill = v->body.alloc = sizeof(rust_vec_box*) * nstrs;
|
||||
for (size_t i = 0; i < nstrs; ++i) {
|
||||
rust_str *str = make_str(kernel, strs[i],
|
||||
strlen(strs[i]),
|
||||
"str");
|
||||
((rust_str**)&v->body.data)[i] = str;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
inline size_t get_box_size(size_t body_size, size_t body_align) {
|
||||
size_t header_size = sizeof(rust_opaque_box);
|
||||
// FIXME (#2699): This alignment calculation is suspicious. Is it right?
|
||||
|
|
|
@ -29,12 +29,12 @@ rust_new_task_in_sched
|
|||
rust_num_threads
|
||||
rust_path_is_dir
|
||||
rust_path_exists
|
||||
rust_getcwd
|
||||
rust_get_stdin
|
||||
rust_get_stdout
|
||||
rust_get_stderr
|
||||
rust_list_files
|
||||
rust_list_files2
|
||||
rust_list_dir_val
|
||||
rust_list_dir_wfd_size
|
||||
rust_list_dir_wfd_fp_buf
|
||||
rust_log_console_on
|
||||
rust_log_console_off
|
||||
rust_process_wait
|
||||
|
@ -43,7 +43,6 @@ rust_sched_current_nonlazy_threads
|
|||
rust_sched_threads
|
||||
rust_set_exit_status
|
||||
rust_start
|
||||
rust_getcwd
|
||||
rust_env_pairs
|
||||
rust_task_yield
|
||||
rust_task_is_unwinding
|
||||
|
|
|
@ -112,8 +112,8 @@ mod test_foreign_items {
|
|||
#[abi = "cdecl"]
|
||||
pub extern {
|
||||
#[cfg(bogus)]
|
||||
pub fn rust_getcwd() -> ~str;
|
||||
pub fn rust_getcwd() -> ~str;
|
||||
pub fn rust_get_stdin() -> ~str;
|
||||
pub fn rust_get_stdin() -> ~str;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@ mod rustrt {
|
|||
|
||||
pub fn rust_get_sched_id() -> libc::intptr_t;
|
||||
pub fn rust_get_argc() -> libc::c_int;
|
||||
pub fn rust_getcwd() -> ~str;
|
||||
pub fn get_task_id() -> libc::intptr_t;
|
||||
pub fn rust_sched_threads();
|
||||
pub fn rust_get_task();
|
||||
|
@ -26,7 +25,6 @@ mod rustrt {
|
|||
|
||||
fn calllink01() { unsafe { rustrt::rust_get_sched_id(); } }
|
||||
fn calllink02() { unsafe { rustrt::rust_get_argc(); } }
|
||||
fn calllink03() { unsafe { rustrt::rust_getcwd(); } }
|
||||
fn calllink08() { unsafe { rustrt::get_task_id(); } }
|
||||
fn calllink09() { unsafe { rustrt::rust_sched_threads(); } }
|
||||
fn calllink10() { unsafe { rustrt::rust_get_task(); } }
|
||||
|
@ -59,7 +57,6 @@ pub fn main() {
|
|||
let fns = ~[
|
||||
calllink01,
|
||||
calllink02,
|
||||
calllink03,
|
||||
calllink08,
|
||||
calllink09,
|
||||
calllink10
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue