1
Fork 0

std: Redesign c_str and c_vec

This commit is an implementation of [RFC 494][rfc] which removes the entire
`std::c_vec` module and redesigns the `std::c_str` module as `std::ffi`.

[rfc]: https://github.com/rust-lang/rfcs/blob/master/text/0494-c_str-and-c_vec-stability.md

The interface of the new `CString` is outlined in the linked RFC, the primary
changes being:

* The `ToCStr` trait is gone, meaning the `with_c_str` and `to_c_str` methods
  are now gone. These two methods are replaced with a `CString::from_slice`
  method.
* The `CString` type is now just a wrapper around `Vec<u8>` with a static
  guarantee that there is a trailing nul byte with no internal nul bytes. This
  means that `CString` now implements `Deref<Target = [c_char]>`, which is where
  it gains most of its methods from. A few helper methods are added to acquire a
  slice of `u8` instead of `c_char`, as well as including a slice with the
  trailing nul byte if necessary.
* All usage of non-owned `CString` values is now done via two functions inside
  of `std::ffi`, called `c_str_to_bytes` and `c_str_to_bytes_with_nul`. These
  functions are now the one method used to convert a `*const c_char` to a Rust
  slice of `u8`.

Many more details, including newly deprecated methods, can be found linked in
the RFC. This is a:

[breaking-change]
Closes #20444
This commit is contained in:
Alex Crichton 2014-11-25 13:28:35 -08:00
parent 1f732ef53d
commit ec7a50d20d
59 changed files with 1018 additions and 1998 deletions

View file

