From b4d3b21850b054a81980616227c2742b10f9d696 Mon Sep 17 00:00:00 2001 From: Jeff Olson Date: Wed, 13 Feb 2013 23:00:34 -0800 Subject: [PATCH 1/8] rt/core: impl os::getcwd() in rust ref #4812 --- src/libcore/os.rs | 9 ++++++++- src/rt/rust_builtin.cpp | 19 ------------------- src/rt/rustrt.def.in | 2 -- 3 files changed, 8 insertions(+), 22 deletions(-) diff --git a/src/libcore/os.rs b/src/libcore/os.rs index 5c73e45364be7..afd21644fecbc 100644 --- a/src/libcore/os.rs +++ b/src/libcore/os.rs @@ -68,10 +68,17 @@ pub mod rustrt { } 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])) } } diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index 1243d82460346..750962b37e8f3 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -52,25 +52,6 @@ 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 * rust_env_pairs() { diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index fca10ac3ef49b..ddbd4729782eb 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -29,7 +29,6 @@ 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 @@ -43,7 +42,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 From 6f3465aaf593f3301624fa0633455b1aa3a0a46c Mon Sep 17 00:00:00 2001 From: Jeff Olson Date: Thu, 14 Feb 2013 22:16:53 -0800 Subject: [PATCH 2/8] core: rt/core: impl os::env() in rust ref #4812 --- src/libcore/libc.rs | 5 +- src/libcore/os.rs | 64 ++++++++++++++++--- src/libcore/ptr.rs | 132 ++++++++++++++++++++++++++++++++++++++++ src/rt/rust_builtin.cpp | 35 ++--------- 4 files changed, 196 insertions(+), 40 deletions(-) diff --git a/src/libcore/libc.rs b/src/libcore/libc.rs index b59824969bb85..9a45ffc5b2ebf 100644 --- a/src/libcore/libc.rs +++ b/src/libcore/libc.rs @@ -534,6 +534,7 @@ pub mod types { pub type LPCWSTR = *WCHAR; pub type LPCSTR = *CHAR; + pub type LPTCH = *CHAR; pub type LPWSTR = *mut WCHAR; pub type LPSTR = *mut CHAR; @@ -1594,7 +1595,7 @@ 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}; #[abi = "stdcall"] @@ -1605,6 +1606,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, diff --git a/src/libcore/os.rs b/src/libcore/os.rs index afd21644fecbc..5fd687ace3d96 100644 --- a/src/libcore/os.rs +++ b/src/libcore/os.rs @@ -171,20 +171,68 @@ fn with_env_lock(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())); + assert 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) + } } } diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index ebf41dc48f405..e5c2bb21eb7d0 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -18,6 +18,8 @@ use sys; #[cfg(test)] use vec; #[cfg(test)] use str; +#[cfg(test)] use uint; +#[cfg(test)] use debug; #[cfg(notest)] use cmp::{Eq, Ord}; pub mod libc_ { @@ -181,6 +183,46 @@ pub pure fn ref_eq(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(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(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 { pure fn is_null(&self) -> bool; pure fn is_not_null(&self) -> bool; @@ -389,3 +431,93 @@ 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)); + assert actual == expected; + ctr += 1; + iteration_count += 1; + }); + assert 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)); + assert actual == expected; + ctr += 1; + iteration_count += 1; + }); + assert iteration_count == 3; + } + } + #[test] + #[should_fail] + 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] + pub fn test_ptr_array_each_null_ptr() { + unsafe { + ptr::array_each(0 as **libc::c_char, |e| { + str::raw::from_c_str(e); + }); + } + } +} diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index 750962b37e8f3..2c9c4a706812f 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -53,44 +53,17 @@ timegm(struct tm *tm) #endif #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(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 From 2d25ea736ef952aa0d78145f0d855d22ca2ad620 Mon Sep 17 00:00:00 2001 From: Jeff Olson Date: Wed, 20 Feb 2013 22:46:26 -0800 Subject: [PATCH 3/8] rt/core: port os::list_dir to rust ref #4812 --- src/libcore/libc.rs | 33 +++++++- src/libcore/os.rs | 96 ++++++++++++++++++++++-- src/libcore/ptr.rs | 6 +- src/libcore/unstable/exchange_alloc.rs | 15 ++++ src/rt/rust_builtin.cpp | 66 ++++++++-------- src/rt/rust_util.h | 32 -------- src/rt/rustrt.def.in | 5 +- src/test/run-pass/conditional-compile.rs | 4 +- src/test/run-pass/morestack6.rs | 3 - 9 files changed, 174 insertions(+), 86 deletions(-) diff --git a/src/libcore/libc.rs b/src/libcore/libc.rs index 9a45ffc5b2ebf..7f293b98e24a9 100644 --- a/src/libcore/libc.rs +++ b/src/libcore/libc.rs @@ -534,6 +534,7 @@ pub mod types { pub type LPCWSTR = *WCHAR; pub type LPCSTR = *CHAR; + pub type LPCTSTR = *CHAR; pub type LPTCH = *CHAR; pub type LPWSTR = *mut WCHAR; @@ -793,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; } } @@ -1116,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; @@ -1139,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! @@ -1382,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; @@ -1597,6 +1620,7 @@ pub mod funcs { use libc::types::os::arch::extra::{BOOL, DWORD, HMODULE}; 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 { @@ -1626,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; } } diff --git a/src/libcore/os.rs b/src/libcore/os.rs index 5fd687ace3d96..9a52a4b1fe614 100644 --- a/src/libcore/os.rs +++ b/src/libcore/os.rs @@ -58,10 +58,8 @@ 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); } @@ -670,13 +668,95 @@ 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 ITERATION -- # of results: %?", 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 private::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 != ~".." } } diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index e5c2bb21eb7d0..2e962eb4cf164 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -18,9 +18,9 @@ use sys; #[cfg(test)] use vec; #[cfg(test)] use str; -#[cfg(test)] use uint; -#[cfg(test)] use debug; #[cfg(notest)] use cmp::{Eq, Ord}; +use debug; +use uint; pub mod libc_ { use libc::c_void; @@ -504,6 +504,7 @@ pub mod ptr_tests { } #[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| { @@ -513,6 +514,7 @@ pub mod ptr_tests { } #[test] #[should_fail] + #[ignore(cfg(windows))] pub fn test_ptr_array_each_null_ptr() { unsafe { ptr::array_each(0 as **libc::c_char, |e| { diff --git a/src/libcore/unstable/exchange_alloc.rs b/src/libcore/unstable/exchange_alloc.rs index a2815cebc51aa..3b4d86ba86b42 100644 --- a/src/libcore/unstable/exchange_alloc.rs +++ b/src/libcore/unstable/exchange_alloc.rs @@ -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::(); diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index 2c9c4a706812f..a621d61cdf792 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -247,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 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(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) { diff --git a/src/rt/rust_util.h b/src/rt/rust_util.h index fbedb9bc6efb2..101d04c880475 100644 --- a/src/rt/rust_util.h +++ b/src/rt/rust_util.h @@ -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(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(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? diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index ddbd4729782eb..284f827bc753a 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -32,8 +32,9 @@ rust_path_exists 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 diff --git a/src/test/run-pass/conditional-compile.rs b/src/test/run-pass/conditional-compile.rs index 0a579916e93ce..fa6f59999f84c 100644 --- a/src/test/run-pass/conditional-compile.rs +++ b/src/test/run-pass/conditional-compile.rs @@ -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; } } } diff --git a/src/test/run-pass/morestack6.rs b/src/test/run-pass/morestack6.rs index 9d210f2580b8b..7e0b4b47846e0 100644 --- a/src/test/run-pass/morestack6.rs +++ b/src/test/run-pass/morestack6.rs @@ -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 From e28af235c2726e646533d9e7dd52b1f3c34ee184 Mon Sep 17 00:00:00 2001 From: Jeff Olson Date: Wed, 6 Mar 2013 10:25:02 -0800 Subject: [PATCH 4/8] core: change import of exchange_alloc for win32 os::_list_dir --- src/libcore/os.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/os.rs b/src/libcore/os.rs index 9a52a4b1fe614..6048c8d86c520 100644 --- a/src/libcore/os.rs +++ b/src/libcore/os.rs @@ -715,7 +715,7 @@ pub fn list_dir(p: &Path) -> ~[~str] { use os::win32::{ as_utf16_p }; - use private::exchange_alloc::{malloc_raw, free_raw}; + use unstable::exchange_alloc::{malloc_raw, free_raw}; #[nolink] extern mod rustrt { unsafe fn rust_list_dir_wfd_size() -> libc::size_t; From 32a5ad84b5feb33119662272c6c82a92085dfb2f Mon Sep 17 00:00:00 2001 From: Jeff Olson Date: Wed, 6 Mar 2013 22:02:01 -0800 Subject: [PATCH 5/8] core: fix broken tests on windows --- src/libcore/os.rs | 5 ++--- src/libcore/vec.rs | 1 + 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libcore/os.rs b/src/libcore/os.rs index 6048c8d86c520..851368602f5a7 100644 --- a/src/libcore/os.rs +++ b/src/libcore/os.rs @@ -1409,9 +1409,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] diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs index 365de1ac3e2b9..3830b157c4176 100644 --- a/src/libcore/vec.rs +++ b/src/libcore/vec.rs @@ -2695,6 +2695,7 @@ mod tests { #[test] #[should_fail] + #[ignore(cfg(windows))] fn test_last_empty() { let a: ~[int] = ~[]; a.last(); From 3f346ed4646c790367e4c406b3c2a93fd2d7bacc Mon Sep 17 00:00:00 2001 From: Jeff Olson Date: Fri, 8 Mar 2013 12:47:34 -0800 Subject: [PATCH 6/8] core: formatting appeasement --- src/libcore/os.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/libcore/os.rs b/src/libcore/os.rs index 851368602f5a7..7e3c81889685e 100644 --- a/src/libcore/os.rs +++ b/src/libcore/os.rs @@ -685,7 +685,7 @@ pub fn list_dir(p: &Path) -> ~[~str] { 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"); + log(debug, "os::list_dir -- opendir() SUCCESS"); let mut entry_ptr = readdir(dir_ptr); while (entry_ptr as uint != 0) { strings.push( @@ -697,9 +697,11 @@ pub fn list_dir(p: &Path) -> ~[~str] { closedir(dir_ptr); } else { - log(debug, "os::list_dir -- opendir() FAILURE"); + log(debug, "os::list_dir -- opendir() FAILURE"); } - log(debug, fmt!("os::list_dir -- AFTER ITERATION -- # of results: %?", strings.len())); + log(debug, + fmt!("os::list_dir -- AFTER -- #: %?", + strings.len())); strings } #[cfg(windows)] From a8bdf411c4e876f66aaabe36475b9423eb2937be Mon Sep 17 00:00:00 2001 From: Jeff Olson Date: Fri, 8 Mar 2013 16:05:50 -0800 Subject: [PATCH 7/8] core: link pthreads explicitly in linux build --- src/libcore/core.rc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libcore/core.rc b/src/libcore/core.rc index 79a5d297178e3..eda5136ca9e85 100644 --- a/src/libcore/core.rc +++ b/src/libcore/core.rc @@ -56,6 +56,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 { } } From d21cc9995f18f5e87eb86d6e84c623c6c5eb7eb1 Mon Sep 17 00:00:00 2001 From: Jeff Olson Date: Fri, 8 Mar 2013 16:06:05 -0800 Subject: [PATCH 8/8] core: convert asserts to fail_unless! --- src/libcore/os.rs | 2 +- src/libcore/ptr.rs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libcore/os.rs b/src/libcore/os.rs index 7e3c81889685e..1dd40f3892d7f 100644 --- a/src/libcore/os.rs +++ b/src/libcore/os.rs @@ -222,7 +222,7 @@ pub fn env() -> ~[(~str,~str)] { log(debug, fmt!("splitting: len: %u", vs.len())); - assert vs.len() == 2; + fail_unless!(vs.len() == 2); pairs.push((copy vs[0], copy vs[1])); } pairs diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 2e962eb4cf164..5ebc1837392a4 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -463,11 +463,11 @@ pub mod ptr_tests { log(debug, fmt!("test_ptr_array_each e: %s, a: %s", expected, actual)); - assert actual == expected; + fail_unless!(actual == expected); ctr += 1; iteration_count += 1; }); - assert iteration_count == 3u; + fail_unless!(iteration_count == 3u); } } #[test] @@ -495,11 +495,11 @@ pub mod ptr_tests { log(debug, fmt!("test_ptr_array_each e: %s, a: %s", expected, actual)); - assert actual == expected; + fail_unless!(actual == expected); ctr += 1; iteration_count += 1; }); - assert iteration_count == 3; + fail_unless!(iteration_count == 3); } } #[test]