auto merge of #9497 : pnkfelix/rust/fsk-7752-use-fcnptr-for-glob-errfunc, r=cmr

Fix #7752.

~~(The glob API is a little funky; I tried to make a small test for it, which I'll add to the end of this description, and its not clear whether globfree is supposed to free solely the structure allocated by glob itself, or if it is going to try to free more than that.)~~ (The previous note was a user-error: I was misusing the CString API.)

Anyway, this seems to work in terms of calling errfunc where expected.)

```rust
#[allow(unused_imports)];
use std::libc::types::os::arch::c95::{c_char, c_int, size_t};
use std::libc::funcs::posix01::glob;
use std::libc::types::os::common::posix01::glob_t;
use std::libc::consts::os::posix01::{GLOB_APPEND, GLOB_DOOFFS, GLOB_ERR,
                                     GLOB_MARK, GLOB_NOCHECK, GLOB_NOSORT,
                                     GLOB_NOESCAPE, GLOB_NOSPACE,
                                     GLOB_ABORTED, GLOB_NOMATCH};
use std::ptr;
use std::c_str;

#[fixed_stack_segment]
fn main() {
    let mut g = glob_t {
        gl_pathc:  0, // size_t,
        __unused1: 0, // c_int,
        gl_offs:   2, // size_t,
        __unused2: 0, // c_int,
        gl_pathv:  ptr::null(), // **c_char,

        __unused3: ptr::null(), // *c_void,

        __unused4: ptr::null(), // *c_void,
        __unused5: ptr::null(), // *c_void,
        __unused6: ptr::null(), // *c_void,
        __unused7: ptr::null(), // *c_void,
        __unused8: ptr::null(), // *c_void,
    };

    extern "C" fn errfunc(_epath: *c_char, _errno: int) -> int {
        println!("errfunc called");
        return 0;
    }

    struct Reduced { pathc: size_t, offs: size_t, pathv: **c_char, }
    impl Reduced {
        fn from(g: &glob_t) -> Reduced {
            Reduced {pathc: g.gl_pathc, offs: g.gl_offs, pathv: g.gl_pathv}
        }
    }

    do ("*.rs/*").with_c_str |pat| {
        println!("calling glob");
        unsafe { glob::glob(pat, GLOB_DOOFFS, errfunc, &mut g); }
        println!("After glob call");

        println!("g: {:?}", Reduced::from(&g));
        for i in range(0, g.gl_pathc as int) {
            unsafe {
                let p : **c_char = ptr::offset(g.gl_pathv, g.gl_offs as int + i);
                let x = c_str::CString::new(*p, false);
                match x.as_str() {
                    Some(s) => {
                        println!("gl_pathc[{:d}]: {:?}", i, s);
                    }
                    None => {
                        println!("gl_pathc[{:d}]: unvalid", i);
                    }
                }
            }
        }
    }

    println!("calling globfree on g: {:?}", g);
    unsafe { glob::globfree(&mut g); }
    println!("after globfree call");

}

```
This commit is contained in:
bors 2013-09-26 04:16:03 -07:00
commit 930f7790fb

View File

@ -3224,14 +3224,14 @@ pub mod funcs {
#[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};
use option::Option;
extern {
pub fn glob(pattern: *c_char,
flags: c_int,
errfunc: *c_void, // XXX callback
errfunc: Option<extern "C" fn(epath: *c_char, errno: int) -> int>,
pglob: *mut glob_t);
pub fn globfree(pglob: *mut glob_t);
}