Auto merge of #25777 - shepmaster:cstring-return-to-c, r=alexcrichton
Auto merge of #25777 - shepmaster:cstring-return-to-c, r=alexcrichton

As far as I was able to determine, it's currently *impossible* to allocate a C NUL-terminated string in Rust and then return it to C (transferring ownership), without leaking memory. There is support for passing the string to C (borrowing).

To complicate matters, it's not possible for the C code to just call `free` on the allocated string, due to the different allocators in use.

`CString` has no way to recreate itself from a pointer. This commit adds one. This is complicated a bit because Rust `Vec`s want the pointer, size, and capacity.

To deal with that, another method to shrink and "leak" the `CString` to a `char *` is also provided. 

We can then use `strlen` to determine the length of the string, which must match the capacity. 

**TODO**

- [x] Improve documentation
- [x] Add stability markers
- [x] Convert to `Box<[u8]>`

### Example code

With this example code:

```rust
#![feature(libc)]
#![feature(cstr_to_str)]
#![feature(c_str_memory)]

extern crate libc;

use std::ffi::{CStr,CString};

#[no_mangle]
pub extern fn reverse(s: *const libc::c_char) -> *const libc::c_char {
    let s = unsafe { CStr::from_ptr(s) };
    let s2 = s.to_str().unwrap();
    let s3: String = s2.chars().rev().collect();
    let s4 = CString::new(s3).unwrap();
    s4.into_ptr()
}

#[no_mangle]
pub extern fn cleanup(s: *const libc::c_char) {
    unsafe { CString::from_ptr(s) };
}
```

Compiled using `rustc --crate-type dylib str.rs`, I was able to link against it from C (`gcc -L. -l str str.c -o str`):
 
```c
#include <stdio.h>

extern char *reverse(char *);
extern void cleanup(char *);

int main() {
  char *s = reverse("Hello, world!");
  printf("%s\n", s);
  cleanup(s);
}
```

As well as dynamically link via Ruby:

```ruby
require 'fiddle'
require 'fiddle/import'

module LibSum
  extend Fiddle::Importer

  dlload './libstr.dylib'
  extern 'char* reverse(char *)'
  extern 'void cleanup(char *)'
end

s = LibSum.reverse("hello, world!")
puts s
LibSum.cleanup(s)
```

jashank/rust,reem/rust,pelmers/rust,omasanori/rust,nwin/rust,graydon/rust,jashank/rust,mihneadb/rust,mvdnes/rust,aidancully/rust,pshc/rust,pshc/rust,mihneadb/rust,graydon/rust,omasanori/rust,aidancully/rust,reem/rust,mvdnes/rust,pshc/rust,zubron/rust,nwin/rust,jroesch/rust,jashank/rust,jroesch/rust,l0kod/rust,omasanori/rust,KokaKiwi/rust,KokaKiwi/rust,dwillmer/rust,robertg/rust,l0kod/rust,omasanori/rust,zubron/rust,dwillmer/rust,pshc/rust,pelmers/rust,aidancully/rust,pshc/rust,GBGamer/rust,nwin/rust,vhbit/rust,zubron/rust,GBGamer/rust,dwillmer/rust,jashank/rust,dwillmer/rust,GBGamer/rust,reem/rust,zachwick/rust,pshc/rust,nwin/rust,zubron/rust,dwillmer/rust,dwillmer/rust,vhbit/rust,mihneadb/rust,mvdnes/rust,jroesch/rust,vhbit/rust,KokaKiwi/rust,robertg/rust,jashank/rust,l0kod/rust,omasanori/rust,pelmers/rust,zubron/rust,pshc/rust,pelmers/rust,l0kod/rust,vhbit/rust,mihneadb/rust,graydon/rust,vhbit/rust,nwin/rust,GBGamer/rust,dwillmer/rust,robertg/rust,dwillmer/rust,KokaKiwi/rust,mvdnes/rust,jroesch/rust,zachwick/rust,nwin/rust,aidancully/rust,mihneadb/rust,reem/rust,jroesch/rust,mvdnes/rust,l0kod/rust,zubron/rust,jashank/rust,nwin/rust,pelmers/rust,zubron/rust,zachwick/rust,pelmers/rust,jashank/rust,robertg/rust,vhbit/rust,zachwick/rust,reem/rust,mihneadb/rust,graydon/rust,graydon/rust,reem/rust,l0kod/rust,jashank/rust,nwin/rust,GBGamer/rust,GBGamer/rust,KokaKiwi/rust,KokaKiwi/rust,graydon/rust,vhbit/rust,jroesch/rust,jroesch/rust,jroesch/rust,vhbit/rust,robertg/rust,zachwick/rust,l0kod/rust,pshc/rust,GBGamer/rust,mvdnes/rust,zubron/rust,l0kod/rust,aidancully/rust,omasanori/rust,aidancully/rust,zachwick/rust,robertg/rust,GBGamer/rust