From 058346219a48ff6ac4c9c2fd38e8f478599ab078 Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Tue, 9 Apr 2013 22:18:23 -0500 Subject: [PATCH 1/3] libc bindings for glob.h only tested on linux/x86_64, but i got the values for other platforms from their system header files. no bindings for win32, because win32 doesn't include glob.h. also, glob() takes a callback for error handling, but i'm just making this a *c_void for now, since i don't know how to represent c calling back into rust (if that's even currently possible). --- src/libcore/libc.rs | 108 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 106 insertions(+), 2 deletions(-) diff --git a/src/libcore/libc.rs b/src/libcore/libc.rs index 44864630f987..b5c444dedf8a 100644 --- a/src/libcore/libc.rs +++ b/src/libcore/libc.rs @@ -104,6 +104,7 @@ pub use libc::funcs::posix88::unistd::*; pub use libc::funcs::posix01::stat_::*; pub use libc::funcs::posix01::unistd::*; +pub use libc::funcs::posix01::glob::*; pub use libc::funcs::posix08::unistd::*; pub use libc::funcs::bsd44::*; @@ -210,7 +211,21 @@ pub mod types { #[cfg(target_os = "android")] pub mod os { pub mod common { - pub mod posix01 {} + pub mod posix01 { + use libc::types::common::c95::{c_void}; + use libc::types::os::arch::c95::{c_char, size_t}; + pub struct glob_t { + gl_pathc: size_t, + gl_pathv: **c_char, + gl_offs: size_t, + + __unused1: *c_void, + __unused2: *c_void, + __unused3: *c_void, + __unused4: *c_void, + __unused5: *c_void, + } + } } #[cfg(target_arch = "x86")] @@ -369,7 +384,25 @@ pub mod types { #[cfg(target_os = "freebsd")] pub mod os { pub mod common { - pub mod posix01 {} + pub mod posix01 { + use libc::types::common::c95::{c_void}; + use libc::types::os::arch::c95::{c_char, c_int, size_t}; + struct glob_t { + gl_pathc: size_t, + __unused1: size_t, + gl_offs: size_t, + __unused2: c_int, + gl_pathv: **c_char, + + __unused3: *c_void, + + __unused4: *c_void, + __unused5: *c_void, + __unused6: *c_void, + __unused7: *c_void, + __unused8: *c_void, + } + } } #[cfg(target_arch = "x86_64")] @@ -571,6 +604,23 @@ pub mod types { pub mod os { pub mod common { pub mod posix01 { + use libc::types::common::c95::{c_void}; + use libc::types::os::arch::c95::{c_char, c_int, size_t}; + struct glob_t { + gl_pathc: size_t, + __unused1: c_int, + gl_offs: size_t, + __unused2: c_int, + gl_pathv: **c_char, + + __unused3: *c_void, + + __unused4: *c_void, + __unused5: *c_void, + __unused6: *c_void, + __unused7: *c_void, + __unused8: *c_void, + } } } @@ -877,6 +927,18 @@ pub mod consts { } pub mod posix01 { pub static SIGTRAP : int = 5; + + pub static GLOB_ERR : int = 1 << 0; + pub static GLOB_MARK : int = 1 << 1; + pub static GLOB_NOSORT : int = 1 << 2; + pub static GLOB_DOOFFS : int = 1 << 3; + pub static GLOB_NOCHECK : int = 1 << 4; + pub static GLOB_APPEND : int = 1 << 5; + pub static GLOB_NOESCAPE : int = 1 << 6; + + pub static GLOB_NOSPACE : int = 1; + pub static GLOB_ABORTED : int = 2; + pub static GLOB_NOMATCH : int = 3; } pub mod posix08 { } @@ -956,6 +1018,18 @@ pub mod consts { } pub mod posix01 { pub static SIGTRAP : int = 5; + + pub static GLOB_APPEND : int = 0x0001; + pub static GLOB_DOOFFS : int = 0x0002; + pub static GLOB_ERR : int = 0x0004; + pub static GLOB_MARK : int = 0x0008; + pub static GLOB_NOCHECK : int = 0x0010; + pub static GLOB_NOSORT : int = 0x0020; + pub static GLOB_NOESCAPE : int = 0x2000; + + pub static GLOB_NOSPACE : int = -1; + pub static GLOB_ABORTED : int = -2; + pub static GLOB_NOMATCH : int = -3; } pub mod posix08 { } @@ -1036,6 +1110,18 @@ pub mod consts { } pub mod posix01 { pub static SIGTRAP : int = 5; + + pub static GLOB_APPEND : int = 0x0001; + pub static GLOB_DOOFFS : int = 0x0002; + pub static GLOB_ERR : int = 0x0004; + pub static GLOB_MARK : int = 0x0008; + pub static GLOB_NOCHECK : int = 0x0010; + pub static GLOB_NOSORT : int = 0x0020; + pub static GLOB_NOESCAPE : int = 0x2000; + + pub static GLOB_NOSPACE : int = -1; + pub static GLOB_ABORTED : int = -2; + pub static GLOB_NOMATCH : int = -3; } pub mod posix08 { } @@ -1606,6 +1692,21 @@ pub mod funcs { -> pid_t; } } + + #[nolink] + #[abi = "cdecl"] + pub mod glob { + use libc::types::common::c95::{c_void}; + use libc::types::os::arch::c95::{c_char, c_int}; + use libc::types::os::common::posix01::{glob_t}; + + pub extern { + unsafe fn glob(pattern: *c_char, flags: c_int, + errfunc: *c_void, // XXX callback + pglob: *mut glob_t); + unsafe fn globfree(pglob: *mut glob_t); + } + } } #[cfg(target_os = "win32")] @@ -1615,6 +1716,9 @@ pub mod funcs { pub mod unistd { } + + pub mod glob { + } } From 685baed34ed2d5a94675bb5773c9f968ea133533 Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Wed, 10 Apr 2013 00:33:21 -0500 Subject: [PATCH 2/3] add a higher level glob() function to os this could probably use expansion - it just uses all of the default options, which is usually what we want, but not always. maybe add a separate function that takes more options? --- src/libcore/os.rs | 83 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/src/libcore/os.rs b/src/libcore/os.rs index 0455dabb7f01..8efae3e0e689 100644 --- a/src/libcore/os.rs +++ b/src/libcore/os.rs @@ -38,6 +38,7 @@ use ptr; use str; use task; use uint; +use unstable::finally::Finally; use vec; pub use libc::fclose; @@ -1183,6 +1184,88 @@ pub fn set_args(new_args: ~[~str]) { } } +// FIXME #6100 we should really use an internal implementation of this - using +// the POSIX glob functions isn't portable to windows, probably has slight +// inconsistencies even where it is implemented, and makes extending +// functionality a lot more difficult +// FIXME #6101 also provide a non-allocating version - each_glob or so? +/// Returns a vector of Path objects that match the given glob pattern +#[cfg(target_os = "linux")] +#[cfg(target_os = "android")] +#[cfg(target_os = "freebsd")] +#[cfg(target_os = "macos")] +pub fn glob(pattern: &str) -> ~[Path] { + #[cfg(target_os = "linux")] + #[cfg(target_os = "android")] + fn default_glob_t () -> libc::glob_t { + libc::glob_t { + gl_pathc: 0, + gl_pathv: ptr::null(), + gl_offs: 0, + __unused1: ptr::null(), + __unused2: ptr::null(), + __unused3: ptr::null(), + __unused4: ptr::null(), + __unused5: ptr::null(), + } + } + + #[cfg(target_os = "freebsd")] + fn default_glob_t () -> libc::glob_t { + libc::glob_t { + gl_pathc: 0, + __unused1: 0, + gl_offs: 0, + __unused2: 0, + gl_pathv: ptr::null(), + __unused3: ptr::null(), + __unused4: ptr::null(), + __unused5: ptr::null(), + __unused6: ptr::null(), + __unused7: ptr::null(), + __unused8: ptr::null(), + } + } + + #[cfg(target_os = "macos")] + fn default_glob_t () -> libc::glob_t { + libc::glob_t { + gl_pathc: 0, + __unused1: 0, + gl_offs: 0, + __unused2: 0, + gl_pathv: ptr::null(), + __unused3: ptr::null(), + __unused4: ptr::null(), + __unused5: ptr::null(), + __unused6: ptr::null(), + __unused7: ptr::null(), + __unused8: ptr::null(), + } + } + + let mut g = default_glob_t(); + do str::as_c_str(pattern) |c_pattern| { + unsafe { libc::glob(c_pattern, 0, ptr::null(), &mut g) } + }; + do(|| { + let paths = unsafe { + vec::raw::from_buf_raw(g.gl_pathv, g.gl_pathc as uint) + }; + do paths.map |&c_str| { + Path(unsafe { str::raw::from_c_str(c_str) }) + } + }).finally { + unsafe { libc::globfree(&mut g) }; + } +} + +/// Returns a vector of Path objects that match the given glob pattern +#[cfg(target_os = "win32")] +pub fn glob(pattern: &str) -> ~[Path] { + fail!(~"glob() is unimplemented on Windows") +} + #[cfg(target_os = "macos")] extern { // These functions are in crt_externs.h. From ed81e3353ea8d92b61669dc8d8692d5e9b01a8f4 Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Tue, 30 Apr 2013 22:26:43 -0500 Subject: [PATCH 3/3] glob_t should be public on all platforms --- src/libcore/libc.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/libc.rs b/src/libcore/libc.rs index b5c444dedf8a..999a5d9b350e 100644 --- a/src/libcore/libc.rs +++ b/src/libcore/libc.rs @@ -387,7 +387,7 @@ pub mod types { pub mod posix01 { use libc::types::common::c95::{c_void}; use libc::types::os::arch::c95::{c_char, c_int, size_t}; - struct glob_t { + pub struct glob_t { gl_pathc: size_t, __unused1: size_t, gl_offs: size_t, @@ -606,7 +606,7 @@ pub mod types { pub mod posix01 { use libc::types::common::c95::{c_void}; use libc::types::os::arch::c95::{c_char, c_int, size_t}; - struct glob_t { + pub struct glob_t { gl_pathc: size_t, __unused1: c_int, gl_offs: size_t,