getopt.rs(3): fixed pointer shenanigans

This commit is contained in:
Emma Tebibyte 2024-04-11 20:33:42 -06:00
parent 88b0d55440
commit bb2c63bfaf
Signed by untrusted user: emma
GPG Key ID: 06FA419A1698C270

View File

@ -16,7 +16,7 @@
* along with this program. If not, see https://www.gnu.org/licenses/.
*/
use std::ffi::{ c_int, c_char, CString };
use std::ffi::{ c_int, c_char, CString, CStr };
pub struct Opt {
pub arg: Option<String>,
@ -35,20 +35,22 @@ pub trait GetOpt {
}
impl GetOpt for Vec<String> {
fn getopt(&self, optstring: &str) -> Option<Result<Opt, OptError>> {
let argv = self
fn getopt(&self, optstring: &str) -> Option<Result<Opt, OptError>> {
let c_strings: Vec<_> = self
.iter()
.cloned()
.map(CString::new)
.map(Result::unwrap)
.map(|x| x.as_ptr() as c_char)
.collect::<Vec<c_char>>()
.as_ptr() as *const *mut c_char;
let opts = CString::new(optstring).unwrap().into_raw();
let len = self.len() as c_int;
.collect();
unsafe {
let a = match getopt(len, argv, opts) {
let argv: Vec<_> = c_strings.iter().map(|x| x.as_ptr()).collect();
let argv_ptr = argv.as_ptr() as *const *mut c_char;
let optstring_c = CString::new(optstring).unwrap();
let opts = optstring_c.into_raw();
let len = self.len() as c_int;
unsafe {
let a = match getopt(len, argv_ptr, opts) {
/* From getopt(3p):
*
* The getopt() function shall return the next option character
@ -65,11 +67,11 @@ impl GetOpt for Vec<String> {
*
* Otherwise, getopt() shall return -1 when all command line
* options are parsed. */
58 => { // ASCII value for ':'
58 => { /* ASCII value for ':' */
return Some(Err(OptError::MissingArg));
},
63 => { // ASCII value for '?'
return Some(Err(OptError::UnknownOpt));
63 => { /* ASCII value for '?' */
return Some(Err(OptError::UnknownOpt))
},
/* From getopt(3p):
*
@ -84,18 +86,17 @@ impl GetOpt for Vec<String> {
* argv[optind] points to the string "--"
*
* getopt() shall return -1 after incrementing optind. */
-1 => return None,
a => a.to_string(),
};
-1 => return None,
_ => CStr::from_ptr(optarg).to_string_lossy().into_owned(),
};
Some(Ok(Opt { arg: Some(a), ind: optind, opt: optopt }))
}
}
Some(Ok(Opt { arg: Some(a), ind: optind, opt: optopt }))
}
}
}
/* binding to getopt(3p) */
extern "C" {
static mut _optarg: *mut c_char;
static mut optarg: *mut c_char;
static mut _opterr: c_int;
static mut optind: c_int;
static mut optopt: c_int;