auto merge of #14904 : huonw/rust/cstr-remove-withref, r=alexcrichton
This commit is contained in:
commit
b569c77148
@ -682,9 +682,9 @@ pub mod test {
|
||||
let two = "twoTwo".to_c_str();
|
||||
let three = "threeThree".to_c_str();
|
||||
let arr = vec![
|
||||
one.with_ref(|buf| buf),
|
||||
two.with_ref(|buf| buf),
|
||||
three.with_ref(|buf| buf)
|
||||
one.as_ptr(),
|
||||
two.as_ptr(),
|
||||
three.as_ptr()
|
||||
];
|
||||
let expected_arr = [
|
||||
one, two, three
|
||||
@ -694,9 +694,7 @@ pub mod test {
|
||||
let mut iteration_count = 0;
|
||||
array_each_with_len(arr.as_ptr(), arr.len(), |e| {
|
||||
let actual = str::raw::from_c_str(e);
|
||||
let expected = expected_arr[ctr].with_ref(|buf| {
|
||||
str::raw::from_c_str(buf)
|
||||
});
|
||||
let expected = str::raw::from_c_str(expected_arr[ctr].as_ptr());
|
||||
assert_eq!(actual.as_slice(), expected.as_slice());
|
||||
ctr += 1;
|
||||
iteration_count += 1;
|
||||
@ -712,9 +710,9 @@ pub mod test {
|
||||
let two = "twoTwo".to_c_str();
|
||||
let three = "threeThree".to_c_str();
|
||||
let arr = vec![
|
||||
one.with_ref(|buf| buf),
|
||||
two.with_ref(|buf| buf),
|
||||
three.with_ref(|buf| buf),
|
||||
one.as_ptr(),
|
||||
two.as_ptr(),
|
||||
three.as_ptr(),
|
||||
// fake a null terminator
|
||||
null()
|
||||
];
|
||||
@ -727,9 +725,7 @@ pub mod test {
|
||||
let mut iteration_count = 0u;
|
||||
array_each(arr_ptr, |e| {
|
||||
let actual = str::raw::from_c_str(e);
|
||||
let expected = expected_arr[ctr].with_ref(|buf| {
|
||||
str::raw::from_c_str(buf)
|
||||
});
|
||||
let expected = str::raw::from_c_str(expected_arr[ctr].as_ptr());
|
||||
assert_eq!(actual.as_slice(), expected.as_slice());
|
||||
ctr += 1;
|
||||
iteration_count += 1;
|
||||
|
@ -50,8 +50,8 @@ impl GetAddrInfoRequest {
|
||||
|
||||
// Make the call
|
||||
let s = unsafe {
|
||||
let ch = if c_host.is_null() { null() } else { c_host.with_ref(|x| x) };
|
||||
let cs = if c_serv.is_null() { null() } else { c_serv.with_ref(|x| x) };
|
||||
let ch = if c_host.is_null() { null() } else { c_host.as_ptr() };
|
||||
let cs = if c_serv.is_null() { null() } else { c_serv.as_ptr() };
|
||||
getaddrinfo(ch, cs, hint_ptr, &mut res)
|
||||
};
|
||||
|
||||
|
@ -339,7 +339,7 @@ pub fn open(path: &CString, fm: rtio::FileMode, fa: rtio::FileAccess)
|
||||
libc::S_IRUSR | libc::S_IWUSR),
|
||||
};
|
||||
|
||||
match retry(|| unsafe { libc::open(path.with_ref(|p| p), flags, mode) }) {
|
||||
match retry(|| unsafe { libc::open(path.as_ptr(), flags, mode) }) {
|
||||
-1 => Err(super::last_error()),
|
||||
fd => Ok(FileDesc::new(fd, true)),
|
||||
}
|
||||
@ -347,7 +347,7 @@ pub fn open(path: &CString, fm: rtio::FileMode, fa: rtio::FileAccess)
|
||||
|
||||
pub fn mkdir(p: &CString, mode: uint) -> IoResult<()> {
|
||||
super::mkerr_libc(retry(|| unsafe {
|
||||
libc::mkdir(p.with_ref(|p| p), mode as libc::mode_t)
|
||||
libc::mkdir(p.as_ptr(), mode as libc::mode_t)
|
||||
}))
|
||||
}
|
||||
|
||||
@ -356,7 +356,7 @@ pub fn readdir(p: &CString) -> IoResult<Vec<CString>> {
|
||||
use libc::{opendir, readdir_r, closedir};
|
||||
|
||||
fn prune(root: &CString, dirs: Vec<Path>) -> Vec<CString> {
|
||||
let root = unsafe { CString::new(root.with_ref(|p| p), false) };
|
||||
let root = unsafe { CString::new(root.as_ptr(), false) };
|
||||
let root = Path::new(root);
|
||||
|
||||
dirs.move_iter().filter(|path| {
|
||||
@ -373,7 +373,7 @@ pub fn readdir(p: &CString) -> IoResult<Vec<CString>> {
|
||||
let mut buf = Vec::<u8>::with_capacity(size as uint);
|
||||
let ptr = buf.as_mut_slice().as_mut_ptr() as *mut dirent_t;
|
||||
|
||||
let dir_ptr = p.with_ref(|buf| unsafe { opendir(buf) });
|
||||
let dir_ptr = unsafe {opendir(p.as_ptr())};
|
||||
|
||||
if dir_ptr as uint != 0 {
|
||||
let mut paths = vec!();
|
||||
@ -393,36 +393,36 @@ pub fn readdir(p: &CString) -> IoResult<Vec<CString>> {
|
||||
}
|
||||
|
||||
pub fn unlink(p: &CString) -> IoResult<()> {
|
||||
super::mkerr_libc(retry(|| unsafe { libc::unlink(p.with_ref(|p| p)) }))
|
||||
super::mkerr_libc(retry(|| unsafe { libc::unlink(p.as_ptr()) }))
|
||||
}
|
||||
|
||||
pub fn rename(old: &CString, new: &CString) -> IoResult<()> {
|
||||
super::mkerr_libc(retry(|| unsafe {
|
||||
libc::rename(old.with_ref(|p| p), new.with_ref(|p| p))
|
||||
libc::rename(old.as_ptr(), new.as_ptr())
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn chmod(p: &CString, mode: uint) -> IoResult<()> {
|
||||
super::mkerr_libc(retry(|| unsafe {
|
||||
libc::chmod(p.with_ref(|p| p), mode as libc::mode_t)
|
||||
libc::chmod(p.as_ptr(), mode as libc::mode_t)
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn rmdir(p: &CString) -> IoResult<()> {
|
||||
super::mkerr_libc(retry(|| unsafe {
|
||||
libc::rmdir(p.with_ref(|p| p))
|
||||
libc::rmdir(p.as_ptr())
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn chown(p: &CString, uid: int, gid: int) -> IoResult<()> {
|
||||
super::mkerr_libc(retry(|| unsafe {
|
||||
libc::chown(p.with_ref(|p| p), uid as libc::uid_t,
|
||||
libc::chown(p.as_ptr(), uid as libc::uid_t,
|
||||
gid as libc::gid_t)
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn readlink(p: &CString) -> IoResult<CString> {
|
||||
let p = p.with_ref(|p| p);
|
||||
let p = p.as_ptr();
|
||||
let mut len = unsafe { libc::pathconf(p as *mut _, libc::_PC_NAME_MAX) };
|
||||
if len == -1 {
|
||||
len = 1024; // FIXME: read PATH_MAX from C ffi?
|
||||
@ -443,13 +443,13 @@ pub fn readlink(p: &CString) -> IoResult<CString> {
|
||||
|
||||
pub fn symlink(src: &CString, dst: &CString) -> IoResult<()> {
|
||||
super::mkerr_libc(retry(|| unsafe {
|
||||
libc::symlink(src.with_ref(|p| p), dst.with_ref(|p| p))
|
||||
libc::symlink(src.as_ptr(), dst.as_ptr())
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn link(src: &CString, dst: &CString) -> IoResult<()> {
|
||||
super::mkerr_libc(retry(|| unsafe {
|
||||
libc::link(src.with_ref(|p| p), dst.with_ref(|p| p))
|
||||
libc::link(src.as_ptr(), dst.as_ptr())
|
||||
}))
|
||||
}
|
||||
|
||||
@ -489,7 +489,7 @@ fn mkstat(stat: &libc::stat) -> rtio::FileStat {
|
||||
|
||||
pub fn stat(p: &CString) -> IoResult<rtio::FileStat> {
|
||||
let mut stat: libc::stat = unsafe { mem::zeroed() };
|
||||
match retry(|| unsafe { libc::stat(p.with_ref(|p| p), &mut stat) }) {
|
||||
match retry(|| unsafe { libc::stat(p.as_ptr(), &mut stat) }) {
|
||||
0 => Ok(mkstat(&stat)),
|
||||
_ => Err(super::last_error()),
|
||||
}
|
||||
@ -497,7 +497,7 @@ pub fn stat(p: &CString) -> IoResult<rtio::FileStat> {
|
||||
|
||||
pub fn lstat(p: &CString) -> IoResult<rtio::FileStat> {
|
||||
let mut stat: libc::stat = unsafe { mem::zeroed() };
|
||||
match retry(|| unsafe { libc::lstat(p.with_ref(|p| p), &mut stat) }) {
|
||||
match retry(|| unsafe { libc::lstat(p.as_ptr(), &mut stat) }) {
|
||||
0 => Ok(mkstat(&stat)),
|
||||
_ => Err(super::last_error()),
|
||||
}
|
||||
@ -509,7 +509,7 @@ pub fn utime(p: &CString, atime: u64, mtime: u64) -> IoResult<()> {
|
||||
modtime: (mtime / 1000) as libc::time_t,
|
||||
};
|
||||
super::mkerr_libc(retry(|| unsafe {
|
||||
libc::utime(p.with_ref(|p| p), &buf)
|
||||
libc::utime(p.as_ptr(), &buf)
|
||||
}))
|
||||
}
|
||||
|
||||
|
@ -347,7 +347,7 @@ pub fn readdir(p: &CString) -> IoResult<Vec<CString>> {
|
||||
use std::rt::libc_heap::malloc_raw;
|
||||
|
||||
fn prune(root: &CString, dirs: Vec<Path>) -> Vec<CString> {
|
||||
let root = unsafe { CString::new(root.with_ref(|p| p), false) };
|
||||
let root = unsafe { CString::new(root.as_ptr(), false) };
|
||||
let root = Path::new(root);
|
||||
|
||||
dirs.move_iter().filter(|path| {
|
||||
@ -360,7 +360,7 @@ pub fn readdir(p: &CString) -> IoResult<Vec<CString>> {
|
||||
fn rust_list_dir_wfd_fp_buf(wfd: *mut libc::c_void) -> *const u16;
|
||||
}
|
||||
let star = Path::new(unsafe {
|
||||
CString::new(p.with_ref(|p| p), false)
|
||||
CString::new(p.as_ptr(), false)
|
||||
}).join("*");
|
||||
let path = try!(to_utf16(&star.to_c_str()));
|
||||
|
||||
|
@ -278,7 +278,7 @@ impl Drop for UnixListener {
|
||||
// careful to unlink the path before we close the file descriptor to
|
||||
// prevent races where we unlink someone else's path.
|
||||
unsafe {
|
||||
let _ = libc::unlink(self.path.with_ref(|p| p));
|
||||
let _ = libc::unlink(self.path.as_ptr());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -531,7 +531,7 @@ fn spawn_process_os(cfg: ProcessConfig,
|
||||
assert_eq!(ret, 0);
|
||||
}
|
||||
|
||||
let dirp = cfg.cwd.map(|c| c.with_ref(|p| p)).unwrap_or(ptr::null());
|
||||
let dirp = cfg.cwd.map(|c| c.as_ptr()).unwrap_or(ptr::null());
|
||||
|
||||
let cfg = unsafe {
|
||||
mem::transmute::<ProcessConfig,ProcessConfig<'static>>(cfg)
|
||||
@ -633,7 +633,7 @@ fn spawn_process_os(cfg: ProcessConfig,
|
||||
} else {
|
||||
libc::O_RDWR
|
||||
};
|
||||
devnull.with_ref(|p| libc::open(p, flags, 0))
|
||||
libc::open(devnull.as_ptr(), flags, 0)
|
||||
}
|
||||
Some(obj) => {
|
||||
let fd = obj.fd();
|
||||
@ -715,8 +715,8 @@ fn with_argv<T>(prog: &CString, args: &[CString],
|
||||
// larger than the lifetime of our invocation of cb, but this is
|
||||
// technically unsafe as the callback could leak these pointers
|
||||
// out of our scope.
|
||||
ptrs.push(prog.with_ref(|buf| buf));
|
||||
ptrs.extend(args.iter().map(|tmp| tmp.with_ref(|buf| buf)));
|
||||
ptrs.push(prog.as_ptr());
|
||||
ptrs.extend(args.iter().map(|tmp| tmp.as_ptr()));
|
||||
|
||||
// Add a terminating null pointer (required by libc).
|
||||
ptrs.push(ptr::null());
|
||||
|
@ -412,7 +412,7 @@ pub mod write {
|
||||
{
|
||||
let add = |arg: &str| {
|
||||
let s = arg.to_c_str();
|
||||
llvm_args.push(s.with_ref(|p| p));
|
||||
llvm_args.push(s.as_ptr());
|
||||
llvm_c_strs.push(s);
|
||||
};
|
||||
add("rustc"); // fake program name
|
||||
|
@ -94,7 +94,7 @@ pub fn run(sess: &session::Session, llmod: ModuleRef,
|
||||
// Internalize everything but the reachable symbols of the current module
|
||||
let cstrs: Vec<::std::c_str::CString> =
|
||||
reachable.iter().map(|s| s.as_slice().to_c_str()).collect();
|
||||
let arr: Vec<*const i8> = cstrs.iter().map(|c| c.with_ref(|p| p)).collect();
|
||||
let arr: Vec<*const i8> = cstrs.iter().map(|c| c.as_ptr()).collect();
|
||||
let ptr = arr.as_ptr();
|
||||
unsafe {
|
||||
llvm::LLVMRustRunRestrictionPass(llmod,
|
||||
|
@ -1433,24 +1433,23 @@ fn compile_unit_metadata(cx: &CrateContext) {
|
||||
let producer = format!("rustc version {}",
|
||||
(option_env!("CFG_VERSION")).expect("CFG_VERSION"));
|
||||
|
||||
compile_unit_name.with_ref(|compile_unit_name| {
|
||||
work_dir.as_vec().with_c_str(|work_dir| {
|
||||
producer.with_c_str(|producer| {
|
||||
"".with_c_str(|flags| {
|
||||
"".with_c_str(|split_name| {
|
||||
unsafe {
|
||||
llvm::LLVMDIBuilderCreateCompileUnit(
|
||||
debug_context(cx).builder,
|
||||
DW_LANG_RUST,
|
||||
compile_unit_name,
|
||||
work_dir,
|
||||
producer,
|
||||
cx.sess().opts.optimize != config::No,
|
||||
flags,
|
||||
0,
|
||||
split_name);
|
||||
}
|
||||
})
|
||||
let compile_unit_name = compile_unit_name.as_ptr();
|
||||
work_dir.as_vec().with_c_str(|work_dir| {
|
||||
producer.with_c_str(|producer| {
|
||||
"".with_c_str(|flags| {
|
||||
"".with_c_str(|split_name| {
|
||||
unsafe {
|
||||
llvm::LLVMDIBuilderCreateCompileUnit(
|
||||
debug_context(cx).builder,
|
||||
DW_LANG_RUST,
|
||||
compile_unit_name,
|
||||
work_dir,
|
||||
producer,
|
||||
cx.sess().opts.optimize != config::No,
|
||||
flags,
|
||||
0,
|
||||
split_name);
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -206,9 +206,7 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result {
|
||||
s.push_str(highlight::highlight(text.as_slice(), None, id)
|
||||
.as_slice());
|
||||
let output = s.to_c_str();
|
||||
output.with_ref(|r| {
|
||||
hoedown_buffer_puts(ob, r)
|
||||
})
|
||||
hoedown_buffer_puts(ob, output.as_ptr());
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -51,11 +51,11 @@ fn main() {
|
||||
// Allocate the C string with an explicit local that owns the string. The
|
||||
// `c_buffer` pointer will be deallocated when `my_c_string` goes out of scope.
|
||||
let my_c_string = my_string.to_c_str();
|
||||
my_c_string.with_ref(|c_buffer| {
|
||||
unsafe { puts(c_buffer); }
|
||||
});
|
||||
unsafe {
|
||||
puts(my_c_string.as_ptr());
|
||||
}
|
||||
|
||||
// Don't save off the allocation of the C string, the `c_buffer` will be
|
||||
// Don't save/return the pointer to the C string, the `c_buffer` will be
|
||||
// deallocated when this block returns!
|
||||
my_string.with_c_str(|c_buffer| {
|
||||
unsafe { puts(c_buffer); }
|
||||
@ -122,15 +122,71 @@ impl CString {
|
||||
CString { buf: buf, owns_buffer_: owns_buffer }
|
||||
}
|
||||
|
||||
/// Unwraps the wrapped `*libc::c_char` from the `CString` wrapper.
|
||||
/// Return a pointer to the NUL-terminated string data.
|
||||
///
|
||||
/// The original object is destructed after this method is called, and if
|
||||
/// the underlying pointer was previously allocated, care must be taken to
|
||||
/// ensure that it is deallocated properly.
|
||||
pub unsafe fn unwrap(self) -> *const libc::c_char {
|
||||
let mut c_str = self;
|
||||
c_str.owns_buffer_ = false;
|
||||
c_str.buf
|
||||
/// `.as_ptr` returns an internal pointer into the `CString`, and
|
||||
/// may be invalidated when the `CString` falls out of scope (the
|
||||
/// destructor will run, freeing the allocation if there is
|
||||
/// one).
|
||||
///
|
||||
/// ```rust
|
||||
/// let foo = "some string";
|
||||
///
|
||||
/// // right
|
||||
/// let x = foo.to_c_str();
|
||||
/// let p = x.as_ptr();
|
||||
///
|
||||
/// // wrong (the CString will be freed, invalidating `p`)
|
||||
/// let p = foo.to_c_str().as_ptr();
|
||||
/// ```
|
||||
///
|
||||
/// # Failure
|
||||
///
|
||||
/// Fails if the CString is null.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// extern crate libc;
|
||||
///
|
||||
/// fn main() {
|
||||
/// let c_str = "foo bar".to_c_str();
|
||||
/// unsafe {
|
||||
/// libc::puts(c_str.as_ptr());
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
pub fn as_ptr(&self) -> *const libc::c_char {
|
||||
if self.buf.is_null() { fail!("CString is null!"); }
|
||||
|
||||
self.buf
|
||||
}
|
||||
|
||||
/// Return a mutable pointer to the NUL-terminated string data.
|
||||
///
|
||||
/// `.as_mut_ptr` returns an internal pointer into the `CString`, and
|
||||
/// may be invalidated when the `CString` falls out of scope (the
|
||||
/// destructor will run, freeing the allocation if there is
|
||||
/// one).
|
||||
///
|
||||
/// ```rust
|
||||
/// let foo = "some string";
|
||||
///
|
||||
/// // right
|
||||
/// let mut x = foo.to_c_str();
|
||||
/// let p = x.as_mut_ptr();
|
||||
///
|
||||
/// // wrong (the CString will be freed, invalidating `p`)
|
||||
/// let p = foo.to_c_str().as_mut_ptr();
|
||||
/// ```
|
||||
///
|
||||
/// # Failure
|
||||
///
|
||||
/// Fails if the CString is null.
|
||||
pub fn as_mut_ptr(&mut self) -> *mut libc::c_char {
|
||||
if self.buf.is_null() { fail!("CString is null!") }
|
||||
|
||||
self.buf as *mut _
|
||||
}
|
||||
|
||||
/// Calls a closure with a reference to the underlying `*libc::c_char`.
|
||||
@ -138,6 +194,7 @@ impl CString {
|
||||
/// # Failure
|
||||
///
|
||||
/// Fails if the CString is null.
|
||||
#[deprecated="use `.as_ptr()`"]
|
||||
pub fn with_ref<T>(&self, f: |*const libc::c_char| -> T) -> T {
|
||||
if self.buf.is_null() { fail!("CString is null!"); }
|
||||
f(self.buf)
|
||||
@ -148,6 +205,7 @@ impl CString {
|
||||
/// # Failure
|
||||
///
|
||||
/// Fails if the CString is null.
|
||||
#[deprecated="use `.as_mut_ptr()`"]
|
||||
pub fn with_mut_ref<T>(&mut self, f: |*mut libc::c_char| -> T) -> T {
|
||||
if self.buf.is_null() { fail!("CString is null!"); }
|
||||
f(self.buf as *mut libc::c_char)
|
||||
@ -220,6 +278,22 @@ impl CString {
|
||||
marker: marker::ContravariantLifetime,
|
||||
}
|
||||
}
|
||||
|
||||
/// Unwraps the wrapped `*libc::c_char` from the `CString` wrapper.
|
||||
///
|
||||
/// Any ownership of the buffer by the `CString` wrapper is
|
||||
/// forgotten, meaning that the backing allocation of this
|
||||
/// `CString` is not automatically freed if it owns the
|
||||
/// allocation. In this case, a user of `.unwrap()` should ensure
|
||||
/// the allocation is freed, to avoid leaking memory.
|
||||
///
|
||||
/// Prefer `.as_ptr()` when just retrieving a pointer to the
|
||||
/// string data, as that does not relinquish ownership.
|
||||
pub unsafe fn unwrap(mut self) -> *const libc::c_char {
|
||||
self.owns_buffer_ = false;
|
||||
self.buf
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl Drop for CString {
|
||||
@ -285,13 +359,15 @@ pub trait ToCStr {
|
||||
/// Fails the task if the receiver has an interior null.
|
||||
#[inline]
|
||||
fn with_c_str<T>(&self, f: |*const libc::c_char| -> T) -> T {
|
||||
self.to_c_str().with_ref(f)
|
||||
let c_str = self.to_c_str();
|
||||
f(c_str.as_ptr())
|
||||
}
|
||||
|
||||
/// Unsafe variant of `with_c_str()` that doesn't check for nulls.
|
||||
#[inline]
|
||||
unsafe fn with_c_str_unchecked<T>(&self, f: |*const libc::c_char| -> T) -> T {
|
||||
self.to_c_str_unchecked().with_ref(f)
|
||||
let c_str = self.to_c_str_unchecked();
|
||||
f(c_str.as_ptr())
|
||||
}
|
||||
}
|
||||
|
||||
@ -353,7 +429,7 @@ static BUF_LEN: uint = 128;
|
||||
impl<'a> ToCStr for &'a [u8] {
|
||||
fn to_c_str(&self) -> CString {
|
||||
let mut cs = unsafe { self.to_c_str_unchecked() };
|
||||
cs.with_mut_ref(|buf| check_for_null(*self, buf));
|
||||
check_for_null(*self, cs.as_mut_ptr());
|
||||
cs
|
||||
}
|
||||
|
||||
@ -379,7 +455,7 @@ impl<'a> ToCStr for &'a [u8] {
|
||||
// Unsafe function that handles possibly copying the &[u8] into a stack array.
|
||||
unsafe fn with_c_str<T>(v: &[u8], checked: bool,
|
||||
f: |*const libc::c_char| -> T) -> T {
|
||||
if v.len() < BUF_LEN {
|
||||
let c_str = if v.len() < BUF_LEN {
|
||||
let mut buf: [u8, .. BUF_LEN] = mem::uninitialized();
|
||||
slice::bytes::copy_memory(buf, v);
|
||||
buf[v.len()] = 0;
|
||||
@ -389,12 +465,14 @@ unsafe fn with_c_str<T>(v: &[u8], checked: bool,
|
||||
check_for_null(v, buf as *mut libc::c_char);
|
||||
}
|
||||
|
||||
f(buf as *const libc::c_char)
|
||||
return f(buf as *const libc::c_char)
|
||||
} else if checked {
|
||||
v.to_c_str().with_ref(f)
|
||||
v.to_c_str()
|
||||
} else {
|
||||
v.to_c_str_unchecked().with_ref(f)
|
||||
}
|
||||
v.to_c_str_unchecked()
|
||||
};
|
||||
|
||||
f(c_str.as_ptr())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@ -482,53 +560,51 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_str_to_c_str() {
|
||||
"".to_c_str().with_ref(|buf| {
|
||||
unsafe {
|
||||
assert_eq!(*buf.offset(0), 0);
|
||||
}
|
||||
});
|
||||
let c_str = "".to_c_str();
|
||||
unsafe {
|
||||
assert_eq!(*c_str.as_ptr().offset(0), 0);
|
||||
}
|
||||
|
||||
"hello".to_c_str().with_ref(|buf| {
|
||||
unsafe {
|
||||
assert_eq!(*buf.offset(0), 'h' as libc::c_char);
|
||||
assert_eq!(*buf.offset(1), 'e' as libc::c_char);
|
||||
assert_eq!(*buf.offset(2), 'l' as libc::c_char);
|
||||
assert_eq!(*buf.offset(3), 'l' as libc::c_char);
|
||||
assert_eq!(*buf.offset(4), 'o' as libc::c_char);
|
||||
assert_eq!(*buf.offset(5), 0);
|
||||
}
|
||||
})
|
||||
let c_str = "hello".to_c_str();
|
||||
let buf = c_str.as_ptr();
|
||||
unsafe {
|
||||
assert_eq!(*buf.offset(0), 'h' as libc::c_char);
|
||||
assert_eq!(*buf.offset(1), 'e' as libc::c_char);
|
||||
assert_eq!(*buf.offset(2), 'l' as libc::c_char);
|
||||
assert_eq!(*buf.offset(3), 'l' as libc::c_char);
|
||||
assert_eq!(*buf.offset(4), 'o' as libc::c_char);
|
||||
assert_eq!(*buf.offset(5), 0);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_vec_to_c_str() {
|
||||
let b: &[u8] = [];
|
||||
b.to_c_str().with_ref(|buf| {
|
||||
unsafe {
|
||||
assert_eq!(*buf.offset(0), 0);
|
||||
}
|
||||
});
|
||||
let c_str = b.to_c_str();
|
||||
unsafe {
|
||||
assert_eq!(*c_str.as_ptr().offset(0), 0);
|
||||
}
|
||||
|
||||
let _ = b"hello".to_c_str().with_ref(|buf| {
|
||||
unsafe {
|
||||
assert_eq!(*buf.offset(0), 'h' as libc::c_char);
|
||||
assert_eq!(*buf.offset(1), 'e' as libc::c_char);
|
||||
assert_eq!(*buf.offset(2), 'l' as libc::c_char);
|
||||
assert_eq!(*buf.offset(3), 'l' as libc::c_char);
|
||||
assert_eq!(*buf.offset(4), 'o' as libc::c_char);
|
||||
assert_eq!(*buf.offset(5), 0);
|
||||
}
|
||||
});
|
||||
let c_str = b"hello".to_c_str();
|
||||
let buf = c_str.as_ptr();
|
||||
unsafe {
|
||||
assert_eq!(*buf.offset(0), 'h' as libc::c_char);
|
||||
assert_eq!(*buf.offset(1), 'e' as libc::c_char);
|
||||
assert_eq!(*buf.offset(2), 'l' as libc::c_char);
|
||||
assert_eq!(*buf.offset(3), 'l' as libc::c_char);
|
||||
assert_eq!(*buf.offset(4), 'o' as libc::c_char);
|
||||
assert_eq!(*buf.offset(5), 0);
|
||||
}
|
||||
|
||||
let _ = b"foo\xFF".to_c_str().with_ref(|buf| {
|
||||
unsafe {
|
||||
assert_eq!(*buf.offset(0), 'f' as libc::c_char);
|
||||
assert_eq!(*buf.offset(1), 'o' as libc::c_char);
|
||||
assert_eq!(*buf.offset(2), 'o' as libc::c_char);
|
||||
assert_eq!(*buf.offset(3), 0xff as i8);
|
||||
assert_eq!(*buf.offset(4), 0);
|
||||
}
|
||||
});
|
||||
let c_str = b"foo\xFF".to_c_str();
|
||||
let buf = c_str.as_ptr();
|
||||
unsafe {
|
||||
assert_eq!(*buf.offset(0), 'f' as libc::c_char);
|
||||
assert_eq!(*buf.offset(1), 'o' as libc::c_char);
|
||||
assert_eq!(*buf.offset(2), 'o' as libc::c_char);
|
||||
assert_eq!(*buf.offset(3), 0xffu8 as i8);
|
||||
assert_eq!(*buf.offset(4), 0);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -545,19 +621,18 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_with_ref() {
|
||||
fn test_as_ptr() {
|
||||
let c_str = "hello".to_c_str();
|
||||
let len = unsafe { c_str.with_ref(|buf| libc::strlen(buf)) };
|
||||
let len = unsafe { libc::strlen(c_str.as_ptr()) };
|
||||
assert!(!c_str.is_null());
|
||||
assert!(c_str.is_not_null());
|
||||
assert_eq!(len, 5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_fail]
|
||||
fn test_with_ref_empty_fail() {
|
||||
fn test_as_ptr_empty_fail() {
|
||||
let c_str = unsafe { CString::new(ptr::null(), false) };
|
||||
c_str.with_ref(|_| ());
|
||||
c_str.as_ptr();
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -584,15 +659,15 @@ mod tests {
|
||||
#[test]
|
||||
fn test_to_c_str_unchecked() {
|
||||
unsafe {
|
||||
"he\x00llo".to_c_str_unchecked().with_ref(|buf| {
|
||||
assert_eq!(*buf.offset(0), 'h' as libc::c_char);
|
||||
assert_eq!(*buf.offset(1), 'e' as libc::c_char);
|
||||
assert_eq!(*buf.offset(2), 0);
|
||||
assert_eq!(*buf.offset(3), 'l' as libc::c_char);
|
||||
assert_eq!(*buf.offset(4), 'l' as libc::c_char);
|
||||
assert_eq!(*buf.offset(5), 'o' as libc::c_char);
|
||||
assert_eq!(*buf.offset(6), 0);
|
||||
})
|
||||
let c_string = "he\x00llo".to_c_str_unchecked();
|
||||
let buf = c_string.as_ptr();
|
||||
assert_eq!(*buf.offset(0), 'h' as libc::c_char);
|
||||
assert_eq!(*buf.offset(1), 'e' as libc::c_char);
|
||||
assert_eq!(*buf.offset(2), 0);
|
||||
assert_eq!(*buf.offset(3), 'l' as libc::c_char);
|
||||
assert_eq!(*buf.offset(4), 'l' as libc::c_char);
|
||||
assert_eq!(*buf.offset(5), 'o' as libc::c_char);
|
||||
assert_eq!(*buf.offset(6), 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -675,10 +750,10 @@ mod tests {
|
||||
let s = "test".to_string();
|
||||
let c = s.to_c_str();
|
||||
// give the closure a non-owned CString
|
||||
let mut c_ = c.with_ref(|c| unsafe { CString::new(c, false) } );
|
||||
let mut c_ = unsafe { CString::new(c.as_ptr(), false) };
|
||||
f(&c_);
|
||||
// muck with the buffer for later printing
|
||||
c_.with_mut_ref(|c| unsafe { *c = 'X' as libc::c_char } );
|
||||
unsafe { *c_.as_mut_ptr() = 'X' as libc::c_char }
|
||||
}
|
||||
|
||||
let mut c_: Option<CString> = None;
|
||||
@ -732,7 +807,7 @@ mod bench {
|
||||
fn bench_to_str(b: &mut Bencher, s: &str) {
|
||||
b.iter(|| {
|
||||
let c_str = s.to_c_str();
|
||||
c_str.with_ref(|c_str_buf| check(s, c_str_buf))
|
||||
check(s, c_str.as_ptr());
|
||||
})
|
||||
}
|
||||
|
||||
@ -754,7 +829,7 @@ mod bench {
|
||||
fn bench_to_c_str_unchecked(b: &mut Bencher, s: &str) {
|
||||
b.iter(|| {
|
||||
let c_str = unsafe { s.to_c_str_unchecked() };
|
||||
c_str.with_ref(|c_str_buf| check(s, c_str_buf))
|
||||
check(s, c_str.as_ptr())
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,7 @@ impl GetAddrInfoRequest {
|
||||
let (_c_node, c_node_ptr) = match node {
|
||||
Some(n) => {
|
||||
let c_node = n.to_c_str();
|
||||
let c_node_ptr = c_node.with_ref(|r| r);
|
||||
let c_node_ptr = c_node.as_ptr();
|
||||
(Some(c_node), c_node_ptr)
|
||||
}
|
||||
None => (None, null())
|
||||
@ -49,7 +49,7 @@ impl GetAddrInfoRequest {
|
||||
let (_c_service, c_service_ptr) = match service {
|
||||
Some(s) => {
|
||||
let c_service = s.to_c_str();
|
||||
let c_service_ptr = c_service.with_ref(|r| r);
|
||||
let c_service_ptr = c_service.as_ptr();
|
||||
(Some(c_service), c_service_ptr)
|
||||
}
|
||||
None => (None, null())
|
||||
|
@ -41,7 +41,7 @@ impl FsRequest {
|
||||
{
|
||||
execute(|req, cb| unsafe {
|
||||
uvll::uv_fs_open(io.uv_loop(),
|
||||
req, path.with_ref(|p| p), flags as c_int,
|
||||
req, path.as_ptr(), flags as c_int,
|
||||
mode as c_int, cb)
|
||||
}).map(|req|
|
||||
FileWatcher::new(io, req.get_result() as c_int,
|
||||
@ -51,7 +51,7 @@ impl FsRequest {
|
||||
|
||||
pub fn unlink(loop_: &Loop, path: &CString) -> Result<(), UvError> {
|
||||
execute_nop(|req, cb| unsafe {
|
||||
uvll::uv_fs_unlink(loop_.handle, req, path.with_ref(|p| p),
|
||||
uvll::uv_fs_unlink(loop_.handle, req, path.as_ptr(),
|
||||
cb)
|
||||
})
|
||||
}
|
||||
@ -60,14 +60,14 @@ impl FsRequest {
|
||||
-> Result<rtio::FileStat, UvError>
|
||||
{
|
||||
execute(|req, cb| unsafe {
|
||||
uvll::uv_fs_lstat(loop_.handle, req, path.with_ref(|p| p),
|
||||
uvll::uv_fs_lstat(loop_.handle, req, path.as_ptr(),
|
||||
cb)
|
||||
}).map(|req| req.mkstat())
|
||||
}
|
||||
|
||||
pub fn stat(loop_: &Loop, path: &CString) -> Result<rtio::FileStat, UvError> {
|
||||
execute(|req, cb| unsafe {
|
||||
uvll::uv_fs_stat(loop_.handle, req, path.with_ref(|p| p),
|
||||
uvll::uv_fs_stat(loop_.handle, req, path.as_ptr(),
|
||||
cb)
|
||||
}).map(|req| req.mkstat())
|
||||
}
|
||||
@ -125,14 +125,14 @@ impl FsRequest {
|
||||
-> Result<(), UvError>
|
||||
{
|
||||
execute_nop(|req, cb| unsafe {
|
||||
uvll::uv_fs_mkdir(loop_.handle, req, path.with_ref(|p| p),
|
||||
uvll::uv_fs_mkdir(loop_.handle, req, path.as_ptr(),
|
||||
mode, cb)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn rmdir(loop_: &Loop, path: &CString) -> Result<(), UvError> {
|
||||
execute_nop(|req, cb| unsafe {
|
||||
uvll::uv_fs_rmdir(loop_.handle, req, path.with_ref(|p| p),
|
||||
uvll::uv_fs_rmdir(loop_.handle, req, path.as_ptr(),
|
||||
cb)
|
||||
})
|
||||
}
|
||||
@ -143,8 +143,8 @@ impl FsRequest {
|
||||
execute_nop(|req, cb| unsafe {
|
||||
uvll::uv_fs_rename(loop_.handle,
|
||||
req,
|
||||
path.with_ref(|p| p),
|
||||
to.with_ref(|p| p),
|
||||
path.as_ptr(),
|
||||
to.as_ptr(),
|
||||
cb)
|
||||
})
|
||||
}
|
||||
@ -153,7 +153,7 @@ impl FsRequest {
|
||||
-> Result<(), UvError>
|
||||
{
|
||||
execute_nop(|req, cb| unsafe {
|
||||
uvll::uv_fs_chmod(loop_.handle, req, path.with_ref(|p| p),
|
||||
uvll::uv_fs_chmod(loop_.handle, req, path.as_ptr(),
|
||||
mode, cb)
|
||||
})
|
||||
}
|
||||
@ -163,10 +163,10 @@ impl FsRequest {
|
||||
{
|
||||
execute(|req, cb| unsafe {
|
||||
uvll::uv_fs_readdir(loop_.handle,
|
||||
req, path.with_ref(|p| p), flags, cb)
|
||||
req, path.as_ptr(), flags, cb)
|
||||
}).map(|req| unsafe {
|
||||
let mut paths = vec!();
|
||||
let path = CString::new(path.with_ref(|p| p), false);
|
||||
let path = CString::new(path.as_ptr(), false);
|
||||
let parent = Path::new(path);
|
||||
let _ = c_str::from_c_multistring(req.get_ptr() as *const libc::c_char,
|
||||
Some(req.get_result() as uint),
|
||||
@ -181,7 +181,7 @@ impl FsRequest {
|
||||
pub fn readlink(loop_: &Loop, path: &CString) -> Result<CString, UvError> {
|
||||
execute(|req, cb| unsafe {
|
||||
uvll::uv_fs_readlink(loop_.handle, req,
|
||||
path.with_ref(|p| p), cb)
|
||||
path.as_ptr(), cb)
|
||||
}).map(|req| {
|
||||
// Be sure to clone the cstring so we get an independently owned
|
||||
// allocation to work with and return.
|
||||
@ -196,7 +196,7 @@ impl FsRequest {
|
||||
{
|
||||
execute_nop(|req, cb| unsafe {
|
||||
uvll::uv_fs_chown(loop_.handle,
|
||||
req, path.with_ref(|p| p),
|
||||
req, path.as_ptr(),
|
||||
uid as uvll::uv_uid_t,
|
||||
gid as uvll::uv_gid_t,
|
||||
cb)
|
||||
@ -216,8 +216,8 @@ impl FsRequest {
|
||||
{
|
||||
execute_nop(|req, cb| unsafe {
|
||||
uvll::uv_fs_link(loop_.handle, req,
|
||||
src.with_ref(|p| p),
|
||||
dst.with_ref(|p| p),
|
||||
src.as_ptr(),
|
||||
dst.as_ptr(),
|
||||
cb)
|
||||
})
|
||||
}
|
||||
@ -227,8 +227,8 @@ impl FsRequest {
|
||||
{
|
||||
execute_nop(|req, cb| unsafe {
|
||||
uvll::uv_fs_symlink(loop_.handle, req,
|
||||
src.with_ref(|p| p),
|
||||
dst.with_ref(|p| p),
|
||||
src.as_ptr(),
|
||||
dst.as_ptr(),
|
||||
0, cb)
|
||||
})
|
||||
}
|
||||
@ -252,7 +252,7 @@ impl FsRequest {
|
||||
let atime = atime as libc::c_double / 1000.0;
|
||||
let mtime = mtime as libc::c_double / 1000.0;
|
||||
execute_nop(|req, cb| unsafe {
|
||||
uvll::uv_fs_utime(loop_.handle, req, path.with_ref(|p| p),
|
||||
uvll::uv_fs_utime(loop_.handle, req, path.as_ptr(),
|
||||
atime, mtime, cb)
|
||||
})
|
||||
}
|
||||
|
@ -94,7 +94,7 @@ impl PipeWatcher {
|
||||
cx.connect(pipe, timeout, io, |req, pipe, cb| {
|
||||
unsafe {
|
||||
uvll::uv_pipe_connect(req.handle, pipe.handle(),
|
||||
name.with_ref(|p| p), cb)
|
||||
name.as_ptr(), cb)
|
||||
}
|
||||
0
|
||||
})
|
||||
@ -227,7 +227,7 @@ impl PipeListener {
|
||||
{
|
||||
let pipe = PipeWatcher::new(io, false);
|
||||
match unsafe {
|
||||
uvll::uv_pipe_bind(pipe.handle(), name.with_ref(|p| p))
|
||||
uvll::uv_pipe_bind(pipe.handle(), name.as_ptr())
|
||||
} {
|
||||
0 => {
|
||||
// If successful, unwrap the PipeWatcher because we control how
|
||||
|
@ -85,7 +85,7 @@ impl Process {
|
||||
args: argv,
|
||||
env: envp,
|
||||
cwd: match cfg.cwd {
|
||||
Some(cwd) => cwd.with_ref(|p| p),
|
||||
Some(cwd) => cwd.as_ptr(),
|
||||
None => ptr::null(),
|
||||
},
|
||||
flags: flags as libc::c_uint,
|
||||
@ -183,8 +183,8 @@ fn with_argv<T>(prog: &CString, args: &[CString],
|
||||
// larger than the lifetime of our invocation of cb, but this is
|
||||
// technically unsafe as the callback could leak these pointers
|
||||
// out of our scope.
|
||||
ptrs.push(prog.with_ref(|buf| buf));
|
||||
ptrs.extend(args.iter().map(|tmp| tmp.with_ref(|buf| buf)));
|
||||
ptrs.push(prog.as_ptr());
|
||||
ptrs.extend(args.iter().map(|tmp| tmp.as_ptr()));
|
||||
|
||||
// Add a terminating null pointer (required by libc).
|
||||
ptrs.push(ptr::null());
|
||||
|
@ -24,6 +24,6 @@ pub fn main() {
|
||||
assert!(*(&B[0] as *const u8) == A[0]);
|
||||
|
||||
let bar = str::raw::from_utf8(A).to_c_str();
|
||||
assert_eq!(bar.with_ref(|buf| str::raw::from_c_str(buf)), "hi".to_string());
|
||||
assert_eq!(str::raw::from_c_str(bar.as_ptr()), "hi".to_string());
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user