about summary refs log tree commit diff
path: root/src/libstd/sys
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2014-11-25 13:28:35 -0800
committerAlex Crichton <alex@alexcrichton.com>2015-01-05 08:00:13 -0800
commitec7a50d20dff416d9fec837a6492dfe244f5f3ab (patch)
tree559c2e05abb4f51d6309a1af3f4e1953a6627e3d /src/libstd/sys
parent1f732ef53d54ccfc3e7728390ffbcea8a696ecee (diff)
downloadrust-ec7a50d20dff416d9fec837a6492dfe244f5f3ab.tar.gz
rust-ec7a50d20dff416d9fec837a6492dfe244f5f3ab.zip
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
Diffstat (limited to 'src/libstd/sys')
-rw-r--r--src/libstd/sys/common/mod.rs2
-rw-r--r--src/libstd/sys/common/net.rs12
-rw-r--r--src/libstd/sys/unix/backtrace.rs23
-rw-r--r--src/libstd/sys/unix/fs.rs48
-rw-r--r--src/libstd/sys/unix/mod.rs13
-rw-r--r--src/libstd/sys/unix/os.rs31
-rw-r--r--src/libstd/sys/unix/pipe.rs4
-rw-r--r--src/libstd/sys/unix/process.rs6
-rw-r--r--src/libstd/sys/unix/timer.rs2
-rw-r--r--src/libstd/sys/windows/backtrace.rs18
-rw-r--r--src/libstd/sys/windows/c.rs17
-rw-r--r--src/libstd/sys/windows/fs.rs1
-rw-r--r--src/libstd/sys/windows/pipe.rs21
-rw-r--r--src/libstd/sys/windows/process.rs31
14 files changed, 113 insertions, 116 deletions
diff --git a/src/libstd/sys/common/mod.rs b/src/libstd/sys/common/mod.rs
index a441e55a732..a31dcc9884f 100644
--- a/src/libstd/sys/common/mod.rs
+++ b/src/libstd/sys/common/mod.rs
@@ -14,7 +14,7 @@
 use io::{self, IoError, IoResult};
 use prelude::v1::*;
 use sys::{last_error, retry};
-use c_str::CString;
+use ffi::CString;
 use num::Int;
 use path::BytesContainer;
 use collections;
diff --git a/src/libstd/sys/common/net.rs b/src/libstd/sys/common/net.rs
index 3f67b284f68..4cf891ac498 100644
--- a/src/libstd/sys/common/net.rs
+++ b/src/libstd/sys/common/net.rs
@@ -12,15 +12,16 @@ use prelude::v1::*;
 use self::SocketStatus::*;
 use self::InAddr::*;
 
-use c_str::ToCStr;
+use ffi::CString;
+use ffi;
 use io::net::addrinfo;
 use io::net::ip::{SocketAddr, IpAddr, Ipv4Addr, Ipv6Addr};
 use io::{IoResult, IoError};
 use libc::{self, c_char, c_int};
-use c_str::CString;
 use mem;
 use num::Int;
 use ptr::{self, null, null_mut};
+use str;
 use sys::{self, retry, c, sock_t, last_error, last_net_error, last_gai_error, close_sock,
           wrlen, msglen_t, os, wouldblock, set_nonblocking, timer, ms_to_timeval,
           decode_error_detailed};
