Skip to content

New c_str/ffi makes error buffer operations harder than necessary #20928

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
viraptor opened this issue Jan 11, 2015 · 6 comments
Closed

New c_str/ffi makes error buffer operations harder than necessary #20928

viraptor opened this issue Jan 11, 2015 · 6 comments
Labels
A-FFI Area: Foreign function interface (FFI)

Comments

@viraptor
Copy link

After the c_str/ffi interface changed in #20444 operations which return strings into preallocated buffer are harder to handle.

Specifically calls like prctl can take form prctl(int, char[16]). This could be handled by:

let mut name = [0 as u8; 17];
let res = prctl(PrctlOption::PR_GET_NAME as c_int, name.as_mut_ptr() as c_ulong, 0, 0, 0);
(res, CString::from_slice(name.as_slice()))

But the name is likely to contain zeros and there's no simple "construct CString until the first zero" function. This shouldn't be a big issue in case of a simple CString type, but since this one is meant specifically for FFI, I think such constructor should be supported.

(rustc 1.0.0-nightly (44a287e 2015-01-08 17:03:40 -0800))

@kmcallister kmcallister added A-libs A-FFI Area: Foreign function interface (FFI) labels Jan 11, 2015
@shepmaster
Copy link
Member

Related to #20475?

@viraptor
Copy link
Author

I think it's close. The same function could probably satisfy both issues.
The operation could construct the cstring from a slice/vec up to the first
zero, or until max_length - whichever happens first.
On 12 Jan 2015 11:38 am, "Jake Goulding" [email protected] wrote:

Related to #20475 #20475?


Reply to this email directly or view it on GitHub
#20928 (comment).

@alexcrichton
Copy link
Member

It sounds like you don't necessarily want to return a CString but rather a Vec<u8>. are you later passing the string back into other C functions? I'd be thinking of something like:

let mut name = [0 as u8; 17];
let res = prctl(PrctlOption::PR_GET_NAME as c_int, name.as_mut_ptr() as c_ulong, 0, 0, 0);
(res, ffi::c_str_to_bytes(name.as_ptr()).to_vec())

@viraptor
Copy link
Author

I think it's better for the interface if I return a cstring, since that's
exactly what I get back. Vec would suggest some binary data. I can't make
it a proper string since the caller will know the encoding.
I think the interface would need more comments about the nulls, length,
etc. in my library, instead of just providing cstring.
Am I mistaken here?
On 13 Jan 2015 5:59 am, "Alex Crichton" [email protected] wrote:

It sounds like you don't necessarily want to return a CString but rather
a Vec. are you later passing the string back into other C functions?
I'd be thinking of something like:

let mut name = [0 as u8; 17];let res = prctl(PrctlOption::PR_GET_NAME as c_int, name.as_mut_ptr() as c_ulong, 0, 0, 0);
(res, ffi::c_str_to_bytes(name.as_ptr()).to_vec())


Reply to this email directly or view it on GitHub
#20928 (comment).

@alexcrichton
Copy link
Member

Vec would suggest some binary data.

To rust, however, C strings are just binary data. The CString type is basically just a type that derefs to [u8]. The only added benefit of CString over Vec<u8> is a static guarantee that there are no interior nul bytes (which might be useful if you're handing the data right back to C).

@alexcrichton
Copy link
Member

Looking back at this, I'm going to close this as a dupe of #20475 as a from_slice_truncate method looks to be what'd fit the ticket here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-FFI Area: Foreign function interface (FFI)
Projects
None yet
Development

No branches or pull requests

4 participants