std: Implement CString-related RFCs

This commit is an implementation of [RFC 592][r592] and [RFC 840][r840]. These
two RFCs tweak the behavior of `CString` and add a new `CStr` unsized slice type
to the module.

[r592]: https://github.com/rust-lang/rfcs/blob/master/text/0592-c-str-deref.md
[r840]: https://github.com/rust-lang/rfcs/blob/master/text/0840-no-panic-in-c-string.md

The new `CStr` type is only constructable via two methods:

1. By `deref`'ing from a `CString`
2. Unsafely via `CStr::from_ptr`

The purpose of `CStr` is to be an unsized type which is a thin pointer to a
`libc::c_char` (currently it is a fat pointer slice due to implementation
limitations). Strings from C can be safely represented with a `CStr` and an
appropriate lifetime as well. Consumers of `&CString` should now consume `&CStr`
instead to allow producers to pass in C-originating strings instead of just
Rust-allocated strings.

A new constructor was added to `CString`, `new`, which takes `T: IntoBytes`
instead of separate `from_slice` and `from_vec` methods (both have been
deprecated in favor of `new`). The `new` method returns a `Result` instead of
panicking.  The error variant contains the relevant information about where the
error happened and bytes (if present). Conversions are provided to the
`io::Error` and `old_io::IoError` types via the `FromError` trait which
translate to `InvalidInput`.

This is a breaking change due to the modification of existing `#[unstable]` APIs
and new deprecation, and more detailed information can be found in the two RFCs.
Notable breakage includes:

* All construction of `CString` now needs to use `new` and handle the outgoing
  `Result`.
* Usage of `CString` as a byte slice now explicitly needs a `.as_bytes()` call.
* The `as_slice*` methods have been removed in favor of just having the
  `as_bytes*` methods.

Closes #22469
Closes #22470
[breaking-change]
This commit is contained in:
Alex Crichton 2015-02-17 22:47:40 -08:00
parent dfc5c0f1e8
commit 1860ee521a
40 changed files with 555 additions and 290 deletions

View File

