mirror of https://github.com/rust-lang/rust.git
Avoid mem::uninitialized() in std::sys::unix
For `libc` types that will be initialized in FFI calls, we can just use `MaybeUninit` and then pass around raw pointers. For `sun_path_offset()`, which really wants `offset_of`, all callers have a real `sockaddr_un` available, so we can use that reference.
This commit is contained in:
parent
d3e2cec292
commit
3ba1f39fe7
|
@ -40,15 +40,15 @@ impl Condvar {
|
|||
target_os = "android",
|
||||
target_os = "hermit")))]
|
||||
pub unsafe fn init(&mut self) {
|
||||
use crate::mem;
|
||||
let mut attr: libc::pthread_condattr_t = mem::uninitialized();
|
||||
let r = libc::pthread_condattr_init(&mut attr);
|
||||
use crate::mem::MaybeUninit;
|
||||
let mut attr = MaybeUninit::<libc::pthread_condattr_t>::uninit();
|
||||
let r = libc::pthread_condattr_init(attr.as_mut_ptr());
|
||||
assert_eq!(r, 0);
|
||||
let r = libc::pthread_condattr_setclock(&mut attr, libc::CLOCK_MONOTONIC);
|
||||
let r = libc::pthread_condattr_setclock(attr.as_mut_ptr(), libc::CLOCK_MONOTONIC);
|
||||
assert_eq!(r, 0);
|
||||
let r = libc::pthread_cond_init(self.inner.get(), &attr);
|
||||
let r = libc::pthread_cond_init(self.inner.get(), attr.as_ptr());
|
||||
assert_eq!(r, 0);
|
||||
let r = libc::pthread_condattr_destroy(&mut attr);
|
||||
let r = libc::pthread_condattr_destroy(attr.as_mut_ptr());
|
||||
assert_eq!(r, 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -40,10 +40,9 @@ use libc::MSG_NOSIGNAL;
|
|||
target_os = "haiku")))]
|
||||
const MSG_NOSIGNAL: libc::c_int = 0x0;
|
||||
|
||||
fn sun_path_offset() -> usize {
|
||||
fn sun_path_offset(addr: &libc::sockaddr_un) -> usize {
|
||||
// Work with an actual instance of the type since using a null pointer is UB
|
||||
let addr: libc::sockaddr_un = unsafe { mem::uninitialized() };
|
||||
let base = &addr as *const _ as usize;
|
||||
let base = addr as *const _ as usize;
|
||||
let path = &addr.sun_path as *const _ as usize;
|
||||
path - base
|
||||
}
|
||||
|
@ -69,7 +68,7 @@ unsafe fn sockaddr_un(path: &Path) -> io::Result<(libc::sockaddr_un, libc::sockl
|
|||
// null byte for pathname addresses is already there because we zeroed the
|
||||
// struct
|
||||
|
||||
let mut len = sun_path_offset() + bytes.len();
|
||||
let mut len = sun_path_offset(&addr) + bytes.len();
|
||||
match bytes.get(0) {
|
||||
Some(&0) | None => {}
|
||||
Some(_) => len += 1,
|
||||
|
@ -122,7 +121,7 @@ impl SocketAddr {
|
|||
if len == 0 {
|
||||
// When there is a datagram from unnamed unix socket
|
||||
// linux returns zero bytes of address
|
||||
len = sun_path_offset() as libc::socklen_t; // i.e., zero-length address
|
||||
len = sun_path_offset(&addr) as libc::socklen_t; // i.e., zero-length address
|
||||
} else if addr.sun_family != libc::AF_UNIX as libc::sa_family_t {
|
||||
return Err(io::Error::new(io::ErrorKind::InvalidInput,
|
||||
"file descriptor did not correspond to a Unix socket"));
|
||||
|
@ -200,7 +199,7 @@ impl SocketAddr {
|
|||
}
|
||||
|
||||
fn address<'a>(&'a self) -> AddressKind<'a> {
|
||||
let len = self.len as usize - sun_path_offset();
|
||||
let len = self.len as usize - sun_path_offset(&self.addr);
|
||||
let path = unsafe { mem::transmute::<&[libc::c_char], &[u8]>(&self.addr.sun_path) };
|
||||
|
||||
// macOS seems to return a len of 16 and a zeroed sun_path for unnamed addresses
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::cell::UnsafeCell;
|
||||
use crate::mem;
|
||||
use crate::mem::MaybeUninit;
|
||||
|
||||
pub struct Mutex { inner: UnsafeCell<libc::pthread_mutex_t> }
|
||||
|
||||
|
@ -40,14 +40,14 @@ impl Mutex {
|
|||
// references, we instead create the mutex with type
|
||||
// PTHREAD_MUTEX_NORMAL which is guaranteed to deadlock if we try to
|
||||
// re-lock it from the same thread, thus avoiding undefined behavior.
|
||||
let mut attr: libc::pthread_mutexattr_t = mem::uninitialized();
|
||||
let r = libc::pthread_mutexattr_init(&mut attr);
|
||||
let mut attr = MaybeUninit::<libc::pthread_mutexattr_t>::uninit();
|
||||
let r = libc::pthread_mutexattr_init(attr.as_mut_ptr());
|
||||
debug_assert_eq!(r, 0);
|
||||
let r = libc::pthread_mutexattr_settype(&mut attr, libc::PTHREAD_MUTEX_NORMAL);
|
||||
let r = libc::pthread_mutexattr_settype(attr.as_mut_ptr(), libc::PTHREAD_MUTEX_NORMAL);
|
||||
debug_assert_eq!(r, 0);
|
||||
let r = libc::pthread_mutex_init(self.inner.get(), &attr);
|
||||
let r = libc::pthread_mutex_init(self.inner.get(), attr.as_ptr());
|
||||
debug_assert_eq!(r, 0);
|
||||
let r = libc::pthread_mutexattr_destroy(&mut attr);
|
||||
let r = libc::pthread_mutexattr_destroy(attr.as_mut_ptr());
|
||||
debug_assert_eq!(r, 0);
|
||||
}
|
||||
#[inline]
|
||||
|
@ -89,19 +89,19 @@ unsafe impl Sync for ReentrantMutex {}
|
|||
|
||||
impl ReentrantMutex {
|
||||
pub unsafe fn uninitialized() -> ReentrantMutex {
|
||||
ReentrantMutex { inner: mem::uninitialized() }
|
||||
ReentrantMutex { inner: UnsafeCell::new(libc::PTHREAD_MUTEX_INITIALIZER) }
|
||||
}
|
||||
|
||||
pub unsafe fn init(&mut self) {
|
||||
let mut attr: libc::pthread_mutexattr_t = mem::uninitialized();
|
||||
let result = libc::pthread_mutexattr_init(&mut attr as *mut _);
|
||||
let mut attr = MaybeUninit::<libc::pthread_mutexattr_t>::uninit();
|
||||
let result = libc::pthread_mutexattr_init(attr.as_mut_ptr());
|
||||
debug_assert_eq!(result, 0);
|
||||
let result = libc::pthread_mutexattr_settype(&mut attr as *mut _,
|
||||
let result = libc::pthread_mutexattr_settype(attr.as_mut_ptr(),
|
||||
libc::PTHREAD_MUTEX_RECURSIVE);
|
||||
debug_assert_eq!(result, 0);
|
||||
let result = libc::pthread_mutex_init(self.inner.get(), &attr as *const _);
|
||||
let result = libc::pthread_mutex_init(self.inner.get(), attr.as_ptr());
|
||||
debug_assert_eq!(result, 0);
|
||||
let result = libc::pthread_mutexattr_destroy(&mut attr as *mut _);
|
||||
let result = libc::pthread_mutexattr_destroy(attr.as_mut_ptr());
|
||||
debug_assert_eq!(result, 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -466,11 +466,11 @@ mod tests {
|
|||
// Test to make sure that a signal mask does not get inherited.
|
||||
let mut cmd = Command::new(OsStr::new("cat"));
|
||||
|
||||
let mut set: libc::sigset_t = mem::uninitialized();
|
||||
let mut old_set: libc::sigset_t = mem::uninitialized();
|
||||
t!(cvt(sigemptyset(&mut set)));
|
||||
t!(cvt(sigaddset(&mut set, libc::SIGINT)));
|
||||
t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, &set, &mut old_set)));
|
||||
let mut set = mem::MaybeUninit::<libc::sigset_t>::uninit();
|
||||
let mut old_set = mem::MaybeUninit::<libc::sigset_t>::uninit();
|
||||
t!(cvt(sigemptyset(set.as_mut_ptr())));
|
||||
t!(cvt(sigaddset(set.as_mut_ptr(), libc::SIGINT)));
|
||||
t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, set.as_ptr(), old_set.as_mut_ptr())));
|
||||
|
||||
cmd.stdin(Stdio::MakePipe);
|
||||
cmd.stdout(Stdio::MakePipe);
|
||||
|
@ -479,7 +479,7 @@ mod tests {
|
|||
let stdin_write = pipes.stdin.take().unwrap();
|
||||
let stdout_read = pipes.stdout.take().unwrap();
|
||||
|
||||
t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, &old_set,
|
||||
t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, old_set.as_ptr(),
|
||||
ptr::null_mut())));
|
||||
|
||||
t!(cvt(libc::kill(cat.id() as libc::pid_t, libc::SIGINT)));
|
||||
|
|
|
@ -202,7 +202,7 @@ impl Command {
|
|||
// emscripten has no signal support.
|
||||
#[cfg(not(any(target_os = "emscripten")))]
|
||||
{
|
||||
use crate::mem;
|
||||
use crate::mem::{self, MaybeUninit};
|
||||
// Reset signal handling so the child process starts in a
|
||||
// standardized state. libstd ignores SIGPIPE, and signal-handling
|
||||
// libraries often set a mask. Child processes inherit ignored
|
||||
|
@ -210,18 +210,18 @@ impl Command {
|
|||
// UNIX programs do not reset these things on their own, so we
|
||||
// need to clean things up now to avoid confusing the program
|
||||
// we're about to run.
|
||||
let mut set: libc::sigset_t = mem::uninitialized();
|
||||
let mut set = MaybeUninit::<libc::sigset_t>::uninit();
|
||||
if cfg!(target_os = "android") {
|
||||
// Implementing sigemptyset allow us to support older Android
|
||||
// versions. See the comment about Android and sig* functions in
|
||||
// process_common.rs
|
||||
libc::memset(&mut set as *mut _ as *mut _,
|
||||
libc::memset(set.as_mut_ptr() as *mut _,
|
||||
0,
|
||||
mem::size_of::<libc::sigset_t>());
|
||||
} else {
|
||||
cvt(libc::sigemptyset(&mut set))?;
|
||||
cvt(libc::sigemptyset(set.as_mut_ptr()))?;
|
||||
}
|
||||
cvt(libc::pthread_sigmask(libc::SIG_SETMASK, &set,
|
||||
cvt(libc::pthread_sigmask(libc::SIG_SETMASK, set.as_ptr(),
|
||||
ptr::null_mut()))?;
|
||||
let ret = sys::signal(libc::SIGPIPE, libc::SIG_DFL);
|
||||
if ret == libc::SIG_ERR {
|
||||
|
@ -273,7 +273,7 @@ impl Command {
|
|||
fn posix_spawn(&mut self, stdio: &ChildPipes, envp: Option<&CStringArray>)
|
||||
-> io::Result<Option<Process>>
|
||||
{
|
||||
use crate::mem;
|
||||
use crate::mem::MaybeUninit;
|
||||
use crate::sys;
|
||||
|
||||
if self.get_gid().is_some() ||
|
||||
|
@ -315,63 +315,63 @@ impl Command {
|
|||
|
||||
let mut p = Process { pid: 0, status: None };
|
||||
|
||||
struct PosixSpawnFileActions(libc::posix_spawn_file_actions_t);
|
||||
struct PosixSpawnFileActions(MaybeUninit<libc::posix_spawn_file_actions_t>);
|
||||
|
||||
impl Drop for PosixSpawnFileActions {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
libc::posix_spawn_file_actions_destroy(&mut self.0);
|
||||
libc::posix_spawn_file_actions_destroy(self.0.as_mut_ptr());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct PosixSpawnattr(libc::posix_spawnattr_t);
|
||||
struct PosixSpawnattr(MaybeUninit<libc::posix_spawnattr_t>);
|
||||
|
||||
impl Drop for PosixSpawnattr {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
libc::posix_spawnattr_destroy(&mut self.0);
|
||||
libc::posix_spawnattr_destroy(self.0.as_mut_ptr());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let mut file_actions = PosixSpawnFileActions(mem::uninitialized());
|
||||
let mut attrs = PosixSpawnattr(mem::uninitialized());
|
||||
let mut file_actions = PosixSpawnFileActions(MaybeUninit::uninit());
|
||||
let mut attrs = PosixSpawnattr(MaybeUninit::uninit());
|
||||
|
||||
libc::posix_spawnattr_init(&mut attrs.0);
|
||||
libc::posix_spawn_file_actions_init(&mut file_actions.0);
|
||||
libc::posix_spawnattr_init(attrs.0.as_mut_ptr());
|
||||
libc::posix_spawn_file_actions_init(file_actions.0.as_mut_ptr());
|
||||
|
||||
if let Some(fd) = stdio.stdin.fd() {
|
||||
cvt(libc::posix_spawn_file_actions_adddup2(&mut file_actions.0,
|
||||
cvt(libc::posix_spawn_file_actions_adddup2(file_actions.0.as_mut_ptr(),
|
||||
fd,
|
||||
libc::STDIN_FILENO))?;
|
||||
}
|
||||
if let Some(fd) = stdio.stdout.fd() {
|
||||
cvt(libc::posix_spawn_file_actions_adddup2(&mut file_actions.0,
|
||||
cvt(libc::posix_spawn_file_actions_adddup2(file_actions.0.as_mut_ptr(),
|
||||
fd,
|
||||
libc::STDOUT_FILENO))?;
|
||||
}
|
||||
if let Some(fd) = stdio.stderr.fd() {
|
||||
cvt(libc::posix_spawn_file_actions_adddup2(&mut file_actions.0,
|
||||
cvt(libc::posix_spawn_file_actions_adddup2(file_actions.0.as_mut_ptr(),
|
||||
fd,
|
||||
libc::STDERR_FILENO))?;
|
||||
}
|
||||
if let Some((f, cwd)) = addchdir {
|
||||
cvt(f(&mut file_actions.0, cwd.as_ptr()))?;
|
||||
cvt(f(file_actions.0.as_mut_ptr(), cwd.as_ptr()))?;
|
||||
}
|
||||
|
||||
let mut set: libc::sigset_t = mem::uninitialized();
|
||||
cvt(libc::sigemptyset(&mut set))?;
|
||||
cvt(libc::posix_spawnattr_setsigmask(&mut attrs.0,
|
||||
&set))?;
|
||||
cvt(libc::sigaddset(&mut set, libc::SIGPIPE))?;
|
||||
cvt(libc::posix_spawnattr_setsigdefault(&mut attrs.0,
|
||||
&set))?;
|
||||
let mut set = MaybeUninit::<libc::sigset_t>::uninit();
|
||||
cvt(libc::sigemptyset(set.as_mut_ptr()))?;
|
||||
cvt(libc::posix_spawnattr_setsigmask(attrs.0.as_mut_ptr(),
|
||||
set.as_ptr()))?;
|
||||
cvt(libc::sigaddset(set.as_mut_ptr(), libc::SIGPIPE))?;
|
||||
cvt(libc::posix_spawnattr_setsigdefault(attrs.0.as_mut_ptr(),
|
||||
set.as_ptr()))?;
|
||||
|
||||
let flags = libc::POSIX_SPAWN_SETSIGDEF |
|
||||
libc::POSIX_SPAWN_SETSIGMASK;
|
||||
cvt(libc::posix_spawnattr_setflags(&mut attrs.0, flags as _))?;
|
||||
cvt(libc::posix_spawnattr_setflags(attrs.0.as_mut_ptr(), flags as _))?;
|
||||
|
||||
// Make sure we synchronize access to the global `environ` resource
|
||||
let _env_lock = sys::os::env_lock();
|
||||
|
@ -380,8 +380,8 @@ impl Command {
|
|||
let ret = libc::posix_spawnp(
|
||||
&mut p.pid,
|
||||
self.get_argv()[0],
|
||||
&file_actions.0,
|
||||
&attrs.0,
|
||||
file_actions.0.as_ptr(),
|
||||
attrs.0.as_ptr(),
|
||||
self.get_argv().as_ptr() as *const _,
|
||||
envp as *const _,
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue