about summary refs log tree commit diff
path: root/src/libstd/sys/windows
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/windows
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/windows')
-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
5 files changed, 45 insertions, 43 deletions
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);