mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-20 04:24:41 +00:00
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:
parent
dfc5c0f1e8
commit
1860ee521a
@ -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);
|
||||
|
@ -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: '{}'",
|
||||
|
@ -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 @@ impl 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() {
|
||||
|
@ -2149,7 +2149,7 @@ impl Drop for TargetData {
|
||||
}
|
||||
|
||||
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()) }
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -22,7 +22,7 @@ use syntax::codemap;
|
||||
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 @@ unsafe extern "C" fn diagnostic_handler(info: DiagnosticInfoRef, user: *mut c_vo
|
||||
}
|
||||
|
||||
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 optimize_and_codegen(cgcx: &CodegenContext,
|
||||
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 optimize_and_codegen(cgcx: &CodegenContext,
|
||||
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);
|
||||
};
|
||||
|
@ -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(),
|
||||
|
@ -86,7 +86,7 @@ use util::nodemap::NodeMap;
|
||||
|
||||
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 @@ impl<'a, 'tcx> Drop for StatRecorder<'a, 'tcx> {
|
||||
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 {
|
||||
§)[]);
|
||||
}
|
||||
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);
|
||||
|
@ -431,7 +431,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
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 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
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,
|
||||
|
@ -488,7 +488,7 @@ impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
|
||||
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);
|
||||
|
@ -225,15 +225,15 @@ impl<'a, 'tcx> Iterator for CrateContextMaybeIterator<'a, 'tcx> {
|
||||
|
||||
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)
|
||||
}
|
||||
|
@ -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 @@ pub fn create_function_debug_context<'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 @@ pub fn create_function_debug_context<'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 {
|
||||
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
@ -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())
|
||||
|
@ -163,7 +163,7 @@ impl 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()))
|
||||
}
|
||||
|
||||
|
@ -112,7 +112,7 @@ mod imp {
|
||||
|
||||
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)
|
||||
|
@ -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()) }
|
||||
}
|
||||
|
||||
|
@ -112,7 +112,7 @@ impl DynamicLibrary {
|
||||
// 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 @@ mod test {
|
||||
mod dl {
|
||||
use prelude::v1::*;
|
||||
|
||||
use ffi::{self, CString};
|
||||
use ffi::{CString, CStr};
|
||||
use str;
|
||||
use libc;
|
||||
use ptr;
|
||||
@ -206,7 +206,7 @@ mod dl {
|
||||
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 @@ mod dl {
|
||||
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())
|
||||
};
|
||||
|
||||
|
@ -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 @@ use vec::Vec;
|
||||
/// 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 @@ use vec::Vec;
|
||||
/// ```
|
||||
#[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 @@ impl 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 @@ impl 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 @@ impl fmt::Debug for CString {
|
||||
}
|
||||
}
|
||||
|
||||
/// 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 @@ mod tests {
|
||||
|
||||
#[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 @@ mod tests {
|
||||
|
||||
#[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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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 @@ impl UnixStream {
|
||||
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 })
|
||||
}
|
||||
|
@ -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 @@ impl 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 @@ impl Command {
|
||||
// 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 @@ impl Command {
|
||||
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 @@ impl Command {
|
||||
/// 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 @@ impl Command {
|
||||
-> &'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 @@ mod tests {
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ mod imp {
|
||||
|
||||
use libc;
|
||||
use mem;
|
||||
use ffi;
|
||||
use ffi::CStr;
|
||||
|
||||
use sync::{StaticMutex, MUTEX_INIT};
|
||||
|
||||
@ -96,10 +96,11 @@ mod imp {
|
||||
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()
|
||||
}
|
||||
|
||||
|
@ -12,8 +12,7 @@ use prelude::v1::*;
|
||||
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())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -121,7 +121,7 @@ impl Drop for LookupHost {
|
||||
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 _,
|
||||
|
@ -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 print(w: &mut Writer, idx: int, addr: *mut libc::c_void) -> IoResult<()> {
|
||||
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 @@ 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 { ffi::c_str_to_bytes(&data) }))
|
||||
output(w, idx, addr, Some(unsafe { CStr::from_ptr(data).to_bytes() }))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 @@ impl OsStrExt for OsStr {
|
||||
&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 @@ impl ExitStatusExt for process::ExitStatus {
|
||||
/// 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};
|
||||
}
|
||||
|
@ -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 @@ impl Drop for FileDesc {
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ 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 = 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 @@ pub fn readdir(p: &Path) -> IoResult<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 @@ pub fn readdir(p: &Path) -> IoResult<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 mkstat(stat: &libc::stat) -> FileStat {
|
||||
}
|
||||
|
||||
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,
|
||||
|
@ -12,7 +12,7 @@ use core::prelude::*;
|
||||
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 @@ impl DirEntry {
|
||||
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 @@ impl 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 @@ impl File {
|
||||
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(())
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -14,7 +14,7 @@ use prelude::v1::*;
|
||||
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 @@ pub fn error_string(errno: i32) -> String {
|
||||
}
|
||||
|
||||
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 @@ pub fn env() -> Env {
|
||||
|
||||
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 @@ pub fn home_dir() -> Option<Path> {
|
||||
_ => 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))
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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 @@ impl 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 @@ impl Command {
|
||||
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())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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 }
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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());
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user