@@ -200,6 +200,38 @@ impl CString {
200200 CString { inner : v }
201201 }
202202
203+ /// Retakes ownership of a CString that was transferred to C.
204+ ///
205+ /// The only appropriate argument is a pointer obtained by calling
206+ /// `into_raw`.
207+ #[ unstable( feature = "c_str_memory" , reason = "recently added" ) ]
208+ pub unsafe fn from_raw ( ptr : * const libc:: c_char ) -> CString {
209+ let len = libc:: strlen ( ptr) ;
210+ let len_with_nul = len as usize + 1 ;
211+ let vec = Vec :: from_raw_parts ( ptr as * mut u8 , len_with_nul, len_with_nul) ;
212+ CString :: from_vec_unchecked ( vec)
213+ }
214+
215+ /// Transfers ownership of the string to a C caller.
216+ ///
217+ /// The pointer must be returned to Rust and reconstituted using
218+ /// `from_raw` to be properly deallocated. Specifically, one
219+ /// should *not* use the standard C `free` function to deallocate
220+ /// this string.
221+ ///
222+ /// Failure to call `from_raw` will lead to a memory leak.
223+ #[ unstable( feature = "c_str_memory" , reason = "recently added" ) ]
224+ pub fn into_raw ( self ) -> * const libc:: c_char {
225+ // Resize the vector to fit - we need the capacity to be
226+ // determinable from the string length, and shrinking to fit
227+ // is the only way to be sure.
228+ let mut vec = self . inner ;
229+ vec. shrink_to_fit ( ) ;
230+ let ptr = vec. as_ptr ( ) as * const libc:: c_char ;
231+ mem:: forget ( vec) ;
232+ ptr
233+ }
234+
203235 /// Returns the contents of this `CString` as a slice of bytes.
204236 ///
205237 /// The returned slice does **not** contain the trailing nul separator and
0 commit comments