Skip to content

Commit bf2a772

Browse files
authored
Factor out a SocketAddrArg::write_sockaddr function. (#1334)
This is needed by c-scape in order to encode socket addresses into libc-compatible form. And a few other minor cleanups.
1 parent 76c657f commit bf2a772

File tree

6 files changed

+46
-16
lines changed

6 files changed

+46
-16
lines changed

src/net/addr.rs

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -68,19 +68,34 @@ pub unsafe trait SocketAddrArg {
6868

6969
/// Convert to `SocketAddrAny`.
7070
fn as_any(&self) -> SocketAddrAny {
71-
// SAFETY: The closure dereferences exactly `len` bytes at `ptr`.
71+
let mut storage = MaybeUninit::<SocketAddrStorage>::uninit();
72+
// SAFETY: We've allocated `storage` here, we're writing to it, and
73+
// we're using the number of bytes written.
7274
unsafe {
73-
self.with_sockaddr(|ptr, len| {
74-
let mut storage = MaybeUninit::<SocketAddrStorage>::uninit();
75-
ptr::copy_nonoverlapping(
76-
ptr.cast::<u8>(),
77-
storage.as_mut_ptr().cast::<u8>(),
78-
len as usize,
79-
);
80-
SocketAddrAny::new(storage, len)
81-
})
75+
let len = self.write_sockaddr(storage.as_mut_ptr());
76+
SocketAddrAny::new(storage, len)
8277
}
8378
}
79+
80+
/// Encode an address into a `SocketAddrStorage`.
81+
///
82+
/// Returns the number of bytes that were written.
83+
///
84+
/// For a safe interface to this functionality, use [`as_any`].
85+
///
86+
/// [`as_any`]: Self::as_any
87+
///
88+
/// # Safety
89+
///
90+
/// `storage` must be valid to write up to `size_of<SocketAddrStorage>()`
91+
/// bytes to.
92+
unsafe fn write_sockaddr(&self, storage: *mut SocketAddrStorage) -> SocketAddrLen {
93+
// The closure dereferences exactly `len` bytes at `ptr`.
94+
self.with_sockaddr(|ptr, len| {
95+
ptr::copy_nonoverlapping(ptr.cast::<u8>(), storage.cast::<u8>(), len as usize);
96+
len
97+
})
98+
}
8499
}
85100

86101
/// Helper for implementing SocketAddrArg::with_sockaddr

src/net/socket_addr_any.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ use core::num::NonZeroU32;
1616

1717
/// Temporary buffer for creating a `SocketAddrAny` from a
1818
/// syscall that writes to a `sockaddr_t` and `socklen_t`
19+
///
20+
/// Unlike `SocketAddrAny`, this does not maintain the invariant that `len`
21+
/// bytes are initialized.
1922
pub(crate) struct SocketAddrBuf {
2023
pub(crate) len: c::socklen_t,
2124
pub(crate) storage: MaybeUninit<SocketAddrStorage>,
@@ -38,7 +41,7 @@ impl SocketAddrBuf {
3841
/// and its length written into `self.len`.
3942
#[inline]
4043
pub(crate) unsafe fn into_any(self) -> SocketAddrAny {
41-
SocketAddrAny::new(self.storage, self.len.try_into().unwrap())
44+
SocketAddrAny::new(self.storage, bitcast!(self.len))
4245
}
4346

4447
/// Convert the buffer into [`Option<SocketAddrAny>`].
@@ -53,7 +56,7 @@ impl SocketAddrBuf {
5356
/// have been set to 0.
5457
#[inline]
5558
pub(crate) unsafe fn into_any_option(self) -> Option<SocketAddrAny> {
56-
let len = self.len.try_into().unwrap();
59+
let len = bitcast!(self.len);
5760
if read_sockaddr::sockaddr_nonempty(self.storage.as_ptr().cast(), len) {
5861
Some(SocketAddrAny::new(self.storage, len))
5962
} else {

src/process/types.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
//! Types for use with [`rustix::process`] functions.
2+
//!
3+
//! [`rustix::process`]: crate::process
24
35
#![allow(unsafe_code)]
46

tests/net/unix.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,6 @@ fn test_abstract_unix_msg_unconnected() {
418418
do_test_unix_msg_unconnected(name);
419419
}
420420

421-
#[cfg(feature = "pipe")]
422421
#[cfg(not(any(target_os = "redox", target_os = "wasi")))]
423422
#[cfg(feature = "pipe")]
424423
#[test]
@@ -715,7 +714,6 @@ fn test_unix_peercred_implicit() {
715714

716715
/// Like `test_unix_msg_with_scm_rights`, but with multiple file descriptors
717716
/// over multiple control messages.
718-
#[cfg(feature = "pipe")]
719717
#[cfg(not(any(target_os = "redox", target_os = "wasi")))]
720718
#[cfg(feature = "pipe")]
721719
#[test]

tests/net/unix_alloc.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,6 @@ fn test_abstract_unix_msg_unconnected() {
416416
do_test_unix_msg_unconnected(name);
417417
}
418418

419-
#[cfg(feature = "pipe")]
420419
#[cfg(not(any(target_os = "redox", target_os = "wasi")))]
421420
#[cfg(feature = "pipe")]
422421
#[test]
@@ -656,7 +655,6 @@ fn test_unix_peercred() {
656655

657656
/// Like `test_unix_msg_with_scm_rights`, but with multiple file descriptors
658657
/// over multiple control messages.
659-
#[cfg(feature = "pipe")]
660658
#[cfg(not(any(target_os = "redox", target_os = "wasi")))]
661659
#[cfg(feature = "pipe")]
662660
#[test]

tests/termios/termios.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,20 @@ fn test_termios_modes() {
120120
assert!(new_tio.output_modes.contains(OutputModes::ONOCR));
121121
assert!(new_tio.input_modes.contains(InputModes::IGNBRK));
122122
assert!(new_tio.control_modes.contains(ControlModes::CLOCAL));
123+
124+
tio.local_modes.remove(LocalModes::TOSTOP);
125+
tio.output_modes.remove(OutputModes::ONOCR);
126+
tio.input_modes.remove(InputModes::IGNBRK);
127+
tio.control_modes.remove(ControlModes::CLOCAL);
128+
129+
tcsetattr(&pty, OptionalActions::Now, &tio).unwrap();
130+
131+
let new_tio = tcgetattr(&pty).unwrap();
132+
133+
assert!(!new_tio.local_modes.contains(LocalModes::TOSTOP));
134+
assert!(!new_tio.output_modes.contains(OutputModes::ONOCR));
135+
assert!(!new_tio.input_modes.contains(InputModes::IGNBRK));
136+
assert!(!new_tio.control_modes.contains(ControlModes::CLOCAL));
123137
}
124138

125139
// Disable on illumos where `tcgetattr` doesn't appear to support

0 commit comments

Comments
 (0)