@ -12,7 +12,7 @@
use prelude::v1::*;
use c_str::{CString, ToCStr};
use ffi::{self, CString};
use io::{FilePermission, Write, UnstableFileStat, Open, FileAccess, FileMode};
use io::{IoResult, FileStat, SeekStyle};
use io::{Read, Truncate, SeekCur, SeekSet, ReadWrite, SeekEnd, Append};
@ -150,6 +150,10 @@ impl Drop for FileDesc {
}
}
fn cstr(path: &Path) -> CString {
CString::from_slice(path.as_vec())
}
pub fn open(path: &Path, fm: FileMode, fa: FileAccess) -> IoResult<FileDesc> {
let flags = match fm {
Open => 0,
@ -165,7 +169,7 @@ pub fn open(path: &Path, fm: FileMode, fa: FileAccess) -> IoResult<FileDesc> {
libc::S_IRUSR | libc::S_IWUSR),
};
let path = path.to_c_str();
let path = cstr(path);
match retry(|| unsafe { libc::open(path.as_ptr(), flags, mode) }) {
-1 => Err(super::last_error()),
fd => Ok(FileDesc::new(fd, true)),
@ -173,7 +177,7 @@ pub fn open(path: &Path, fm: FileMode, fa: FileAccess) -> IoResult<FileDesc> {
}
pub fn mkdir(p: &Path, mode: uint) -> IoResult<()> {
let p = p.to_c_str();
let p = cstr(p);
mkerr_libc(unsafe { libc::mkdir(p.as_ptr(), mode as libc::mode_t) })
}
@ -182,7 +186,6 @@ pub fn readdir(p: &Path) -> IoResult<Vec<Path>> {
use libc::{opendir, readdir_r, closedir};
fn prune(root: &CString, dirs: Vec<Path>) -> Vec<Path> {
let root = unsafe { CString::new(root.as_ptr(), false) };
let root = Path::new(root);
dirs.into_iter().filter(|path| {
@ -199,7 +202,7 @@ pub fn readdir(p: &Path) -> IoResult<Vec<Path>> {
let mut buf = Vec::<u8>::with_capacity(size as uint);
let ptr = buf.as_mut_ptr() as *mut dirent_t;
let p = p.to_c_str();
let p = CString::from_slice(p.as_vec());
let dir_ptr = unsafe {opendir(p.as_ptr())};
if dir_ptr as uint != 0 {
@ -207,10 +210,9 @@ pub fn readdir(p: &Path) -> IoResult<Vec<Path>> {
let mut entry_ptr = 0 as *mut dirent_t;
while unsafe { readdir_r(dir_ptr, ptr, &mut entry_ptr) == 0 } {
if entry_ptr.is_null() { break }
let cstr = unsafe {
CString::new(rust_list_dir_val(entry_ptr), false)
};
paths.push(Path::new(cstr));
paths.push(unsafe {
Path::new(ffi::c_str_to_bytes(&rust_list_dir_val(entry_ptr)))
});
}
assert_eq!(unsafe { closedir(dir_ptr) }, 0);
Ok(prune(&p, paths))
@ -220,39 +222,39 @@ pub fn readdir(p: &Path) -> IoResult<Vec<Path>> {
}
pub fn unlink(p: &Path) -> IoResult<()> {
let p = p.to_c_str();
let p = cstr(p);
mkerr_libc(unsafe { libc::unlink(p.as_ptr()) })
}
pub fn rename(old: &Path, new: &Path) -> IoResult<()> {
let old = old.to_c_str();
let new = new.to_c_str();
let old = cstr(old);
let new = cstr(new);
mkerr_libc(unsafe {
libc::rename(old.as_ptr(), new.as_ptr())
})
}
pub fn chmod(p: &Path, mode: uint) -> IoResult<()> {
let p = p.to_c_str();
let p = cstr(p);
mkerr_libc(retry(|| unsafe {
libc::chmod(p.as_ptr(), mode as libc::mode_t)
}))
}
pub fn rmdir(p: &Path) -> IoResult<()> {
let p = p.to_c_str();
let p = cstr(p);
mkerr_libc(unsafe { libc::rmdir(p.as_ptr()) })
}
pub fn chown(p: &Path, uid: int, gid: int) -> IoResult<()> {
let p = p.to_c_str();
let p = cstr(p);
mkerr_libc(retry(|| unsafe {
libc::chown(p.as_ptr(), uid as libc::uid_t, gid as libc::gid_t)
}))
}
pub fn readlink(p: &Path) -> IoResult<Path> {
let c_path = p.to_c_str();
let c_path = cstr(p);
let p = c_path.as_ptr();
let mut len = unsafe { libc::pathconf(p as *mut _, libc::_PC_NAME_MAX) };
if len == -1 {
@ -273,14 +275,14 @@ pub fn readlink(p: &Path) -> IoResult<Path> {
}
pub fn symlink(src: &Path, dst: &Path) -> IoResult<()> {
let src = src.to_c_str();
let dst = dst.to_c_str();
let src = cstr(src);
let dst = cstr(dst);
mkerr_libc(unsafe { libc::symlink(src.as_ptr(), dst.as_ptr()) })
}
pub fn link(src: &Path, dst: &Path) -> IoResult<()> {
let src = src.to_c_str();
let dst = dst.to_c_str();
let src = cstr(src);
let dst = cstr(dst);
mkerr_libc(unsafe { libc::link(src.as_ptr(), dst.as_ptr()) })
}
@ -328,7 +330,7 @@ fn mkstat(stat: &libc::stat) -> FileStat {
}
pub fn stat(p: &Path) -> IoResult<FileStat> {
let p = p.to_c_str();
let p = cstr(p);
let mut stat: libc::stat = unsafe { mem::zeroed() };
match unsafe { libc::stat(p.as_ptr(), &mut stat) } {
0 => Ok(mkstat(&stat)),
@ -337,7 +339,7 @@ pub fn stat(p: &Path) -> IoResult<FileStat> {
}
pub fn lstat(p: &Path) -> IoResult<FileStat> {
let p = p.to_c_str();
let p = cstr(p);
let mut stat: libc::stat = unsafe { mem::zeroed() };
match unsafe { libc::lstat(p.as_ptr(), &mut stat) } {
0 => Ok(mkstat(&stat)),
@ -346,7 +348,7 @@ pub fn lstat(p: &Path) -> IoResult<FileStat> {
}
pub fn utime(p: &Path, atime: u64, mtime: u64) -> IoResult<()> {
let p = p.to_c_str();
let p = cstr(p);
let buf = libc::utimbuf {
actime: (atime / 1000) as libc::time_t,
modtime: (mtime / 1000) as libc::time_t,