diff options
author | Carl Lerche <me@carllerche.com> | 2015-05-21 16:38:54 -0700 |
---|---|---|
committer | Carl Lerche <me@carllerche.com> | 2015-05-21 16:38:54 -0700 |
commit | 21fb1394a111d19079da90a4d31171b0d6adc27c (patch) | |
tree | e2c9f436216cb238b6bfe8c27b3a3ce34668aca1 /src/lib.rs | |
parent | 3fc83b942a57fd76372e83e987fc191f6bdf6a5c (diff) | |
download | nix-21fb1394a111d19079da90a4d31171b0d6adc27c.zip |
Fix NixPath yield with CStr instead of OsStr
As described in #117, the `AsExtStr` trait is defined to return a raw `*const
libc::c_char`. Its impl for `OsStr` simply borrowed the byte slice from its
`OsStr` argument and cast it to a `*const libc::c_char`, which does not
construct a proper null-terminated C string.
Given this, the `AsExtStr` is not necessary and is removed. `NixPath` is
updated to yield `CStr`.
Fixes #117, #120
Thanks to @dead10ck
Diffstat (limited to 'src/lib.rs')
-rw-r--r-- | src/lib.rs | 53 |
1 files changed, 24 insertions, 29 deletions
@@ -48,8 +48,11 @@ pub mod unistd; * */ +use libc::c_char; use std::{ptr, result}; +use std::ffi::CStr; use std::path::{Path, PathBuf}; +use std::os::unix::ffi::OsStrExt; pub type Result<T> = result::Result<T, Error>; @@ -81,13 +84,19 @@ impl Error { } pub trait NixPath { + fn len(&self) -> usize; + fn with_nix_path<T, F>(&self, f: F) -> Result<T> - where F: FnOnce(&OsStr) -> T; + where F: FnOnce(&CStr) -> T; } impl NixPath for [u8] { + fn len(&self) -> usize { + self.len() + } + fn with_nix_path<T, F>(&self, f: F) -> Result<T> - where F: FnOnce(&OsStr) -> T { + where F: FnOnce(&CStr) -> T { // TODO: Extract this size as a const let mut buf = [0u8; 4096]; @@ -101,25 +110,31 @@ impl NixPath for [u8] { unsafe { // TODO: Replace with bytes::copy_memory. rust-lang/rust#24028 ptr::copy_nonoverlapping(self.as_ptr(), buf.as_mut_ptr(), self.len()); + Ok(f(CStr::from_ptr(buf.as_ptr() as *const c_char))) } - Ok(f(<OsStr as OsStrExt>::from_bytes(&buf[..self.len()]))) } } } } impl NixPath for Path { - fn with_nix_path<T, F>(&self, f: F) -> Result<T> - where F: FnOnce(&OsStr) -> T { - Ok(f(self.as_os_str())) + fn len(&self) -> usize { + self.as_os_str().as_bytes().len() + } + + fn with_nix_path<T, F>(&self, f: F) -> Result<T> where F: FnOnce(&CStr) -> T { + self.as_os_str().as_bytes().with_nix_path(f) } } impl NixPath for PathBuf { - fn with_nix_path<T, F>(&self, f: F) -> Result<T> - where F: FnOnce(&OsStr) -> T { - Ok(f(self.as_os_str())) + fn len(&self) -> usize { + self.as_os_str().as_bytes().len() + } + + fn with_nix_path<T, F>(&self, f: F) -> Result<T> where F: FnOnce(&CStr) -> T { + self.as_os_str().as_bytes().with_nix_path(f) } } @@ -131,23 +146,3 @@ pub fn from_ffi(res: libc::c_int) -> Result<()> { Ok(()) } - -/* - * - * ===== Impl utilities ===== - * - */ - -use std::ffi::OsStr; -use std::os::unix::ffi::OsStrExt; - -/// Converts a value to an external (FFI) string representation -trait AsExtStr { - fn as_ext_str(&self) -> *const libc::c_char; -} - -impl AsExtStr for OsStr { - fn as_ext_str(&self) -> *const libc::c_char { - self.as_bytes().as_ptr() as *const libc::c_char - } -} |