@ -435,8 +435,8 @@ extern {
}
fn main() {
let prompt = CString::from_slice(b"[my-awesome-shell] $");
unsafe {
let prompt = CString::new("[my-awesome-shell] $").unwrap();
unsafe {
rl_prompt = prompt.as_ptr();
println!("{:?}", rl_prompt);

View File

@ -744,7 +744,7 @@ fn get_metadata_section_imp(is_osx: bool, filename: &Path) -> Result<MetadataBlo
}
}
unsafe {
let buf = CString::from_slice(filename.as_vec());
let buf = CString::new(filename.as_vec()).unwrap();
let mb = llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf.as_ptr());
if mb as int == 0 {
return Err(format!("error reading library: '{}'",

View File

@ -30,7 +30,7 @@ impl ArchiveRO {
/// raised.
pub fn open(dst: &Path) -> Option<ArchiveRO> {
unsafe {
let s = CString::from_slice(dst.as_vec());
let s = CString::new(dst.as_vec()).unwrap();
let ar = ::LLVMRustOpenArchive(s.as_ptr());
if ar.is_null() {
None
@ -44,7 +44,7 @@ pub fn open(dst: &Path) -> Option<ArchiveRO> {
pub fn read<'a>(&'a self, file: &str) -> Option<&'a [u8]> {
unsafe {
let mut size = 0 as libc::size_t;
let file = CString::from_slice(file.as_bytes());
let file = CString::new(file).unwrap();
let ptr = ::LLVMRustArchiveReadSection(self.ptr, file.as_ptr(),
&mut size);
if ptr.is_null() {

View File

@ -2149,7 +2149,7 @@ fn drop(&mut self) {
}
pub fn mk_target_data(string_rep: &str) -> TargetData {
let string_rep = CString::from_slice(string_rep.as_bytes());
let string_rep = CString::new(string_rep).unwrap();
TargetData {
lltd: unsafe { LLVMCreateTargetData(string_rep.as_ptr()) }
}

View File

@ -140,7 +140,7 @@ pub fn run(sess: &session::Session, llmod: ModuleRef,
// Internalize everything but the reachable symbols of the current module
let cstrs: Vec<CString> = reachable.iter().map(|s| {
CString::from_slice(s.as_bytes())
CString::new(s.clone()).unwrap()
}).collect();
let arr: Vec<*const libc::c_char> = cstrs.iter().map(|c| c.as_ptr()).collect();
let ptr = arr.as_ptr();

View File

@ -22,7 +22,7 @@
use syntax::diagnostic;
use syntax::diagnostic::{Emitter, Handler, Level, mk_handler};
use std::ffi::{self, CString};
use std::ffi::{CStr, CString};
use std::old_io::Command;
use std::old_io::fs;
use std::iter::Unfold;
@ -49,7 +49,7 @@ pub fn llvm_err(handler: &diagnostic::Handler, msg: String) -> ! {
if cstr == ptr::null() {
handler.fatal(&msg[]);
} else {
let err = ffi::c_str_to_bytes(&cstr);
let err = CStr::from_ptr(cstr).to_bytes();
let err = String::from_utf8_lossy(err).to_string();
libc::free(cstr as *mut _);
handler.fatal(&format!("{}: {}",
@ -67,7 +67,7 @@ pub fn write_output_file(
output: &Path,
file_type: llvm::FileType) {
unsafe {
let output_c = CString::from_slice(output.as_vec());
let output_c = CString::new(output.as_vec()).unwrap();
let result = llvm::LLVMRustWriteOutputFile(
target, pm, m, output_c.as_ptr(), file_type);
if !result {
@ -221,13 +221,13 @@ fn create_target_machine(sess: &Session) -> TargetMachineRef {
let triple = &sess.target.target.llvm_target[];
let tm = unsafe {
let triple = CString::from_slice(triple.as_bytes());
let triple = CString::new(triple.as_bytes()).unwrap();
let cpu = match sess.opts.cg.target_cpu {
Some(ref s) => &**s,
None => &*sess.target.target.options.cpu
};
let cpu = CString::from_slice(cpu.as_bytes());
let features = CString::from_slice(target_feature(sess).as_bytes());
let cpu = CString::new(cpu.as_bytes()).unwrap();
let features = CString::new(target_feature(sess).as_bytes()).unwrap();
llvm::LLVMRustCreateTargetMachine(
triple.as_ptr(), cpu.as_ptr(), features.as_ptr(),
code_model,
@ -380,7 +380,7 @@ struct HandlerFreeVars<'a> {
}
llvm::diagnostic::Optimization(opt) => {
let pass_name = str::from_utf8(ffi::c_str_to_bytes(&opt.pass_name))
let pass_name = str::from_utf8(CStr::from_ptr(opt.pass_name).to_bytes())
.ok()
.expect("got a non-UTF8 pass name from LLVM");
let enabled = match cgcx.remark {
@ -424,7 +424,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
if config.emit_no_opt_bc {
let ext = format!("{}.no-opt.bc", name_extra);
let out = output_names.with_extension(&ext);
let out = CString::from_slice(out.as_vec());
let out = CString::new(out.as_vec()).unwrap();
llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr());
}
@ -440,7 +440,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
// If we're verifying or linting, add them to the function pass
// manager.
let addpass = |pass: &str| {
let pass = CString::from_slice(pass.as_bytes());
let pass = CString::new(pass).unwrap();
llvm::LLVMRustAddPass(fpm, pass.as_ptr())
};
if !config.no_verify { assert!(addpass("verify")); }
@ -453,7 +453,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
}
for pass in &config.passes {
let pass = CString::from_slice(pass.as_bytes());
let pass = CString::new(pass.clone()).unwrap();
if !llvm::LLVMRustAddPass(mpm, pass.as_ptr()) {
cgcx.handler.warn(&format!("unknown pass {:?}, ignoring", pass));
}
@ -477,7 +477,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
if config.emit_lto_bc {
let name = format!("{}.lto.bc", name_extra);
let out = output_names.with_extension(&name);
let out = CString::from_slice(out.as_vec());
let out = CString::new(out.as_vec()).unwrap();
llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr());
}
},
@ -511,7 +511,7 @@ unsafe fn with_codegen<F>(tm: TargetMachineRef,
if config.emit_bc {
let ext = format!("{}.bc", name_extra);
let out = output_names.with_extension(&ext);
let out = CString::from_slice(out.as_vec());
let out = CString::new(out.as_vec()).unwrap();
llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr());
}
@ -519,7 +519,7 @@ unsafe fn with_codegen<F>(tm: TargetMachineRef,
if config.emit_ir {
let ext = format!("{}.ll", name_extra);
let out = output_names.with_extension(&ext);
let out = CString::from_slice(out.as_vec());
let out = CString::new(out.as_vec()).unwrap();
with_codegen(tm, llmod, config.no_builtins, |cpm| {
llvm::LLVMRustPrintModule(cpm, llmod, out.as_ptr());
})
@ -1004,7 +1004,7 @@ unsafe fn configure_llvm(sess: &Session) {
let mut llvm_args = Vec::new();
{
let mut add = |arg: &str| {
let s = CString::from_slice(arg.as_bytes());
let s = CString::new(arg).unwrap();
llvm_args.push(s.as_ptr());
llvm_c_strs.push(s);
};

View File

@ -120,8 +120,8 @@ pub fn trans_inline_asm<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ia: &ast::InlineAsm)
ast::AsmIntel => llvm::AD_Intel
};
let asm = CString::from_slice(ia.asm.as_bytes());
let constraints = CString::from_slice(constraints.as_bytes());
let asm = CString::new(ia.asm.as_bytes()).unwrap();
let constraints = CString::new(constraints).unwrap();
let r = InlineAsmCall(bcx,
asm.as_ptr(),
constraints.as_ptr(),

View File

@ -86,7 +86,7 @@
use arena::TypedArena;
use libc::{c_uint, uint64_t};
use std::ffi::{self, CString};
use std::ffi::{CStr, CString};
use std::cell::{Cell, RefCell};
use std::collections::HashSet;
use std::mem;
@ -186,7 +186,7 @@ fn drop(&mut self) {
pub fn decl_fn(ccx: &CrateContext, name: &str, cc: llvm::CallConv,
ty: Type, output: ty::FnOutput) -> ValueRef {
let buf = CString::from_slice(name.as_bytes());
let buf = CString::new(name).unwrap();
let llfn: ValueRef = unsafe {
llvm::LLVMGetOrInsertFunction(ccx.llmod(), buf.as_ptr(), ty.to_ref())
};
@ -340,7 +340,7 @@ pub fn get_extern_const<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, did: ast::DefId,
None => ()
}
unsafe {
let buf = CString::from_slice(name.as_bytes());
let buf = CString::new(name.clone()).unwrap();
let c = llvm::LLVMAddGlobal(ccx.llmod(), ty.to_ref(), buf.as_ptr());
// Thread-local statics in some other crate need to *always* be linked
// against in a thread-local fashion, so we need to be sure to apply the
@ -2788,7 +2788,7 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
&format!("Illegal null byte in export_name \
value: `{}`", sym)[]);
}
let buf = CString::from_slice(sym.as_bytes());
let buf = CString::new(sym.clone()).unwrap();
let g = llvm::LLVMAddGlobal(ccx.llmod(), llty,
buf.as_ptr());
@ -2826,7 +2826,7 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
&sect)[]);
}
unsafe {
let buf = CString::from_slice(sect.as_bytes());
let buf = CString::new(sect.as_bytes()).unwrap();
llvm::LLVMSetSection(v, buf.as_ptr());
}
},
@ -2993,7 +2993,7 @@ pub fn write_metadata(cx: &SharedCrateContext, krate: &ast::Crate) -> Vec<u8> {
let name = format!("rust_metadata_{}_{}",
cx.link_meta().crate_name,
cx.link_meta().crate_hash);
let buf = CString::from_vec(name.into_bytes());
let buf = CString::new(name).unwrap();
let llglobal = unsafe {
llvm::LLVMAddGlobal(cx.metadata_llmod(), val_ty(llconst).to_ref(),
buf.as_ptr())
@ -3001,7 +3001,7 @@ pub fn write_metadata(cx: &SharedCrateContext, krate: &ast::Crate) -> Vec<u8> {
unsafe {
llvm::LLVMSetInitializer(llglobal, llconst);
let name = loader::meta_section_name(cx.sess().target.target.options.is_like_osx);
let name = CString::from_slice(name.as_bytes());
let name = CString::new(name).unwrap();
llvm::LLVMSetSection(llglobal, name.as_ptr())
}
return metadata;
@ -3039,8 +3039,8 @@ fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet<String>) {
continue
}
let name = ffi::c_str_to_bytes(&llvm::LLVMGetValueName(val))
.to_vec();
let name = CStr::from_ptr(llvm::LLVMGetValueName(val))
.to_bytes().to_vec();
declared.insert(name);
}
}
@ -3056,8 +3056,8 @@ fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet<String>) {
continue
}
let name = ffi::c_str_to_bytes(&llvm::LLVMGetValueName(val))
.to_vec();
let name = CStr::from_ptr(llvm::LLVMGetValueName(val))
.to_bytes().to_vec();
if !declared.contains(&name) &&
!reachable.contains(str::from_utf8(&name).unwrap()) {
llvm::SetLinkage(val, llvm::InternalLinkage);

View File

@ -431,7 +431,7 @@ pub fn alloca(&self, ty: Type, name: &str) -> ValueRef {
if name.is_empty() {
llvm::LLVMBuildAlloca(self.llbuilder, ty.to_ref(), noname())
} else {
let name = CString::from_slice(name.as_bytes());
let name = CString::new(name).unwrap();
llvm::LLVMBuildAlloca(self.llbuilder, ty.to_ref(),
name.as_ptr())
}
@ -786,7 +786,7 @@ pub fn add_comment(&self, text: &str) {
let comment_text = format!("{} {}", "#",
sanitized.replace("\n", "\n\t# "));
self.count_insn("inlineasm");
let comment_text = CString::from_vec(comment_text.into_bytes());
let comment_text = CString::new(comment_text).unwrap();
let asm = unsafe {
llvm::LLVMConstInlineAsm(Type::func(&[], &Type::void(self.ccx)).to_ref(),
comment_text.as_ptr(), noname(), False,

View File

@ -488,7 +488,7 @@ pub fn new_block(&'a self,
opt_node_id: Option<ast::NodeId>)
-> Block<'a, 'tcx> {
unsafe {
let name = CString::from_slice(name.as_bytes());
let name = CString::new(name).unwrap();
let llbb = llvm::LLVMAppendBasicBlockInContext(self.ccx.llcx(),
self.llfn,
name.as_ptr());
@ -761,7 +761,7 @@ pub fn C_integral(t: Type, u: u64, sign_extend: bool) -> ValueRef {
pub fn C_floating(s: &str, t: Type) -> ValueRef {
unsafe {
let s = CString::from_slice(s.as_bytes());
let s = CString::new(s).unwrap();
llvm::LLVMConstRealOfString(t.to_ref(), s.as_ptr())
}
}
@ -839,7 +839,8 @@ pub fn C_cstr(cx: &CrateContext, s: InternedString, null_terminated: bool) -> Va
!null_terminated as Bool);
let gsym = token::gensym("str");
let buf = CString::from_vec(format!("str{}", gsym.usize()).into_bytes());
let buf = CString::new(format!("str{}", gsym.usize()));
let buf = buf.unwrap();
let g = llvm::LLVMAddGlobal(cx.llmod(), val_ty(sc).to_ref(), buf.as_ptr());
llvm::LLVMSetInitializer(g, sc);
llvm::LLVMSetGlobalConstant(g, True);

View File

@ -225,15 +225,15 @@ fn next(&mut self) -> Option<(CrateContext<'a, 'tcx>, bool)> {
unsafe fn create_context_and_module(sess: &Session, mod_name: &str) -> (ContextRef, ModuleRef) {
let llcx = llvm::LLVMContextCreate();
let mod_name = CString::from_slice(mod_name.as_bytes());
let mod_name = CString::new(mod_name).unwrap();
let llmod = llvm::LLVMModuleCreateWithNameInContext(mod_name.as_ptr(), llcx);
let data_layout = &*sess.target.target.data_layout;
let data_layout = CString::from_slice(data_layout.as_bytes());
let data_layout = sess.target.target.data_layout.as_bytes();
let data_layout = CString::new(data_layout).unwrap();
llvm::LLVMSetDataLayout(llmod, data_layout.as_ptr());
let llvm_target = &*sess.target.target.llvm_target;
let llvm_target = CString::from_slice(llvm_target.as_bytes());
let llvm_target = sess.target.target.llvm_target.as_bytes();
let llvm_target = CString::new(llvm_target).unwrap();
llvm::LLVMRustSetNormalizedTarget(llmod, llvm_target.as_ptr());
(llcx, llmod)
}

View File

@ -809,8 +809,8 @@ pub fn create_global_var_metadata(cx: &CrateContext,
namespace_node.mangled_name_of_contained_item(&var_name[]);
let var_scope = namespace_node.scope;
let var_name = CString::from_slice(var_name.as_bytes());
let linkage_name = CString::from_slice(linkage_name.as_bytes());
let var_name = CString::new(var_name).unwrap();
let linkage_name = CString::new(linkage_name).unwrap();
unsafe {
llvm::LLVMDIBuilderCreateStaticVariable(DIB(cx),
var_scope,
@ -1379,8 +1379,8 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
let is_local_to_unit = is_node_local_to_unit(cx, fn_ast_id);
let function_name = CString::from_slice(function_name.as_bytes());
let linkage_name = CString::from_slice(linkage_name.as_bytes());
let function_name = CString::new(function_name).unwrap();
let linkage_name = CString::new(linkage_name).unwrap();
let fn_metadata = unsafe {
llvm::LLVMDIBuilderCreateFunction(
DIB(cx),
@ -1501,7 +1501,7 @@ fn get_template_parameters<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
let ident = special_idents::type_self;
let ident = token::get_ident(ident);
let name = CString::from_slice(ident.as_bytes());
let name = CString::new(ident.as_bytes()).unwrap();
let param_metadata = unsafe {
llvm::LLVMDIBuilderCreateTemplateTypeParameter(
DIB(cx),
@ -1535,7 +1535,7 @@ fn get_template_parameters<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
if cx.sess().opts.debuginfo == FullDebugInfo {
let actual_type_metadata = type_metadata(cx, actual_type, codemap::DUMMY_SP);
let ident = token::get_ident(ident);
let name = CString::from_slice(ident.as_bytes());
let name = CString::new(ident.as_bytes()).unwrap();
let param_metadata = unsafe {
llvm::LLVMDIBuilderCreateTemplateTypeParameter(
DIB(cx),
@ -1601,7 +1601,7 @@ fn compile_unit_metadata(cx: &CrateContext) -> DIDescriptor {
path_bytes.insert(1, prefix[1]);
}
CString::from_vec(path_bytes)
CString::new(path_bytes).unwrap()
}
_ => fallback_path(cx)
}
@ -1614,8 +1614,8 @@ fn compile_unit_metadata(cx: &CrateContext) -> DIDescriptor {
(option_env!("CFG_VERSION")).expect("CFG_VERSION"));
let compile_unit_name = compile_unit_name.as_ptr();
let work_dir = CString::from_slice(work_dir.as_vec());
let producer = CString::from_slice(producer.as_bytes());
let work_dir = CString::new(work_dir.as_vec()).unwrap();
let producer = CString::new(producer).unwrap();
let flags = "\0";
let split_name = "\0";
return unsafe {
@ -1632,7 +1632,7 @@ fn compile_unit_metadata(cx: &CrateContext) -> DIDescriptor {
};
fn fallback_path(cx: &CrateContext) -> CString {
CString::from_slice(cx.link_meta().crate_name.as_bytes())
CString::new(cx.link_meta().crate_name.clone()).unwrap()
}
}
@ -1658,7 +1658,7 @@ fn declare_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
CapturedVariable => (0, DW_TAG_auto_variable)
};
let name = CString::from_slice(name.as_bytes());
let name = CString::new(name.as_bytes()).unwrap();
match (variable_access, [].as_slice()) {
(DirectVariable { alloca }, address_operations) |
(IndirectVariable {alloca, address_operations}, _) => {
@ -1724,8 +1724,8 @@ fn file_metadata(cx: &CrateContext, full_path: &str) -> DIFile {
full_path
};
let file_name = CString::from_slice(file_name.as_bytes());
let work_dir = CString::from_slice(work_dir.as_bytes());
let file_name = CString::new(file_name).unwrap();
let work_dir = CString::new(work_dir).unwrap();
let file_metadata = unsafe {
llvm::LLVMDIBuilderCreateFile(DIB(cx), file_name.as_ptr(),
work_dir.as_ptr())
@ -1800,7 +1800,7 @@ fn basic_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
let llvm_type = type_of::type_of(cx, t);
let (size, align) = size_and_align_of(cx, llvm_type);
let name = CString::from_slice(name.as_bytes());
let name = CString::new(name).unwrap();
let ty_metadata = unsafe {
llvm::LLVMDIBuilderCreateBasicType(
DIB(cx),
@ -1820,7 +1820,7 @@ fn pointer_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
let pointer_llvm_type = type_of::type_of(cx, pointer_type);
let (pointer_size, pointer_align) = size_and_align_of(cx, pointer_llvm_type);
let name = compute_debuginfo_type_name(cx, pointer_type, false);
let name = CString::from_slice(name.as_bytes());
let name = CString::new(name).unwrap();
let ptr_metadata = unsafe {
llvm::LLVMDIBuilderCreatePointerType(
DIB(cx),
@ -2445,7 +2445,7 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
.iter()
.map(|v| {
let token = token::get_name(v.name);
let name = CString::from_slice(token.as_bytes());
let name = CString::new(token.as_bytes()).unwrap();
unsafe {
llvm::LLVMDIBuilderCreateEnumerator(
DIB(cx),
@ -2475,7 +2475,7 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
codemap::DUMMY_SP);
let discriminant_name = get_enum_discriminant_name(cx, enum_def_id);
let name = CString::from_slice(discriminant_name.as_bytes());
let name = CString::new(discriminant_name.as_bytes()).unwrap();
let discriminant_type_metadata = unsafe {
llvm::LLVMDIBuilderCreateEnumerationType(
DIB(cx),
@ -2518,8 +2518,8 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
.borrow()
.get_unique_type_id_as_string(unique_type_id);
let enum_name = CString::from_slice(enum_name.as_bytes());
let unique_type_id_str = CString::from_slice(unique_type_id_str.as_bytes());
let enum_name = CString::new(enum_name).unwrap();
let unique_type_id_str = CString::new(unique_type_id_str.as_bytes()).unwrap();
let enum_metadata = unsafe {
llvm::LLVMDIBuilderCreateUnionType(
DIB(cx),
@ -2644,7 +2644,8 @@ fn set_members_of_composite_type(cx: &CrateContext,
ComputedMemberOffset => machine::llelement_offset(cx, composite_llvm_type, i)
};
let member_name = CString::from_slice(member_description.name.as_bytes());
let member_name = member_description.name.as_bytes();
let member_name = CString::new(member_name).unwrap();
unsafe {
llvm::LLVMDIBuilderCreateMemberType(
DIB(cx),
@ -2681,8 +2682,8 @@ fn create_struct_stub(cx: &CrateContext,
let unique_type_id_str = debug_context(cx).type_map
.borrow()
.get_unique_type_id_as_string(unique_type_id);
let name = CString::from_slice(struct_type_name.as_bytes());
let unique_type_id = CString::from_slice(unique_type_id_str.as_bytes());
let name = CString::new(struct_type_name).unwrap();
let unique_type_id = CString::new(unique_type_id_str.as_bytes()).unwrap();
let metadata_stub = unsafe {
// LLVMDIBuilderCreateStructType() wants an empty array. A null
// pointer will lead to hard to trace and debug LLVM assertions
@ -3971,8 +3972,7 @@ fn namespace_for_item(cx: &CrateContext, def_id: ast::DefId) -> Rc<NamespaceTree
None => ptr::null_mut()
};
let namespace_name = token::get_name(name);
let namespace_name = CString::from_slice(namespace_name
.as_bytes());
let namespace_name = CString::new(namespace_name.as_bytes()).unwrap();
let scope = unsafe {
llvm::LLVMDIBuilderCreateNameSpace(
DIB(cx),
@ -4020,7 +4020,7 @@ fn namespace_for_item(cx: &CrateContext, def_id: ast::DefId) -> Rc<NamespaceTree
/// .debug_gdb_scripts global is referenced, so it isn't removed by the linker.
pub fn insert_reference_to_gdb_debug_scripts_section_global(ccx: &CrateContext) {
if needs_gdb_debug_scripts_section(ccx) {
let empty = CString::from_slice(b"");
let empty = CString::new(b"").unwrap();
let gdb_debug_scripts_section_global =
get_or_insert_gdb_debug_scripts_section_global(ccx);
unsafe {

View File

@ -135,7 +135,7 @@ pub fn register_static(ccx: &CrateContext,
};
unsafe {
// Declare a symbol `foo` with the desired linkage.
let buf = CString::from_slice(ident.as_bytes());
let buf = CString::new(ident.as_bytes()).unwrap();
let g1 = llvm::LLVMAddGlobal(ccx.llmod(), llty2.to_ref(),
buf.as_ptr());
llvm::SetLinkage(g1, linkage);
@ -148,7 +148,7 @@ pub fn register_static(ccx: &CrateContext,
// zero.
let mut real_name = "_rust_extern_with_linkage_".to_string();
real_name.push_str(&ident);
let real_name = CString::from_vec(real_name.into_bytes());
let real_name = CString::new(real_name).unwrap();
let g2 = llvm::LLVMAddGlobal(ccx.llmod(), llty.to_ref(),
real_name.as_ptr());
llvm::SetLinkage(g2, llvm::InternalLinkage);
@ -158,7 +158,7 @@ pub fn register_static(ccx: &CrateContext,
}
None => unsafe {
// Generate an external declaration.
let buf = CString::from_slice(ident.as_bytes());
let buf = CString::new(ident.as_bytes()).unwrap();
llvm::LLVMAddGlobal(ccx.llmod(), llty.to_ref(), buf.as_ptr())
}
}

View File

@ -513,7 +513,7 @@ pub fn declare_tydesc<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>)
let llalign = llalign_of(ccx, llty);
let name = mangle_internal_name_by_type_and_seq(ccx, t, "tydesc");
debug!("+++ declare_tydesc {} {}", ppaux::ty_to_string(ccx.tcx(), t), name);
let buf = CString::from_slice(name.as_bytes());
let buf = CString::new(name.clone()).unwrap();
let gvar = unsafe {
llvm::LLVMAddGlobal(ccx.llmod(), ccx.tydesc_type().to_ref(),
buf.as_ptr())

View File

@ -163,7 +163,7 @@ pub fn struct_(ccx: &CrateContext, els: &[Type], packed: bool) -> Type {
}
pub fn named_struct(ccx: &CrateContext, name: &str) -> Type {
let name = CString::from_slice(name.as_bytes());
let name = CString::new(name).unwrap();
ty!(llvm::LLVMStructCreateNamed(ccx.llcx(), name.as_ptr()))
}

View File

@ -112,7 +112,7 @@ pub struct Lock {
impl Lock {
pub fn new(p: &Path) -> Lock {
let buf = CString::from_slice(p.as_vec());
let buf = CString::from_slice(p.as_vec()).unwrap();
let fd = unsafe {
libc::open(buf.as_ptr(), libc::O_RDWR | libc::O_CREAT,
libc::S_IRWXU)

View File

@ -236,7 +236,7 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result {
s.push_str(&highlight::highlight(&text,
None,
Some("rust-example-rendered")));
let output = CString::from_vec(s.into_bytes());
let output = CString::from_vec(s.into_bytes()).unwrap();
hoedown_buffer_puts(ob, output.as_ptr());
})
}
@ -293,7 +293,7 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result {
format!("{} ", sec)
});
let text = CString::from_vec(text.into_bytes());
let text = CString::from_vec(text.into_bytes()).unwrap();
unsafe { hoedown_buffer_puts(ob, text.as_ptr()) }
}

View File

@ -112,7 +112,7 @@ pub unsafe fn symbol<T>(&self, symbol: &str) -> Result<*mut T, String> {
// This function should have a lifetime constraint of 'a on
// T but that feature is still unimplemented
let raw_string = CString::from_slice(symbol.as_bytes());
let raw_string = CString::new(symbol).unwrap();
let maybe_symbol_value = dl::check_for_errors_in(|| {
dl::symbol(self.handle, raw_string.as_ptr())
});
@ -187,7 +187,7 @@ fn test_errors_do_not_crash() {
mod dl {
use prelude::v1::*;
use ffi::{self, CString};
use ffi::{CString, CStr};
use str;
use libc;
use ptr;
@ -206,7 +206,7 @@ pub fn open(filename: Option<&[u8]>) -> Result<*mut u8, String> {
const LAZY: libc::c_int = 1;
unsafe fn open_external(filename: &[u8]) -> *mut u8 {
let s = CString::from_slice(filename);
let s = CString::new(filename).unwrap();
dlopen(s.as_ptr(), LAZY) as *mut u8
}
@ -231,7 +231,7 @@ pub fn check_for_errors_in<T, F>(f: F) -> Result<T, String> where
let ret = if ptr::null() == last_error {
Ok(result)
} else {
let s = ffi::c_str_to_bytes(&last_error);
let s = CStr::from_ptr(last_error).to_bytes();
Err(str::from_utf8(s).unwrap().to_string())
};

View File

@ -8,18 +8,25 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering};
use error::{Error, FromError};
use fmt;
use io;
use iter::IteratorExt;
use libc;
use mem;
use old_io;
use ops::Deref;
use option::Option::{self, Some, None};
use result::Result::{self, Ok, Err};
use slice::{self, SliceExt};
use str::StrExt;
use string::String;
use vec::Vec;
/// A type representing a C-compatible string
/// A type representing an owned C-compatible string
///
/// This type serves the primary purpose of being able to generate a
/// This type serves the primary purpose of being able to safely generate a
/// C-compatible string from a Rust byte slice or vector. An instance of this
/// type is a static guarantee that the underlying bytes contain no interior 0
/// bytes and the final byte is 0.
@ -44,8 +51,8 @@
/// fn my_printer(s: *const libc::c_char);
/// }
///
/// let to_print = "Hello, world!";
/// let c_to_print = CString::from_slice(to_print.as_bytes());
/// let to_print = b"Hello, world!";
/// let c_to_print = CString::new(to_print).unwrap();
/// unsafe {
/// my_printer(c_to_print.as_ptr());
/// }
@ -53,19 +60,135 @@
/// ```
#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
pub struct CString {
inner: Vec<libc::c_char>,
inner: Vec<u8>,
}
/// Representation of a borrowed C string.
///
/// This dynamically sized type is only safely constructed via a borrowed
/// version of an instance of `CString`. This type can be constructed from a raw
/// C string as well and represents a C string borrowed from another location.
///
/// Note that this structure is **not** `repr(C)` and is not recommended to be
/// placed in the signatures of FFI functions. Instead safe wrappers of FFI
/// functions may leverage the unsafe `from_ptr` constructor to provide a safe
/// interface to other consumers.
///
/// # Examples
///
/// Inspecting a foreign C string
///
/// ```no_run
/// extern crate libc;
/// use std::ffi::CStr;
///
/// extern { fn my_string() -> *const libc::c_char; }
///
/// fn main() {
/// unsafe {
/// let slice = CStr::from_ptr(my_string());
/// println!("string length: {}", slice.to_bytes().len());
/// }
/// }
/// ```
///
/// Passing a Rust-originating C string
///
/// ```no_run
/// extern crate libc;
/// use std::ffi::{CString, CStr};
///
/// fn work(data: &CStr) {
/// extern { fn work_with(data: *const libc::c_char); }
///
/// unsafe { work_with(data.as_ptr()) }
/// }
///
/// fn main() {
/// let s = CString::from_slice(b"data data data data").unwrap();
/// work(&s);
/// }
/// ```
#[derive(Hash)]
pub struct CStr {
inner: [libc::c_char]
}
/// An error returned from `CString::new` to indicate that a nul byte was found
/// in the vector provided.
#[derive(Clone, PartialEq, Debug)]
pub struct NulError(usize, Vec<u8>);
/// A conversion trait used by the constructor of `CString` for types that can
/// be converted to a vector of bytes.
pub trait IntoBytes {
/// Consumes this container, returning a vector of bytes.
fn into_bytes(self) -> Vec<u8>;
}
impl CString {
/// Create a new C-compatible string from a container of bytes.
///
/// This method will consume the provided data and use the underlying bytes
/// to construct a new string, ensuring that there is a trailing 0 byte.
///
/// # Examples
///
/// ```no_run
/// extern crate libc;
/// use std::ffi::CString;
///
/// extern { fn puts(s: *const libc::c_char); }
///
/// fn main() {
/// let to_print = CString::from_slice(b"Hello!").unwrap();
/// unsafe {
/// puts(to_print.as_ptr());
/// }
/// }
/// ```
///
/// # Errors
///
/// This function will return an error if the bytes yielded contain an
/// internal 0 byte. The error returned will contain the bytes as well as
/// the position of the nul byte.
pub fn new<T: IntoBytes>(t: T) -> Result<CString, NulError> {
let bytes = t.into_bytes();
match bytes.iter().position(|x| *x == 0) {
Some(i) => Err(NulError(i, bytes)),
None => Ok(unsafe { CString::from_vec_unchecked(bytes) }),
}
}
/// Create a new C-compatible string from a byte slice.
///
/// This method will copy the data of the slice provided into a new
/// allocation, ensuring that there is a trailing 0 byte.
///
/// # Examples
///
/// ```no_run
/// extern crate libc;
/// use std::ffi::CString;
///
/// extern { fn puts(s: *const libc::c_char); }
///
/// fn main() {
/// let to_print = CString::from_slice(b"Hello!").unwrap();
/// unsafe {
/// puts(to_print.as_ptr());
/// }
/// }
/// ```
///
/// # Panics
///
/// This function will panic if there are any 0 bytes already in the slice
/// provided.
/// This function will panic if the provided slice contains any
/// interior nul bytes.
#[unstable(feature = "std_misc")]
#[deprecated(since = "1.0.0", reason = "use CString::new instead")]
#[allow(deprecated)]
pub fn from_slice(v: &[u8]) -> CString {
CString::from_vec(v.to_vec())
}
@ -77,11 +200,15 @@ pub fn from_slice(v: &[u8]) -> CString {
///
/// # Panics
///
/// This function will panic if there are any 0 bytes already in the vector
/// provided.
/// This function will panic if the provided slice contains any
/// interior nul bytes.
#[unstable(feature = "std_misc")]
#[deprecated(since = "1.0.0", reason = "use CString::new instead")]
pub fn from_vec(v: Vec<u8>) -> CString {
assert!(!v.iter().any(|&x| x == 0));
unsafe { CString::from_vec_unchecked(v) }
match v.iter().position(|x| *x == 0) {
Some(i) => panic!("null byte found in slice at: {}", i),
None => unsafe { CString::from_vec_unchecked(v) },
}
}
/// Create a C-compatible string from a byte vector without checking for
@ -91,31 +218,29 @@ pub fn from_vec(v: Vec<u8>) -> CString {
/// is made that `v` contains no 0 bytes.
pub unsafe fn from_vec_unchecked(mut v: Vec<u8>) -> CString {
v.push(0);
CString { inner: mem::transmute(v) }
CString { inner: v }
}
/// Create a view into this C string which includes the trailing nul
/// terminator at the end of the string.
pub fn as_slice_with_nul(&self) -> &[libc::c_char] { &self.inner }
/// Similar to the `as_slice` method, but returns a `u8` slice instead of a
/// `libc::c_char` slice.
/// Returns the contents of this `CString` as a slice of bytes.
///
/// The returned slice does **not** contain the trailing nul separator and
/// it is guaranteet to not have any interior nul bytes.
pub fn as_bytes(&self) -> &[u8] {
unsafe { mem::transmute(&**self) }
&self.inner[..self.inner.len() - 1]
}
/// Equivalent to `as_slice_with_nul` except that the type returned is a
/// `u8` slice instead of a `libc::c_char` slice.
/// Equivalent to the `as_bytes` function except that the returned slice
/// includes the trailing nul byte.
pub fn as_bytes_with_nul(&self) -> &[u8] {
unsafe { mem::transmute(self.as_slice_with_nul()) }
&self.inner
}
}
impl Deref for CString {
type Target = [libc::c_char];
type Target = CStr;
fn deref(&self) -> &[libc::c_char] {
&self.inner[..(self.inner.len() - 1)]
fn deref(&self) -> &CStr {
unsafe { mem::transmute(self.as_bytes_with_nul()) }
}
}
@ -126,54 +251,172 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
}
}
/// Interpret a C string as a byte slice.
///
/// This function will calculate the length of the C string provided, and it
/// will then return a corresponding slice for the contents of the C string not
/// including the nul terminator.
///
/// This function will tie the lifetime of the returned slice to the lifetime of
/// the pointer provided. This is done to help prevent the slice from escaping
/// the lifetime of the pointer itself. If a longer lifetime is needed, then
/// `mem::copy_lifetime` should be used.
///
/// This function is unsafe because there is no guarantee of the validity of the
/// pointer `raw` or a guarantee that a nul terminator will be found.
///
/// # Example
///
/// ```no_run
/// # extern crate libc;
/// # fn main() {
/// use std::ffi;
/// use std::str;
/// use libc;
///
/// extern {
/// fn my_string() -> *const libc::c_char;
/// }
///
/// unsafe {
/// let to_print = my_string();
/// let slice = ffi::c_str_to_bytes(&to_print);
/// println!("string returned: {}", str::from_utf8(slice).unwrap());
/// }
/// # }
/// ```
impl NulError {
/// Returns the position of the nul byte in the slice that was provided to
/// `CString::from_vec`.
pub fn nul_position(&self) -> usize { self.0 }
/// Consumes this error, returning the underlying vector of bytes which
/// generated the error in the first place.
pub fn into_vec(self) -> Vec<u8> { self.1 }
}
impl Error for NulError {
fn description(&self) -> &str { "nul byte found in data" }
}
impl fmt::Display for NulError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "nul byte found in provided data at position: {}", self.0)
}
}
impl FromError<NulError> for io::Error {
fn from_error(_: NulError) -> io::Error {
io::Error::new(io::ErrorKind::InvalidInput,
"data provided contains a nul byte", None)
}
}
impl FromError<NulError> for old_io::IoError {
fn from_error(_: NulError) -> old_io::IoError {
old_io::IoError {
kind: old_io::IoErrorKind::InvalidInput,
desc: "data provided contains a nul byte",
detail: None
}
}
}
impl CStr {
/// Cast a raw C string to a safe C string wrapper.
///
/// This function will cast the provided `ptr` to the `CStr` wrapper which
/// allows inspection and interoperation of non-owned C strings. This method
/// is unsafe for a number of reasons:
///
/// * There is no guarantee to the validity of `ptr`
/// * The returned lifetime is not guaranteed to be the actual lifetime of
/// `ptr`
/// * There is no guarantee that the memory pointed to by `ptr` contains a
/// valid nul terminator byte at the end of the string.
///
/// > **Note**: This operation is intended to be a 0-cost cast but it is
/// > currently implemented with an up-front calculation of the length of
/// > the string. This is not guaranteed to always be the case.
///
/// # Example
///
/// ```no_run
/// # extern crate libc;
/// # fn main() {
/// use std::ffi::CStr;
/// use std::str;
/// use libc;
///
/// extern {
/// fn my_string() -> *const libc::c_char;
/// }
///
/// unsafe {
/// let slice = CStr::from_ptr(my_string());
/// println!("string returned: {}",
/// str::from_utf8(slice.to_bytes()).unwrap());
/// }
/// # }
/// ```
pub unsafe fn from_ptr<'a>(ptr: *const libc::c_char) -> &'a CStr {
let len = libc::strlen(ptr);
mem::transmute(slice::from_raw_parts(ptr, len as usize + 1))
}
/// Return the inner pointer to this C string.
///
/// The returned pointer will be valid for as long as `self` is and points
/// to a continguous region of memory terminated with a 0 byte to represent
/// the end of the string.
pub fn as_ptr(&self) -> *const libc::c_char {
self.inner.as_ptr()
}
/// Convert this C string to a byte slice.
///
/// This function will calculate the length of this string (which normally
/// requires a linear amount of work to be done) and then return the
/// resulting slice of `u8` elements.
///
/// The returned slice will **not** contain the trailing nul that this C
/// string has.
///
/// > **Note**: This method is currently implemented as a 0-cost cast, but
/// > it is planned to alter its definition in the future to perform the
/// > length calculation whenever this method is called.
pub fn to_bytes(&self) -> &[u8] {
let bytes = self.to_bytes_with_nul();
&bytes[..bytes.len() - 1]
}
/// Convert this C string to a byte slice containing the trailing 0 byte.
///
/// This function is the equivalent of `to_bytes` except that it will retain
/// the trailing nul instead of chopping it off.
///
/// > **Note**: This method is currently implemented as a 0-cost cast, but
/// > it is planned to alter its definition in the future to perform the
/// > length calculation whenever this method is called.
pub fn to_bytes_with_nul(&self) -> &[u8] {
unsafe { mem::transmute::<&[libc::c_char], &[u8]>(&self.inner) }
}
}
impl PartialEq for CStr {
fn eq(&self, other: &CStr) -> bool {
self.to_bytes().eq(&other.to_bytes())
}
}
impl Eq for CStr {}
impl PartialOrd for CStr {
fn partial_cmp(&self, other: &CStr) -> Option<Ordering> {
self.to_bytes().partial_cmp(&other.to_bytes())
}
}
impl Ord for CStr {
fn cmp(&self, other: &CStr) -> Ordering {
self.to_bytes().cmp(&other.to_bytes())
}
}
/// Deprecated in favor of `CStr`
#[unstable(feature = "std_misc")]
#[deprecated(since = "1.0.0", reason = "use CStr::from_ptr(p).to_bytes() instead")]
pub unsafe fn c_str_to_bytes<'a>(raw: &'a *const libc::c_char) -> &'a [u8] {
let len = libc::strlen(*raw);
slice::from_raw_parts(*(raw as *const _ as *const *const u8), len as usize)
}
/// Interpret a C string as a byte slice with the nul terminator.
///
/// This function is identical to `from_raw_buf` except that the returned slice
/// will include the nul terminator of the string.
pub unsafe fn c_str_to_bytes_with_nul<'a>(raw: &'a *const libc::c_char) -> &'a [u8] {
/// Deprecated in favor of `CStr`
#[unstable(feature = "std_misc")]
#[deprecated(since = "1.0.0",
reason = "use CStr::from_ptr(p).to_bytes_with_nul() instead")]
pub unsafe fn c_str_to_bytes_with_nul<'a>(raw: &'a *const libc::c_char)
-> &'a [u8] {
let len = libc::strlen(*raw) + 1;
slice::from_raw_parts(*(raw as *const _ as *const *const u8), len as usize)
}
impl<'a> IntoBytes for &'a str {
fn into_bytes(self) -> Vec<u8> { self.as_bytes().to_vec() }
}
impl<'a> IntoBytes for &'a [u8] {
fn into_bytes(self) -> Vec<u8> { self.to_vec() }
}
impl IntoBytes for String {
fn into_bytes(self) -> Vec<u8> { self.into_bytes() }
}
impl IntoBytes for Vec<u8> {
fn into_bytes(self) -> Vec<u8> { self }
}
#[cfg(test)]
mod tests {
use prelude::v1::*;
@ -193,21 +436,19 @@ fn c_to_rust() {
#[test]
fn simple() {
let s = CString::from_slice(b"1234");
let s = CString::from_slice(b"1234").unwrap();
assert_eq!(s.as_bytes(), b"1234");
assert_eq!(s.as_bytes_with_nul(), b"1234\0");
unsafe {
assert_eq!(&*s,
mem::transmute::<_, &[libc::c_char]>(b"1234"));
assert_eq!(s.as_slice_with_nul(),
mem::transmute::<_, &[libc::c_char]>(b"1234\0"));
}
}
#[should_fail] #[test]
fn build_with_zero1() { CString::from_slice(b"\0"); }
#[should_fail] #[test]
fn build_with_zero2() { CString::from_vec(vec![0]); }
#[test]
fn build_with_zero1() {
assert!(CString::from_slice(b"\0").is_err());
}
#[test]
fn build_with_zero2() {
assert!(CString::from_vec(vec![0]).is_err());
}
#[test]
fn build_with_zero3() {
@ -219,7 +460,16 @@ fn build_with_zero3() {
#[test]
fn formatted() {
let s = CString::from_slice(b"12");
let s = CString::from_slice(b"12").unwrap();
assert_eq!(format!("{:?}", s), "\"12\"");
}
#[test]
fn borrowed() {
unsafe {
let s = CStr::from_ptr(b"12\0".as_ptr() as *const _);
assert_eq!(s.to_bytes(), b"12");
assert_eq!(s.to_bytes_with_nul(), b"12\0");
}
}
}

View File

@ -14,8 +14,10 @@
reason = "module just underwent fairly large reorganization and the dust \
still needs to settle")]
pub use self::c_str::CString;
pub use self::c_str::{CString, CStr, NulError, IntoBytes};
#[allow(deprecated)]
pub use self::c_str::c_str_to_bytes;
#[allow(deprecated)]
pub use self::c_str::c_str_to_bytes_with_nul;
pub use self::os_str::OsString;

View File

@ -55,7 +55,7 @@ impl UnixStream {
/// stream.write(&[1, 2, 3]);
/// ```
pub fn connect<P: BytesContainer>(path: P) -> IoResult<UnixStream> {
let path = CString::from_slice(path.container_as_bytes());
let path = try!(CString::new(path.container_as_bytes()));
UnixStreamImp::connect(&path, None)
.map(|inner| UnixStream { inner: inner })
}
@ -77,7 +77,7 @@ pub fn connect_timeout<P>(path: P, timeout: Duration)
return Err(standard_error(TimedOut));
}
let path = CString::from_slice(path.container_as_bytes());
let path = try!(CString::new(path.container_as_bytes()));
UnixStreamImp::connect(&path, Some(timeout.num_milliseconds() as u64))
.map(|inner| UnixStream { inner: inner })
}
@ -184,7 +184,7 @@ impl UnixListener {
/// # }
/// ```
pub fn bind<P: BytesContainer>(path: P) -> IoResult<UnixListener> {
let path = CString::from_slice(path.container_as_bytes());
let path = try!(CString::new(path.container_as_bytes()));
UnixListenerImp::bind(&path)
.map(|inner| UnixListener { inner: inner })
}

View File

@ -204,7 +204,7 @@ impl Command {
/// otherwise configure the process.
pub fn new<T: BytesContainer>(program: T) -> Command {
Command {
program: CString::from_slice(program.container_as_bytes()),
program: CString::new(program.container_as_bytes()).unwrap(),
args: Vec::new(),
env: None,
cwd: None,
@ -219,14 +219,14 @@ pub fn new<T: BytesContainer>(program: T) -> Command {
/// Add an argument to pass to the program.
pub fn arg<'a, T: BytesContainer>(&'a mut self, arg: T) -> &'a mut Command {
self.args.push(CString::from_slice(arg.container_as_bytes()));
self.args.push(CString::new(arg.container_as_bytes()).unwrap());
self
}
/// Add multiple arguments to pass to the program.
pub fn args<'a, T: BytesContainer>(&'a mut self, args: &[T]) -> &'a mut Command {
self.args.extend(args.iter().map(|arg| {
CString::from_slice(arg.container_as_bytes())
CString::new(arg.container_as_bytes()).unwrap()
}));
self
}
@ -239,8 +239,8 @@ fn get_env_map<'a>(&'a mut self) -> &'a mut EnvMap {
// if the env is currently just inheriting from the parent's,
// materialize the parent's env into a hashtable.
self.env = Some(os::env_as_bytes().into_iter().map(|(k, v)| {
(EnvKey(CString::from_slice(&k)),
CString::from_slice(&v))
(EnvKey(CString::new(k).unwrap()),
CString::new(v).unwrap())
}).collect());
self.env.as_mut().unwrap()
}
@ -254,8 +254,8 @@ fn get_env_map<'a>(&'a mut self) -> &'a mut EnvMap {
pub fn env<'a, T, U>(&'a mut self, key: T, val: U)
-> &'a mut Command
where T: BytesContainer, U: BytesContainer {
let key = EnvKey(CString::from_slice(key.container_as_bytes()));
let val = CString::from_slice(val.container_as_bytes());
let key = EnvKey(CString::new(key.container_as_bytes()).unwrap());
let val = CString::new(val.container_as_bytes()).unwrap();
self.get_env_map().insert(key, val);
self
}
@ -263,7 +263,7 @@ pub fn env<'a, T, U>(&'a mut self, key: T, val: U)
/// Removes an environment variable mapping.
pub fn env_remove<'a, T>(&'a mut self, key: T) -> &'a mut Command
where T: BytesContainer {
let key = EnvKey(CString::from_slice(key.container_as_bytes()));
let key = EnvKey(CString::new(key.container_as_bytes()).unwrap());
self.get_env_map().remove(&key);
self
}
@ -276,15 +276,15 @@ pub fn env_set_all<'a, T, U>(&'a mut self, env: &[(T,U)])
-> &'a mut Command
where T: BytesContainer, U: BytesContainer {
self.env = Some(env.iter().map(|&(ref k, ref v)| {
(EnvKey(CString::from_slice(k.container_as_bytes())),
CString::from_slice(v.container_as_bytes()))
(EnvKey(CString::new(k.container_as_bytes()).unwrap()),
CString::new(v.container_as_bytes()).unwrap())
}).collect());
self
}
/// Set the working directory for the child process.
pub fn cwd<'a>(&'a mut self, dir: &Path) -> &'a mut Command {
self.cwd = Some(CString::from_slice(dir.as_vec()));
self.cwd = Some(CString::new(dir.as_vec()).unwrap());
self
}
@ -1226,7 +1226,7 @@ fn env_map_keys_ci() {
cmd.env("path", "foo");
cmd.env("Path", "bar");
let env = &cmd.env.unwrap();
let val = env.get(&EnvKey(CString::from_slice(b"PATH")));
assert!(val.unwrap() == &CString::from_slice(b"bar"));
let val = env.get(&EnvKey(CString::new(b"PATH").unwrap()));
assert!(val.unwrap() == &CString::new(b"bar").unwrap());
}
}

View File

@ -49,7 +49,7 @@ mod imp {
use libc;
use mem;
use ffi;
use ffi::CStr;
use sync::{StaticMutex, MUTEX_INIT};
@ -96,10 +96,11 @@ fn get_global_ptr() -> *mut Option<Box<Vec<Vec<u8>>>> {
unsafe { mem::transmute(&GLOBAL_ARGS_PTR) }
}
unsafe fn load_argc_and_argv(argc: int, argv: *const *const u8) -> Vec<Vec<u8>> {
unsafe fn load_argc_and_argv(argc: isize,
argv: *const *const u8) -> Vec<Vec<u8>> {
let argv = argv as *const *const libc::c_char;
(0..argc as uint).map(|i| {
ffi::c_str_to_bytes(&*argv.offset(i as int)).to_vec()
(0..argc).map(|i| {
CStr::from_ptr(*argv.offset(i)).to_bytes().to_vec()
}).collect()
}

View File

@ -12,8 +12,7 @@
use self::SocketStatus::*;
use self::InAddr::*;
use ffi::CString;
use ffi;
use ffi::{CString, CStr};
use old_io::net::addrinfo;
use old_io::net::ip::{SocketAddr, IpAddr, Ipv4Addr, Ipv6Addr};
use old_io::{IoResult, IoError};
@ -235,9 +234,15 @@ pub fn get_host_addresses(host: Option<&str>, servname: Option<&str>,
assert!(host.is_some() || servname.is_some());
let c_host = host.map(|x| CString::from_slice(x.as_bytes()));
let c_host = match host {
Some(x) => Some(try!(CString::new(x))),
None => None,
};
let c_host = c_host.as_ref().map(|x| x.as_ptr()).unwrap_or(null());
let c_serv = servname.map(|x| CString::from_slice(x.as_bytes()));
let c_serv = match servname {
Some(x) => Some(try!(CString::new(x))),
None => None,
};
let c_serv = c_serv.as_ref().map(|x| x.as_ptr()).unwrap_or(null());
let hint = hint.map(|hint| {
@ -325,8 +330,8 @@ pub fn get_address_name(addr: IpAddr) -> Result<String, IoError> {
}
unsafe {
Ok(str::from_utf8(ffi::c_str_to_bytes(&hostbuf.as_ptr()))
.unwrap().to_string())
let data = CStr::from_ptr(hostbuf.as_ptr());
Ok(str::from_utf8(data.to_bytes()).unwrap().to_string())
}
}

View File

@ -121,7 +121,7 @@ fn drop(&mut self) {
pub fn lookup_host(host: &str) -> io::Result<LookupHost> {
init();
let c_host = CString::from_slice(host.as_bytes());
let c_host = try!(CString::new(host));
let mut res = 0 as *mut _;
unsafe {
try!(cvt_gai(getaddrinfo(c_host.as_ptr(), 0 as *const _, 0 as *const _,

View File

@ -85,7 +85,7 @@
use prelude::v1::*;
use ffi;
use ffi::CStr;
use old_io::IoResult;
use libc;
use mem;
@ -233,7 +233,7 @@ fn dladdr(addr: *const libc::c_void,
output(w, idx,addr, None)
} else {
output(w, idx, addr, Some(unsafe {
ffi::c_str_to_bytes(&info.dli_sname)
CStr::from_ptr(info.dli_sname).to_bytes()
}))
}
}
@ -364,7 +364,7 @@ unsafe fn init_state() -> *mut backtrace_state {
if ret == 0 || data.is_null() {
output(w, idx, addr, None)
} else {
output(w, idx, addr, Some(unsafe { ffi::c_str_to_bytes(&data) }))
output(w, idx, addr, Some(unsafe { CStr::from_ptr(data).to_bytes() }))
}
}

View File

@ -33,7 +33,7 @@
use prelude::v1::*;
use ffi::{CString, OsStr, OsString};
use ffi::{CString, NulError, OsStr, OsString};
use fs::{self, Permissions, OpenOptions};
use net;
use mem;
@ -155,7 +155,7 @@ pub trait OsStrExt {
fn as_bytes(&self) -> &[u8];
/// Convert the `OsStr` slice into a `CString`.
fn to_cstring(&self) -> CString;
fn to_cstring(&self) -> Result<CString, NulError>;
}
impl OsStrExt for OsStr {
@ -166,8 +166,8 @@ fn as_bytes(&self) -> &[u8] {
&self.as_inner().inner
}
fn to_cstring(&self) -> CString {
CString::from_slice(self.as_bytes())
fn to_cstring(&self) -> Result<CString, NulError> {
CString::new(self.as_bytes())
}
}
@ -249,5 +249,7 @@ fn signal(&self) -> Option<i32> {
/// Includes all extension traits, and some important type definitions.
pub mod prelude {
#[doc(no_inline)]
pub use super::{Fd, AsRawFd, OsStrExt, OsStringExt, PermissionsExt, CommandExt, ExitStatusExt};
pub use super::{Fd, AsRawFd, OsStrExt, OsStringExt, PermissionsExt};
#[doc(no_inline)]
pub use super::{CommandExt, ExitStatusExt};
}

View File

@ -12,7 +12,7 @@
use prelude::v1::*;
use ffi::{self, CString};
use ffi::{CString, CStr};
use old_io::{FilePermission, Write, UnstableFileStat, Open, FileAccess, FileMode};
use old_io::{IoResult, FileStat, SeekStyle};
use old_io::{Read, Truncate, SeekCur, SeekSet, ReadWrite, SeekEnd, Append};
@ -151,8 +151,8 @@ fn drop(&mut self) {
}
}
fn cstr(path: &Path) -> CString {
CString::from_slice(path.as_vec())
fn cstr(path: &Path) -> IoResult<CString> {
Ok(try!(CString::new(path.as_vec())))
}
pub fn open(path: &Path, fm: FileMode, fa: FileAccess) -> IoResult<FileDesc> {
@ -170,7 +170,7 @@ pub fn open(path: &Path, fm: FileMode, fa: FileAccess) -> IoResult<FileDesc> {
libc::S_IRUSR | libc::S_IWUSR),
};
let path = cstr(path);
let path = try!(cstr(path));
match retry(|| unsafe { libc::open(path.as_ptr(), flags, mode) }) {
-1 => Err(super::last_error()),
fd => Ok(FileDesc::new(fd, true)),
@ -178,7 +178,7 @@ pub fn open(path: &Path, fm: FileMode, fa: FileAccess) -> IoResult<FileDesc> {
}
pub fn mkdir(p: &Path, mode: uint) -> IoResult<()> {
let p = cstr(p);
let p = try!(cstr(p));
mkerr_libc(unsafe { libc::mkdir(p.as_ptr(), mode as libc::mode_t) })
}
@ -203,7 +203,7 @@ fn prune(root: &CString, dirs: Vec<Path>) -> Vec<Path> {
let mut buf = Vec::<u8>::with_capacity(size as uint);
let ptr = buf.as_mut_ptr() as *mut dirent_t;
let p = CString::from_slice(p.as_vec());
let p = try!(CString::new(p.as_vec()));
let dir_ptr = unsafe {opendir(p.as_ptr())};
if dir_ptr as uint != 0 {
@ -212,7 +212,7 @@ fn prune(root: &CString, dirs: Vec<Path>) -> Vec<Path> {
while unsafe { readdir_r(dir_ptr, ptr, &mut entry_ptr) == 0 } {
if entry_ptr.is_null() { break }
paths.push(unsafe {
Path::new(ffi::c_str_to_bytes(&rust_list_dir_val(entry_ptr)))
Path::new(CStr::from_ptr(rust_list_dir_val(entry_ptr)).to_bytes())
});
}
assert_eq!(unsafe { closedir(dir_ptr) }, 0);
@ -223,39 +223,39 @@ fn prune(root: &CString, dirs: Vec<Path>) -> Vec<Path> {
}
pub fn unlink(p: &Path) -> IoResult<()> {
let p = cstr(p);
let p = try!(cstr(p));
mkerr_libc(unsafe { libc::unlink(p.as_ptr()) })
}
pub fn rename(old: &Path, new: &Path) -> IoResult<()> {
let old = cstr(old);
let new = cstr(new);
let old = try!(cstr(old));
let new = try!(cstr(new));
mkerr_libc(unsafe {
libc::rename(old.as_ptr(), new.as_ptr())
})
}
pub fn chmod(p: &Path, mode: uint) -> IoResult<()> {
let p = cstr(p);
let p = try!(cstr(p));
mkerr_libc(retry(|| unsafe {
libc::chmod(p.as_ptr(), mode as libc::mode_t)
}))
}
pub fn rmdir(p: &Path) -> IoResult<()> {
let p = cstr(p);
let p = try!(cstr(p));
mkerr_libc(unsafe { libc::rmdir(p.as_ptr()) })
}
pub fn chown(p: &Path, uid: int, gid: int) -> IoResult<()> {
let p = cstr(p);
let p = try!(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 = cstr(p);
let c_path = try!(cstr(p));
let p = c_path.as_ptr();
let mut len = unsafe { libc::pathconf(p as *mut _, libc::_PC_NAME_MAX) };
if len == -1 {
@ -276,14 +276,14 @@ pub fn readlink(p: &Path) -> IoResult<Path> {
}
pub fn symlink(src: &Path, dst: &Path) -> IoResult<()> {
let src = cstr(src);
let dst = cstr(dst);
let src = try!(cstr(src));
let dst = try!(cstr(dst));
mkerr_libc(unsafe { libc::symlink(src.as_ptr(), dst.as_ptr()) })
}
pub fn link(src: &Path, dst: &Path) -> IoResult<()> {
let src = cstr(src);
let dst = cstr(dst);
let src = try!(cstr(src));
let dst = try!(cstr(dst));
mkerr_libc(unsafe { libc::link(src.as_ptr(), dst.as_ptr()) })
}
@ -331,7 +331,7 @@ fn gen(_stat: &libc::stat) -> u64 { 0 }
}
pub fn stat(p: &Path) -> IoResult<FileStat> {
let p = cstr(p);
let p = try!(cstr(p));
let mut stat: libc::stat = unsafe { mem::zeroed() };
match unsafe { libc::stat(p.as_ptr(), &mut stat) } {
0 => Ok(mkstat(&stat)),
@ -340,7 +340,7 @@ pub fn stat(p: &Path) -> IoResult<FileStat> {
}
pub fn lstat(p: &Path) -> IoResult<FileStat> {
let p = cstr(p);
let p = try!(cstr(p));
let mut stat: libc::stat = unsafe { mem::zeroed() };
match unsafe { libc::lstat(p.as_ptr(), &mut stat) } {
0 => Ok(mkstat(&stat)),
@ -349,7 +349,7 @@ pub fn lstat(p: &Path) -> IoResult<FileStat> {
}
pub fn utime(p: &Path, atime: u64, mtime: u64) -> IoResult<()> {
let p = cstr(p);
let p = try!(cstr(p));
let buf = libc::utimbuf {
actime: (atime / 1000) as libc::time_t,
modtime: (mtime / 1000) as libc::time_t,

View File

@ -12,7 +12,7 @@
use io::prelude::*;
use os::unix::prelude::*;
use ffi::{self, CString, OsString, AsOsStr, OsStr};
use ffi::{CString, CStr, OsString, AsOsStr, OsStr};
use io::{self, Error, Seek, SeekFrom};
use libc::{self, c_int, c_void, size_t, off_t, c_char, mode_t};
use mem;
@ -147,8 +147,7 @@ fn name_bytes(&self) -> &[u8] {
fn rust_list_dir_val(ptr: *mut libc::dirent_t) -> *const c_char;
}
unsafe {
let ptr = rust_list_dir_val(self.dirent);
ffi::c_str_to_bytes(mem::copy_lifetime(self, &ptr))
CStr::from_ptr(rust_list_dir_val(self.dirent)).to_bytes()
}
}
}
@ -204,7 +203,7 @@ pub fn open(path: &Path, opts: &OpenOptions) -> io::Result<File> {
(true, false) |
(false, false) => libc::O_RDONLY,
};
let path = cstr(path);
let path = try!(cstr(path));
let fd = try!(cvt_r(|| unsafe {
libc::open(path.as_ptr(), flags, opts.mode)
}));
@ -268,19 +267,20 @@ pub fn seek(&self, pos: SeekFrom) -> io::Result<u64> {
pub fn fd(&self) -> &FileDesc { &self.0 }
}
fn cstr(path: &Path) -> CString {
CString::from_slice(path.as_os_str().as_bytes())
fn cstr(path: &Path) -> io::Result<CString> {
let cstring = try!(path.as_os_str().to_cstring());
Ok(cstring)
}
pub fn mkdir(p: &Path) -> io::Result<()> {
let p = cstr(p);
let p = try!(cstr(p));
try!(cvt(unsafe { libc::mkdir(p.as_ptr(), 0o777) }));
Ok(())
}
pub fn readdir(p: &Path) -> io::Result<ReadDir> {
let root = Rc::new(p.to_path_buf());
let p = cstr(p);
let p = try!(cstr(p));
unsafe {
let ptr = libc::opendir(p.as_ptr());
if ptr.is_null() {
@ -292,32 +292,32 @@ pub fn readdir(p: &Path) -> io::Result<ReadDir> {
}
pub fn unlink(p: &Path) -> io::Result<()> {
let p = cstr(p);
let p = try!(cstr(p));
try!(cvt(unsafe { libc::unlink(p.as_ptr()) }));
Ok(())
}
pub fn rename(old: &Path, new: &Path) -> io::Result<()> {
let old = cstr(old);
let new = cstr(new);
let old = try!(cstr(old));
let new = try!(cstr(new));
try!(cvt(unsafe { libc::rename(old.as_ptr(), new.as_ptr()) }));
Ok(())
}
pub fn set_perm(p: &Path, perm: FilePermissions) -> io::Result<()> {
let p = cstr(p);
let p = try!(cstr(p));
try!(cvt_r(|| unsafe { libc::chmod(p.as_ptr(), perm.mode) }));
Ok(())
}
pub fn rmdir(p: &Path) -> io::Result<()> {
let p = cstr(p);
let p = try!(cstr(p));
try!(cvt(unsafe { libc::rmdir(p.as_ptr()) }));
Ok(())
}
pub fn chown(p: &Path, uid: isize, gid: isize) -> io::Result<()> {
let p = cstr(p);
let p = try!(cstr(p));
try!(cvt_r(|| unsafe {
libc::chown(p.as_ptr(), uid as libc::uid_t, gid as libc::gid_t)
}));
@ -325,7 +325,7 @@ pub fn chown(p: &Path, uid: isize, gid: isize) -> io::Result<()> {
}
pub fn readlink(p: &Path) -> io::Result<PathBuf> {
let c_path = cstr(p);
let c_path = try!(cstr(p));
let p = c_path.as_ptr();
let mut len = unsafe { libc::pathconf(p as *mut _, libc::_PC_NAME_MAX) };
if len < 0 {
@ -343,35 +343,35 @@ pub fn readlink(p: &Path) -> io::Result<PathBuf> {
}
pub fn symlink(src: &Path, dst: &Path) -> io::Result<()> {
let src = cstr(src);
let dst = cstr(dst);
let src = try!(cstr(src));
let dst = try!(cstr(dst));
try!(cvt(unsafe { libc::symlink(src.as_ptr(), dst.as_ptr()) }));
Ok(())
}
pub fn link(src: &Path, dst: &Path) -> io::Result<()> {
let src = cstr(src);
let dst = cstr(dst);
let src = try!(cstr(src));
let dst = try!(cstr(dst));
try!(cvt(unsafe { libc::link(src.as_ptr(), dst.as_ptr()) }));
Ok(())
}
pub fn stat(p: &Path) -> io::Result<FileAttr> {
let p = cstr(p);
let p = try!(cstr(p));
let mut stat: libc::stat = unsafe { mem::zeroed() };
try!(cvt(unsafe { libc::stat(p.as_ptr(), &mut stat) }));
Ok(FileAttr { stat: stat })
}
pub fn lstat(p: &Path) -> io::Result<FileAttr> {
let p = cstr(p);
let p = try!(cstr(p));
let mut stat: libc::stat = unsafe { mem::zeroed() };
try!(cvt(unsafe { libc::lstat(p.as_ptr(), &mut stat) }));
Ok(FileAttr { stat: stat })
}
pub fn utimes(p: &Path, atime: u64, mtime: u64) -> io::Result<()> {
let p = cstr(p);
let p = try!(cstr(p));
let buf = [super::ms_to_timeval(atime), super::ms_to_timeval(mtime)];
try!(cvt(unsafe { c::utimes(p.as_ptr(), buf.as_ptr()) }));
Ok(())

View File

@ -17,7 +17,7 @@
use prelude::v1::*;
use ffi;
use ffi::CStr;
use io::{self, ErrorKind};
use libc;
use num::{Int, SignedInt};
@ -91,7 +91,8 @@ pub fn last_gai_error(s: libc::c_int) -> IoError {
let mut err = decode_error(s);
err.detail = Some(unsafe {
str::from_utf8(ffi::c_str_to_bytes(&gai_strerror(s))).unwrap().to_string()
let data = CStr::from_ptr(gai_strerror(s));
str::from_utf8(data.to_bytes()).unwrap().to_string()
});
err
}

View File

@ -10,7 +10,7 @@
use prelude::v1::*;
use ffi;
use ffi::CStr;
use io;
use libc::{self, c_int, size_t};
use str;
@ -31,7 +31,7 @@ pub fn cvt_gai(err: c_int) -> io::Result<()> {
if err == 0 { return Ok(()) }
let detail = unsafe {
str::from_utf8(ffi::c_str_to_bytes(&c::gai_strerror(err))).unwrap()
str::from_utf8(CStr::from_ptr(c::gai_strerror(err)).to_bytes()).unwrap()
.to_string()
};
Err(io::Error::new(io::ErrorKind::Other,

View File

@ -14,7 +14,7 @@
use os::unix::*;
use error::Error as StdError;
use ffi::{self, CString, OsString, OsStr, AsOsStr};
use ffi::{CString, CStr, OsString, OsStr, AsOsStr};
use fmt;
use iter;
use libc::{self, c_int, c_char, c_void};
@ -88,7 +88,7 @@ fn strerror_r(errnum: c_int, buf: *mut c_char,
}
let p = p as *const _;
str::from_utf8(ffi::c_str_to_bytes(&p)).unwrap().to_string()
str::from_utf8(CStr::from_ptr(p).to_bytes()).unwrap().to_string()
}
}
@ -98,13 +98,13 @@ pub fn getcwd() -> IoResult<Path> {
if libc::getcwd(buf.as_mut_ptr(), buf.len() as libc::size_t).is_null() {
Err(IoError::last_error())
} else {
Ok(Path::new(ffi::c_str_to_bytes(&buf.as_ptr())))
Ok(Path::new(CStr::from_ptr(buf.as_ptr()).to_bytes()))
}
}
}
pub fn chdir(p: &Path) -> IoResult<()> {
let p = CString::from_slice(p.as_vec());
let p = CString::new(p.as_vec()).unwrap();
unsafe {
match libc::chdir(p.as_ptr()) == (0 as c_int) {
true => Ok(()),
@ -211,7 +211,7 @@ pub fn current_exe() -> IoResult<Path> {
if v.is_null() {
Err(IoError::last_error())
} else {
Ok(Path::new(ffi::c_str_to_bytes(&v).to_vec()))
Ok(Path::new(CStr::from_ptr(&v).to_bytes().to_vec()))
}
}
}
@ -266,7 +266,7 @@ pub fn args() -> Args {
let (argc, argv) = (*_NSGetArgc() as isize,
*_NSGetArgv() as *const *const c_char);
range(0, argc as isize).map(|i| {
let bytes = ffi::c_str_to_bytes(&*argv.offset(i)).to_vec();
let bytes = CStr::from_ptr(&*argv.offset(i)).to_bytes().to_vec();
OsStringExt::from_vec(bytes)
}).collect::<Vec<_>>()
};
@ -324,7 +324,7 @@ pub fn args() -> Args {
let tmp = objc_msgSend(args, object_at_sel, i);
let utf_c_str: *const libc::c_char =
mem::transmute(objc_msgSend(tmp, utf8_sel));
let bytes = ffi::c_str_to_bytes(&utf_c_str);
let bytes = CStr::from_ptr(utf_c_str).to_bytes();
res.push(OsString::from_str(str::from_utf8(bytes).unwrap()))
}
}
@ -380,7 +380,7 @@ pub fn env() -> Env {
}
let mut result = Vec::new();
while *environ != ptr::null() {
result.push(parse(ffi::c_str_to_bytes(&*environ)));
result.push(parse(CStr::from_ptr(*environ).to_bytes()));
environ = environ.offset(1);
}
Env { iter: result.into_iter(), _dont_send_or_sync_me: 0 as *mut _ }
@ -397,20 +397,20 @@ fn parse(input: &[u8]) -> (OsString, OsString) {
pub fn getenv(k: &OsStr) -> Option<OsString> {
unsafe {
let s = CString::from_slice(k.as_bytes());
let s = k.to_cstring().unwrap();
let s = libc::getenv(s.as_ptr()) as *const _;
if s.is_null() {
None
} else {
Some(OsStringExt::from_vec(ffi::c_str_to_bytes(&s).to_vec()))
Some(OsStringExt::from_vec(CStr::from_ptr(s).to_bytes().to_vec()))
}
}
}
pub fn setenv(k: &OsStr, v: &OsStr) {
unsafe {
let k = CString::from_slice(k.as_bytes());
let v = CString::from_slice(v.as_bytes());
let k = k.to_cstring().unwrap();
let v = v.to_cstring().unwrap();
if libc::funcs::posix01::unistd::setenv(k.as_ptr(), v.as_ptr(), 1) != 0 {
panic!("failed setenv: {}", IoError::last_error());
}
@ -419,7 +419,7 @@ pub fn setenv(k: &OsStr, v: &OsStr) {
pub fn unsetenv(n: &OsStr) {
unsafe {
let nbuf = CString::from_slice(n.as_bytes());
let nbuf = n.to_cstring().unwrap();
if libc::funcs::posix01::unistd::unsetenv(nbuf.as_ptr()) != 0 {
panic!("failed unsetenv: {}", IoError::last_error());
}
@ -480,7 +480,7 @@ unsafe fn fallback() -> Option<OsString> {
_ => return None
}
let ptr = passwd.pw_dir as *const _;
let bytes = ffi::c_str_to_bytes(&ptr).to_vec();
let bytes = CStr::from_ptr(ptr).to_bytes().to_vec();
return Some(OsStringExt::from_vec(bytes))
}
}

View File

@ -38,7 +38,7 @@ fn addr_to_sockaddr_un(addr: &CString,
mem::size_of::<libc::sockaddr_un>());
let s = unsafe { &mut *(storage as *mut _ as *mut libc::sockaddr_un) };
let len = addr.len();
let len = addr.as_bytes().len();
if len > s.sun_path.len() - 1 {
return Err(IoError {
kind: old_io::InvalidInput,
@ -47,8 +47,8 @@ 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;
for (slot, value) in s.sun_path.iter_mut().zip(addr.as_bytes().iter()) {
*slot = *value as libc::c_char;
}
// count the null terminator

View File

@ -46,7 +46,7 @@ pub struct Command {
impl Command {
pub fn new(program: &OsStr) -> Command {
Command {
program: program.to_cstring(),
program: program.to_cstring().unwrap(),
args: Vec::new(),
env: None,
cwd: None,
@ -57,10 +57,10 @@ pub fn new(program: &OsStr) -> Command {
}
pub fn arg(&mut self, arg: &OsStr) {
self.args.push(arg.to_cstring())
self.args.push(arg.to_cstring().unwrap())
}
pub fn args<'a, I: Iterator<Item = &'a OsStr>>(&mut self, args: I) {
self.args.extend(args.map(OsStrExt::to_cstring))
self.args.extend(args.map(|s| OsStrExt::to_cstring(s).unwrap()))
}
fn init_env_map(&mut self) {
if self.env.is_none() {
@ -79,7 +79,7 @@ pub fn env_clear(&mut self) {
self.env = Some(HashMap::new())
}
pub fn cwd(&mut self, dir: &OsStr) {
self.cwd = Some(dir.to_cstring())
self.cwd = Some(dir.to_cstring().unwrap())
}
}

View File

@ -237,7 +237,7 @@ pub unsafe fn create(stack: uint, p: Thunk) -> io::Result<rust_thread> {
pub unsafe fn set_name(name: &str) {
// pthread_setname_np() since glibc 2.12
// availability autodetected via weak linkage
let cname = CString::from_slice(name.as_bytes());
let cname = CString::new(name).unwrap();
type F = unsafe extern "C" fn(libc::pthread_t, *const libc::c_char) -> libc::c_int;
extern {
#[linkage = "extern_weak"]
@ -255,14 +255,14 @@ pub unsafe fn set_name(name: &str) {
target_os = "openbsd"))]
pub unsafe fn set_name(name: &str) {
// pthread_set_name_np() since almost forever on all BSDs
let cname = CString::from_slice(name.as_bytes());
let cname = CString::new(name).unwrap();
pthread_set_name_np(pthread_self(), cname.as_ptr());
}
#[cfg(any(target_os = "macos", target_os = "ios"))]
pub unsafe fn set_name(name: &str) {
// pthread_setname_np() since OS X 10.6 and iOS 3.2
let cname = CString::from_slice(name.as_bytes());
let cname = CString::new(name).unwrap();
pthread_setname_np(cname.as_ptr());
}

View File

@ -618,22 +618,25 @@ fn print_macro_backtrace(w: &mut EmitterWriter,
cm: &codemap::CodeMap,
sp: Span)
-> old_io::IoResult<()> {
let cs = try!(cm.with_expn_info(sp.expn_id, |expn_info| match expn_info {
Some(ei) => {
let ss = ei.callee.span.map_or(String::new(), |span| cm.span_to_string(span));
let (pre, post) = match ei.callee.format {
codemap::MacroAttribute => ("#[", "]"),
codemap::MacroBang => ("", "!")
};
try!(print_diagnostic(w, &ss[], Note,
&format!("in expansion of {}{}{}", pre,
ei.callee.name,
post)[], None));
let ss = cm.span_to_string(ei.call_site);
try!(print_diagnostic(w, &ss[], Note, "expansion site", None));
Ok(Some(ei.call_site))
}
None => Ok(None)
let cs = try!(cm.with_expn_info(sp.expn_id, |expn_info| -> old_io::IoResult<_> {
match expn_info {
Some(ei) => {
let ss = ei.callee.span.map_or(String::new(),
|span| cm.span_to_string(span));
let (pre, post) = match ei.callee.format {
codemap::MacroAttribute => ("#[", "]"),
codemap::MacroBang => ("", "!")
};
try!(print_diagnostic(w, &ss[], Note,
&format!("in expansion of {}{}{}", pre,
ei.callee.name,
post)[], None));
let ss = cm.span_to_string(ei.call_site);
try!(print_diagnostic(w, &ss[], Note, "expansion site", None));
Ok(Some(ei.call_site))
}
None => Ok(None)
}
}));
cs.map_or(Ok(()), |call_site| print_macro_backtrace(w, cm, call_site))
}

View File

@ -24,12 +24,12 @@ mod mlibc {
}
fn atol(s: String) -> int {
let c = CString::from_slice(s.as_bytes());
let c = CString::from_slice(s.as_bytes()).unwrap();
unsafe { mlibc::atol(c.as_ptr()) as int }
}
fn atoll(s: String) -> i64 {
let c = CString::from_slice(s.as_bytes());
let c = CString::from_slice(s.as_bytes()).unwrap();
unsafe { mlibc::atoll(c.as_ptr()) as i64 }
}

View File

@ -24,7 +24,7 @@ mod mlibc {
fn strlen(str: String) -> uint {
// C string is terminated with a zero
let s = CString::from_slice(str.as_bytes());
let s = CString::from_slice(str.as_bytes()).unwrap();
unsafe {
mlibc::my_strlen(s.as_ptr()) as uint
}

View File

@ -31,12 +31,12 @@ fn rename_directory() {
let test_file = &old_path.join("temp.txt");
/* Write the temp input file */
let fromp = CString::from_slice(test_file.as_vec());
let modebuf = CString::from_slice(b"w+b");
let fromp = CString::from_slice(test_file.as_vec()).unwrap();
let modebuf = CString::from_slice(b"w+b").unwrap();
let ostream = libc::fopen(fromp.as_ptr(), modebuf.as_ptr());
assert!((ostream as uint != 0u));
let s = "hello".to_string();
let buf = CString::from_slice(b"hello");
let buf = CString::from_slice(b"hello").unwrap();
let write_len = libc::fwrite(buf.as_ptr() as *mut _,
1u as libc::size_t,
(s.len() + 1u) as libc::size_t,

View File

@ -29,11 +29,11 @@ pub fn main() {
unsafe {
// Call with just the named parameter
let c = CString::from_slice(b"Hello World\n");
let c = CString::from_slice(b"Hello World\n").unwrap();
check("Hello World\n", |s| sprintf(s, c.as_ptr()));
// Call with variable number of arguments
let c = CString::from_slice(b"%d %f %c %s\n");
let c = CString::from_slice(b"%d %f %c %s\n").unwrap();
check("42 42.500000 a %d %f %c %s\n\n", |s| {
sprintf(s, c.as_ptr(), 42, 42.5f64, 'a' as c_int, c.as_ptr());
});
@ -44,11 +44,11 @@ pub fn main() {
// A function that takes a function pointer
unsafe fn call(p: unsafe extern fn(*mut c_char, *const c_char, ...) -> c_int) {
// Call with just the named parameter
let c = CString::from_slice(b"Hello World\n");
let c = CString::from_slice(b"Hello World\n").unwrap();
check("Hello World\n", |s| sprintf(s, c.as_ptr()));
// Call with variable number of arguments
let c = CString::from_slice(b"%d %f %c %s\n");
let c = CString::from_slice(b"%d %f %c %s\n").unwrap();
check("42 42.500000 a %d %f %c %s\n\n", |s| {
sprintf(s, c.as_ptr(), 42, 42.5f64, 'a' as c_int, c.as_ptr());
});