From bb2c63bfafc19cd468b7fb9ebbdb3dd4e411d2b4 Mon Sep 17 00:00:00 2001 From: emma Date: Thu, 11 Apr 2024 20:33:42 -0600 Subject: [PATCH] getopt.rs(3): fixed pointer shenanigans --- src/getopt.rs | 43 ++++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/src/getopt.rs b/src/getopt.rs index b95108c..81c146d 100644 --- a/src/getopt.rs +++ b/src/getopt.rs @@ -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, @@ -35,20 +35,22 @@ pub trait GetOpt { } impl GetOpt for Vec { - fn getopt(&self, optstring: &str) -> Option> { - let argv = self + fn getopt(&self, optstring: &str) -> Option> { + let c_strings: Vec<_> = self .iter() .cloned() .map(CString::new) .map(Result::unwrap) - .map(|x| x.as_ptr() as c_char) - .collect::>() - .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 { * * 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 { * 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;