Skip to content

Commit

Permalink
Change UtunIfname sockopt type to CString (nix-rust#2329)
Browse files Browse the repository at this point in the history
* Implement GetCString for use with sockopt

* Change UtunIfname sockopt type to CString
  • Loading branch information
friedrich authored Mar 9, 2024
1 parent bb9ffeb commit ce0f5b1
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 4 deletions.
35 changes: 32 additions & 3 deletions src/sys/socket/sockopt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::sys::time::TimeVal;
use crate::Result;
use cfg_if::cfg_if;
use libc::{self, c_int, c_void, socklen_t};
use std::ffi::{OsStr, OsString};
use std::ffi::{CStr, CString, OsStr, OsString};
use std::mem::{self, MaybeUninit};
use std::os::unix::ffi::OsStrExt;
use std::os::unix::io::{AsFd, AsRawFd};
Expand Down Expand Up @@ -1073,8 +1073,8 @@ sockopt_impl!(
GetOnly,
libc::SYSPROTO_CONTROL,
libc::UTUN_OPT_IFNAME,
OsString,
GetOsString<[u8; libc::IFNAMSIZ]>
CString,
GetCString<[u8; libc::IFNAMSIZ]>
);

#[allow(missing_docs)]
Expand Down Expand Up @@ -1579,3 +1579,32 @@ impl<'a> Set<'a, OsString> for SetOsString<'a> {
}
}

/// Getter for a `CString` value.
struct GetCString<T: AsMut<[u8]>> {
len: socklen_t,
val: MaybeUninit<T>,
}

impl<T: AsMut<[u8]>> Get<CString> for GetCString<T> {
fn uninit() -> Self {
GetCString {
len: mem::size_of::<T>() as socklen_t,
val: MaybeUninit::uninit(),
}
}

fn ffi_ptr(&mut self) -> *mut c_void {
self.val.as_mut_ptr().cast()
}

fn ffi_len(&mut self) -> *mut socklen_t {
&mut self.len
}

unsafe fn assume_init(self) -> CString {
let mut v = unsafe { self.val.assume_init() };
CStr::from_bytes_until_nul(v.as_mut())
.expect("string should be null-terminated")
.to_owned()
}
}
2 changes: 1 addition & 1 deletion test/sys/test_sockopt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -856,6 +856,6 @@ fn test_utun_ifname() {
let name = getsockopt(&fd, sockopt::UtunIfname)
.expect("getting UTUN_OPT_IFNAME on a utun interface should succeed");

let expected_name = format!("utun{}\0", unit - 1);
let expected_name = format!("utun{}", unit - 1);
assert_eq!(name.into_string(), Ok(expected_name));
}

0 comments on commit ce0f5b1

Please sign in to comment.