How can I create and pass a null-terminated array of C-strings (char**) in rust?
Asked Answered
S

1

10

I'm playing around with a new init system with #![no_std] and extern crate rlibc and making syscalls with asm, and currently trying to not allocate memory either. So the scope of possible tools I have is limited.

I need to call the execve syscall, and it requires a char** argv, and a char **envp. I can hack together c-style strings as arrays of bytes with zeros, but how can I null-terminate a statically declared list of such (the last pointer being NULL)?

Secret answered 26/7, 2014 at 8:27 Comment(0)
S
7

After sleeping on this, I woke up with the answer, and it seems obvious to me now. Use slices of integers and set the last one to 0.

// Execute something as an example:
let filename: &[u8] = b"/usr/bin/sensors\x00";     // <-- Make c strings like this
let argv1: &[u8] = b"/usr/bin/sensors\x00";
let argv2: &[u8] = b"-h\x00";
let argv: &[int] = [                               // <-- store them in this
    ::core::intrinsics::transmute(argv1.as_ptr()), // <-- transmuting 
    ::core::intrinsics::transmute(argv2.as_ptr()),
    0                                              // <-- and NULL terminate
];
let envp: &[int] = [0];

::linux64::execve(filename,argv,envp);
Secret answered 26/7, 2014 at 19:4 Comment(5)
You should use *const u8 instead of int. The as_ptr() method already returns a *const u8, so you can just remove the transmute. To get a null pointer, use ptr::null() (or 0 as *const T) instead of 0.Civvies
Also, you can use \0 instead of \x00 in bytestrings to represent a null byte.Civvies
You can cast raw pointers to and from integers freely (argv1.as_ptr() as int), but as @FrancisGagné, suggests, it would be better to store a &[*const u8]. Also, do you know about use, while allows to to bring names into scope, e.g. use core::mem; ... mem::transmute(...)?Apt
@FrancisGagné: Thanks for that I was hoping someone would comment on the typesSecret
@dbaupp I didn't know the cast was so easy. Yes I know about use, I prefer to see the full paths for the moment.Secret

© 2022 - 2024 — McMap. All rights reserved.