@@ -234,9 +235,9 @@ pub fn get_host_addresses(host: Option<&str>, servname: Option<&str>,
 
     assert!(host.is_some() || servname.is_some());
 
-    let c_host = host.map(|x| x.to_c_str());
+    let c_host = host.map(|x| CString::from_slice(x.as_bytes()));
     let c_host = c_host.as_ref().map(|x| x.as_ptr()).unwrap_or(null());
-    let c_serv = servname.map(|x| x.to_c_str());
+    let c_serv = servname.map(|x| CString::from_slice(x.as_bytes()));
     let c_serv = c_serv.as_ref().map(|x| x.as_ptr()).unwrap_or(null());
 
     let hint = hint.map(|hint| {
@@ -324,7 +325,8 @@ pub fn get_address_name(addr: IpAddr) -> Result<String, IoError> {
     }
 
     unsafe {
-        Ok(CString::new(hostbuf.as_ptr(), false).as_str().unwrap().to_string())
+        Ok(str::from_utf8(ffi::c_str_to_bytes(&hostbuf.as_ptr()))
+               .unwrap().to_string())
     }
 }
 
diff --git a/src/libstd/sys/unix/backtrace.rs b/src/libstd/sys/unix/backtrace.rs
index 5b261ea6b9e..ca268a8f27f 100644
--- a/src/libstd/sys/unix/backtrace.rs
+++ b/src/libstd/sys/unix/backtrace.rs
@@ -83,12 +83,13 @@
 /// to symbols. This is a bit of a hokey implementation as-is, but it works for
 /// all unix platforms we support right now, so it at least gets the job done.
 
-use c_str::CString;
-use io::{IoResult, Writer};
+use prelude::v1::*;
+
+use ffi;
+use io::IoResult;
 use libc;
 use mem;
-use option::Option::{self, Some, None};
-use result::Result::{Ok, Err};
+use str;
 use sync::{StaticMutex, MUTEX_INIT};
 
 use sys_common::backtrace::*;
@@ -105,9 +106,7 @@ use sys_common::backtrace::*;
 #[cfg(all(target_os = "ios", target_arch = "arm"))]
 #[inline(never)]
 pub fn write(w: &mut Writer) -> IoResult<()> {
-    use iter::{IteratorExt, range};
     use result;
-    use slice::SliceExt;
 
     extern {
         fn backtrace(buf: *mut *mut libc::c_void,
@@ -234,19 +233,15 @@ fn print(w: &mut Writer, idx: int, addr: *mut libc::c_void) -> IoResult<()> {
         output(w, idx,addr, None)
     } else {
         output(w, idx, addr, Some(unsafe {
-            CString::new(info.dli_sname, false)
+            ffi::c_str_to_bytes(&info.dli_sname)
         }))
     }
 }
 
 #[cfg(not(any(target_os = "macos", target_os = "ios")))]
 fn print(w: &mut Writer, idx: int, addr: *mut libc::c_void) -> IoResult<()> {
-    use iter::{Iterator, IteratorExt};
     use os;
-    use path::GenericPath;
-    use ptr::PtrExt;
     use ptr;
-    use slice::SliceExt;
 
     ////////////////////////////////////////////////////////////////////////
     // libbacktrace.h API
@@ -368,15 +363,15 @@ fn print(w: &mut Writer, idx: int, addr: *mut libc::c_void) -> IoResult<()> {
     if ret == 0 || data.is_null() {
         output(w, idx, addr, None)
     } else {
-        output(w, idx, addr, Some(unsafe { CString::new(data, false) }))
+        output(w, idx, addr, Some(unsafe { ffi::c_str_to_bytes(&data) }))
     }
 }
 
 // Finally, after all that work above, we can emit a symbol.
 fn output(w: &mut Writer, idx: int, addr: *mut libc::c_void,
-          s: Option<CString>) -> IoResult<()> {
+          s: Option<&[u8]>) -> IoResult<()> {
     try!(write!(w, "  {:2}: {:2$} - ", idx, addr, HEX_WIDTH));
-    match s.as_ref().and_then(|c| c.as_str()) {
+    match s.and_then(|s| str::from_utf8(s).ok()) {
         Some(string) => try!(demangle(w, string)),
         None => try!(write!(w, "<unknown>")),
     }
diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs
index b49ace8e2f8..1ad775517bb 100644
--- a/src/libstd/sys/unix/fs.rs
+++ b/src/libstd/sys/unix/fs.rs
@@ -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,
diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs
index ea0d230e8b2..6a408aa60f0 100644
--- a/src/libstd/sys/unix/mod.rs
+++ b/src/libstd/sys/unix/mod.rs
@@ -15,12 +15,14 @@
 #![allow(unused_unsafe)]
 #![allow(unused_mut)]
 
-extern crate libc;
-
-use num;
-use num::{Int, SignedInt};
 use prelude::v1::*;
+
+use ffi;
 use io::{self, IoResult, IoError};
+use libc;
+use num::{Int, SignedInt};
+use num;
+use str;
 use sys_common::mkerr_libc;
 
 macro_rules! helper_init { (static $name:ident: Helper<$m:ty>) => (
@@ -78,11 +80,10 @@ extern "system" {
 }
 
 pub fn last_gai_error(s: libc::c_int) -> IoError {
-    use c_str::CString;
 
     let mut err = decode_error(s);
     err.detail = Some(unsafe {
-        CString::new(gai_strerror(s), false).as_str().unwrap().to_string()
+        str::from_utf8(ffi::c_str_to_bytes(&gai_strerror(s))).unwrap().to_string()
     });
     err
 }
diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs
index 181b8fdd0f8..175c4e2e353 100644
--- a/src/libstd/sys/unix/os.rs
+++ b/src/libstd/sys/unix/os.rs
@@ -12,18 +12,18 @@
 
 use prelude::v1::*;
 
-use c_str::ToCStr;
 use error::{FromError, Error};
+use ffi::{self, CString};
 use fmt;
 use io::{IoError, IoResult};
 use libc::{self, c_int, c_char, c_void};
+use os::TMPBUF_SZ;
 use os;
 use path::{BytesContainer};
 use ptr;
+use str;
 use sys::fs::FileDesc;
 
-use os::TMPBUF_SZ;
-
 const BUF_BYTES : uint = 2048u;
 
 /// Returns the platform-specific value of errno
@@ -108,7 +108,8 @@ pub fn error_string(errno: i32) -> String {
             panic!("strerror_r failure");
         }
 
-        String::from_raw_buf(p as *const u8)
+        let p = p as *const _;
+        str::from_utf8(ffi::c_str_to_bytes(&p)).unwrap().to_string()
     }
 }
 
@@ -122,21 +123,17 @@ pub unsafe fn pipe() -> IoResult<(FileDesc, FileDesc)> {
 }
 
 pub fn getcwd() -> IoResult<Path> {
-    use c_str::CString;
-
     let mut buf = [0 as c_char; BUF_BYTES];
     unsafe {
         if libc::getcwd(buf.as_mut_ptr(), buf.len() as libc::size_t).is_null() {
             Err(IoError::last_error())
         } else {
-            Ok(Path::new(CString::new(buf.as_ptr(), false)))
+            Ok(Path::new(ffi::c_str_to_bytes(&buf.as_ptr())))
         }
     }
 }
 
 pub unsafe fn get_env_pairs() -> Vec<Vec<u8>> {
-    use c_str::CString;
-
     extern {
         fn rust_env_pairs() -> *const *const c_char;
     }
@@ -147,8 +144,7 @@ pub unsafe fn get_env_pairs() -> Vec<Vec<u8>> {
     }
     let mut result = Vec::new();
     while *environ != 0 as *const _ {
-        let env_pair =
-            CString::new(*environ, false).as_bytes_no_nul().to_vec();
+        let env_pair = ffi::c_str_to_bytes(&*environ).to_vec();
         result.push(env_pair);
         environ = environ.offset(1);
     }
@@ -234,14 +230,13 @@ pub fn load_self() -> Option<Vec<u8>> {
 }
 
 pub fn chdir(p: &Path) -> IoResult<()> {
-    p.with_c_str(|buf| {
-        unsafe {
-            match libc::chdir(buf) == (0 as c_int) {
-                true => Ok(()),
-                false => Err(IoError::last_error()),
-            }
+    let p = CString::from_slice(p.as_vec());
+    unsafe {
+        match libc::chdir(p.as_ptr()) == (0 as c_int) {
+            true => Ok(()),
+            false => Err(IoError::last_error()),
         }
-    })
+    }
 }
 
 pub fn page_size() -> uint {
diff --git a/src/libstd/sys/unix/pipe.rs b/src/libstd/sys/unix/pipe.rs
index 9063fbc2ba9..158a1ce2204 100644
--- a/src/libstd/sys/unix/pipe.rs
+++ b/src/libstd/sys/unix/pipe.rs
@@ -10,8 +10,8 @@
 
 use prelude::v1::*;
 
+use ffi::CString;
 use libc;
-use c_str::CString;
 use mem;
 use sync::{Arc, Mutex};
 use sync::atomic::{AtomicBool, Ordering};
@@ -48,7 +48,7 @@ fn addr_to_sockaddr_un(addr: &CString,
     }
     s.sun_family = libc::AF_UNIX as libc::sa_family_t;
     for (slot, value) in s.sun_path.iter_mut().zip(addr.iter()) {
-        *slot = value;
+        *slot = *value;
     }
 
     // count the null terminator
diff --git a/src/libstd/sys/unix/process.rs b/src/libstd/sys/unix/process.rs
index b73919fe2a2..5bc6b0c703b 100644
--- a/src/libstd/sys/unix/process.rs
+++ b/src/libstd/sys/unix/process.rs
@@ -11,8 +11,8 @@
 use prelude::v1::*;
 use self::Req::*;
 
-use c_str::{CString, ToCStr};
 use collections;
+use ffi::CString;
 use hash::Hash;
 use io::process::{ProcessExit, ExitStatus, ExitSignal};
 use io::{self, IoResult, IoError, EndOfFile};
@@ -101,7 +101,7 @@ impl Process {
 
                 // We may use this in the child, so perform allocations before the
                 // fork
-                let devnull = "/dev/null".to_c_str();
+                let devnull = b"/dev/null\0";
 
                 set_cloexec(output.fd());
 
@@ -204,7 +204,7 @@ impl Process {
                             } else {
                                 libc::O_RDWR
                             };
-                            libc::open(devnull.as_ptr(), flags, 0)
+                            libc::open(devnull.as_ptr() as *const _, flags, 0)
                         }
                         Some(obj) => {
                             let fd = obj.as_inner().fd();
diff --git a/src/libstd/sys/unix/timer.rs b/src/libstd/sys/unix/timer.rs
index 11f29232a92..62f3242a206 100644
--- a/src/libstd/sys/unix/timer.rs
+++ b/src/libstd/sys/unix/timer.rs
@@ -54,7 +54,7 @@ use libc;
 use mem;
 use os;
 use ptr;
-use sync::atomic::{mod, Ordering};
+use sync::atomic::{self, Ordering};
 use sync::mpsc::{channel, Sender, Receiver, TryRecvError};
 use sys::c;
 use sys::fs::FileDesc;
diff --git a/src/libstd/sys/windows/backtrace.rs b/src/libstd/sys/windows/backtrace.rs
index 319a458087b..4ccecfd1f5f 100644
--- a/src/libstd/sys/windows/backtrace.rs
+++ b/src/libstd/sys/windows/backtrace.rs
@@ -21,7 +21,8 @@
 /// copy of that function in my mingw install (maybe it was broken?). Instead,
 /// this takes the route of using StackWalk64 in order to walk the stack.
 
-use c_str::CString;
+use dynamic_lib::DynamicLibrary;
+use ffi;
 use intrinsics;
 use io::{IoResult, Writer};
 use libc;
@@ -30,10 +31,9 @@ use ops::Drop;
 use option::Option::{Some, None};
 use path::Path;
 use result::Result::{Ok, Err};
-use sync::{StaticMutex, MUTEX_INIT};
 use slice::SliceExt;
-use str::StrExt;
-use dynamic_lib::DynamicLibrary;
+use str::{self, StrExt};
+use sync::{StaticMutex, MUTEX_INIT};
 
 use sys_common::backtrace::*;
 
@@ -357,11 +357,11 @@ pub fn write(w: &mut Writer) -> IoResult<()> {
 
         if ret == libc::TRUE {
             try!(write!(w, " - "));
-            let cstr = unsafe { CString::new(info.Name.as_ptr(), false) };
-            let bytes = cstr.as_bytes();
-            match cstr.as_str() {
-                Some(s) => try!(demangle(w, s)),
-                None => try!(w.write(bytes[..bytes.len()-1])),
+            let ptr = info.Name.as_ptr() as *const libc::c_char;
+            let bytes = unsafe { ffi::c_str_to_bytes(&ptr) };
+            match str::from_utf8(bytes) {
+                Ok(s) => try!(demangle(w, s)),
+                Err(..) => try!(w.write(bytes[..bytes.len()-1])),
             }
         }
         try!(w.write(&['\n' as u8]));
diff --git a/src/libstd/sys/windows/c.rs b/src/libstd/sys/windows/c.rs
index 1ee57434fb9..945c2e8e7d1 100644
--- a/src/libstd/sys/windows/c.rs
+++ b/src/libstd/sys/windows/c.rs
@@ -133,7 +133,7 @@ pub mod compat {
     use intrinsics::{atomic_store_relaxed, transmute};
     use libc::types::os::arch::extra::{LPCWSTR, HMODULE, LPCSTR, LPVOID};
     use prelude::v1::*;
-    use c_str::ToCStr;
+    use ffi::CString;
 
     extern "system" {
         fn GetModuleHandleW(lpModuleName: LPCWSTR) -> HMODULE;
@@ -147,14 +147,13 @@ pub mod compat {
     unsafe fn store_func(ptr: *mut uint, module: &str, symbol: &str, fallback: uint) {
         let mut module: Vec<u16> = module.utf16_units().collect();
         module.push(0);
-        symbol.with_c_str(|symbol| {
-            let handle = GetModuleHandleW(module.as_ptr());
-            let func: uint = transmute(GetProcAddress(handle, symbol));
-            atomic_store_relaxed(ptr, if func == 0 {
-                fallback
-            } else {
-                func
-            })
+        let symbol = CString::from_slice(symbol.as_bytes());
+        let handle = GetModuleHandleW(module.as_ptr());
+        let func: uint = transmute(GetProcAddress(handle, symbol.as_ptr()));
+        atomic_store_relaxed(ptr, if func == 0 {
+            fallback
+        } else {
+            func
         })
     }
 
diff --git a/src/libstd/sys/windows/fs.rs b/src/libstd/sys/windows/fs.rs
index 9a942300656..f8c75335b35 100644
--- a/src/libstd/sys/windows/fs.rs
+++ b/src/libstd/sys/windows/fs.rs
@@ -13,7 +13,6 @@
 use alloc::arc::Arc;
 use libc::{self, c_int};
 
-use c_str::CString;
 use mem;
 use sys::os::fill_utf16_buf_and_decode;
 use path;
diff --git a/src/libstd/sys/windows/pipe.rs b/src/libstd/sys/windows/pipe.rs
index 9057515cad2..9996909f2f5 100644
--- a/src/libstd/sys/windows/pipe.rs
+++ b/src/libstd/sys/windows/pipe.rs
@@ -87,16 +87,21 @@
 use prelude::v1::*;
 
 use libc;
-use c_str::CString;
+use ffi::CString;
+use io::{self, IoError, IoResult};
 use mem;
 use ptr;
-use sync::{Arc, Mutex};
+use str;
 use sync::atomic::{AtomicBool, Ordering};
-use io::{self, IoError, IoResult};
+use sync::{Arc, Mutex};
 
 use sys_common::{self, eof};
 
-use super::{c, os, timer, to_utf16, decode_error_detailed};
+use super::{c, os, timer, decode_error_detailed};
+
+fn to_utf16(c: &CString) -> IoResult<Vec<u16>> {
+    super::to_utf16(str::from_utf8(c.as_bytes()).ok())
+}
 
 struct Event(libc::HANDLE);
 
@@ -270,7 +275,7 @@ impl UnixStream {
     }
 
     pub fn connect(addr: &CString, timeout: Option<u64>) -> IoResult<UnixStream> {
-        let addr = try!(to_utf16(addr.as_str()));
+        let addr = try!(to_utf16(addr));
         let start = timer::now();
         loop {
             match UnixStream::try_connect(addr.as_ptr()) {
@@ -571,7 +576,7 @@ impl UnixListener {
         // Although we technically don't need the pipe until much later, we
         // create the initial handle up front to test the validity of the name
         // and such.
-        let addr_v = try!(to_utf16(addr.as_str()));
+        let addr_v = try!(to_utf16(addr));
         let ret = unsafe { pipe(addr_v.as_ptr(), true) };
         if ret == libc::INVALID_HANDLE_VALUE {
             Err(super::last_error())
@@ -661,7 +666,7 @@ impl UnixAcceptor {
         // proceed in accepting new clients in the future
         if self.inner.closed.load(Ordering::SeqCst) { return Err(eof()) }
 
-        let name = try!(to_utf16(self.listener.name.as_str()));
+        let name = try!(to_utf16(&self.listener.name));
 
         // Once we've got a "server handle", we need to wait for a client to
         // connect. The ConnectNamedPipe function will block this thread until
@@ -753,7 +758,7 @@ impl UnixAcceptor {
 
 impl Clone for UnixAcceptor {
     fn clone(&self) -> UnixAcceptor {
-        let name = to_utf16(self.listener.name.as_str()).ok().unwrap();
+        let name = to_utf16(&self.listener.name).ok().unwrap();
         UnixAcceptor {
             inner: self.inner.clone(),
             event: Event::new(true, false).ok().unwrap(),
diff --git a/src/libstd/sys/windows/process.rs b/src/libstd/sys/windows/process.rs
index 81e8f974a12..9b3f2ca0373 100644
--- a/src/libstd/sys/windows/process.rs
+++ b/src/libstd/sys/windows/process.rs
@@ -10,27 +10,26 @@
 
 use prelude::v1::*;
 
+use collections;
+use ffi::CString;
+use hash::Hash;
+use io::fs::PathExtensions;
+use io::process::{ProcessExit, ExitStatus, ExitSignal};
+use io::{IoResult, IoError};
+use io;
 use libc::{pid_t, c_void, c_int};
 use libc;
-use c_str::{CString, ToCStr};
-use io;
 use mem;
 use os;
-use ptr;
-use io::process::{ProcessExit, ExitStatus, ExitSignal};
-use collections;
 use path::BytesContainer;
-use hash::Hash;
-use io::{IoResult, IoError};
-
+use ptr;
+use str;
+use sys::fs::FileDesc;
 use sys::fs;
 use sys::{self, retry, c, wouldblock, set_nonblocking, ms_to_timeval, timer};
-use sys::fs::FileDesc;
 use sys_common::helper_thread::Helper;
 use sys_common::{AsInner, mkerr_libc, timeout};
 
-use io::fs::PathExtensions;
-
 pub use sys_common::ProcessConfig;
 
 /// A value representing a child process.
@@ -142,10 +141,10 @@ impl Process {
                 // Split the value and test each path to see if the
                 // program exists.
                 for path in os::split_paths(v.container_as_bytes()).into_iter() {
-                    let path = path.join(cfg.program().as_bytes_no_nul())
+                    let path = path.join(cfg.program().as_bytes())
                                    .with_extension(os::consts::EXE_EXTENSION);
                     if path.exists() {
-                        return Some(path.to_c_str())
+                        return Some(CString::from_slice(path.as_vec()))
                     }
                 }
                 break
@@ -363,11 +362,11 @@ fn zeroed_process_information() -> libc::types::os::arch::extra::PROCESS_INFORMA
 
 fn make_command_line(prog: &CString, args: &[CString]) -> String {
     let mut cmd = String::new();
-    append_arg(&mut cmd, prog.as_str()
+    append_arg(&mut cmd, str::from_utf8(prog.as_bytes()).ok()
                              .expect("expected program name to be utf-8 encoded"));
     for arg in args.iter() {
         cmd.push(' ');
-        append_arg(&mut cmd, arg.as_str()
+        append_arg(&mut cmd, str::from_utf8(arg.as_bytes()).ok()
                                 .expect("expected argument to be utf-8 encoded"));
     }
     return cmd;
@@ -449,7 +448,7 @@ fn with_dirp<T, F>(d: Option<&CString>, cb: F) -> T where
 {
     match d {
       Some(dir) => {
-          let dir_str = dir.as_str()
+          let dir_str = str::from_utf8(dir.as_bytes()).ok()
                            .expect("expected workingdirectory to be utf-8 encoded");
           let mut dir_str: Vec<u16> = dir_str.utf16_units().collect();
           dir_str.push(0);