Skip to content

Commit c130599

Browse files
authored
Rollup merge of rust-lang#62163 - cuviper:unix-uninit, r=RalfJung
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. r? @RalfJung
2 parents 2c0f7eb + b533aff commit c130599

File tree

5 files changed

+58
-61
lines changed

5 files changed

+58
-61
lines changed

src/libstd/sys/unix/condvar.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,15 @@ impl Condvar {
4040
target_os = "android",
4141
target_os = "hermit")))]
4242
pub unsafe fn init(&mut self) {
43-
use crate::mem;
44-
let mut attr: libc::pthread_condattr_t = mem::uninitialized();
45-
let r = libc::pthread_condattr_init(&mut attr);
43+
use crate::mem::MaybeUninit;
44+
let mut attr = MaybeUninit::<libc::pthread_condattr_t>::uninit();
45+
let r = libc::pthread_condattr_init(attr.as_mut_ptr());
4646
assert_eq!(r, 0);
47-
let r = libc::pthread_condattr_setclock(&mut attr, libc::CLOCK_MONOTONIC);
47+
let r = libc::pthread_condattr_setclock(attr.as_mut_ptr(), libc::CLOCK_MONOTONIC);
4848
assert_eq!(r, 0);
49-
let r = libc::pthread_cond_init(self.inner.get(), &attr);
49+
let r = libc::pthread_cond_init(self.inner.get(), attr.as_ptr());
5050
assert_eq!(r, 0);
51-
let r = libc::pthread_condattr_destroy(&mut attr);
51+
let r = libc::pthread_condattr_destroy(attr.as_mut_ptr());
5252
assert_eq!(r, 0);
5353
}
5454

src/libstd/sys/unix/ext/net.rs

+5-6
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,9 @@ use libc::MSG_NOSIGNAL;
4040
target_os = "haiku")))]
4141
const MSG_NOSIGNAL: libc::c_int = 0x0;
4242

43-
fn sun_path_offset() -> usize {
43+
fn sun_path_offset(addr: &libc::sockaddr_un) -> usize {
4444
// Work with an actual instance of the type since using a null pointer is UB
45-
let addr: libc::sockaddr_un = unsafe { mem::uninitialized() };
46-
let base = &addr as *const _ as usize;
45+
let base = addr as *const _ as usize;
4746
let path = &addr.sun_path as *const _ as usize;
4847
path - base
4948
}
@@ -69,7 +68,7 @@ unsafe fn sockaddr_un(path: &Path) -> io::Result<(libc::sockaddr_un, libc::sockl
6968
// null byte for pathname addresses is already there because we zeroed the
7069
// struct
7170

72-
let mut len = sun_path_offset() + bytes.len();
71+
let mut len = sun_path_offset(&addr) + bytes.len();
7372
match bytes.get(0) {
7473
Some(&0) | None => {}
7574
Some(_) => len += 1,
@@ -122,7 +121,7 @@ impl SocketAddr {
122121
if len == 0 {
123122
// When there is a datagram from unnamed unix socket
124123
// linux returns zero bytes of address
125-
len = sun_path_offset() as libc::socklen_t; // i.e., zero-length address
124+
len = sun_path_offset(&addr) as libc::socklen_t; // i.e., zero-length address
126125
} else if addr.sun_family != libc::AF_UNIX as libc::sa_family_t {
127126
return Err(io::Error::new(io::ErrorKind::InvalidInput,
128127
"file descriptor did not correspond to a Unix socket"));
@@ -200,7 +199,7 @@ impl SocketAddr {
200199
}
201200

202201
fn address<'a>(&'a self) -> AddressKind<'a> {
203-
let len = self.len as usize - sun_path_offset();
202+
let len = self.len as usize - sun_path_offset(&self.addr);
204203
let path = unsafe { mem::transmute::<&[libc::c_char], &[u8]>(&self.addr.sun_path) };
205204

206205
// macOS seems to return a len of 16 and a zeroed sun_path for unnamed addresses

src/libstd/sys/unix/mutex.rs

+12-12
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::cell::UnsafeCell;
2-
use crate::mem;
2+
use crate::mem::MaybeUninit;
33

44
pub struct Mutex { inner: UnsafeCell<libc::pthread_mutex_t> }
55

@@ -40,14 +40,14 @@ impl Mutex {
4040
// references, we instead create the mutex with type
4141
// PTHREAD_MUTEX_NORMAL which is guaranteed to deadlock if we try to
4242
// re-lock it from the same thread, thus avoiding undefined behavior.
43-
let mut attr: libc::pthread_mutexattr_t = mem::uninitialized();
44-
let r = libc::pthread_mutexattr_init(&mut attr);
43+
let mut attr = MaybeUninit::<libc::pthread_mutexattr_t>::uninit();
44+
let r = libc::pthread_mutexattr_init(attr.as_mut_ptr());
4545
debug_assert_eq!(r, 0);
46-
let r = libc::pthread_mutexattr_settype(&mut attr, libc::PTHREAD_MUTEX_NORMAL);
46+
let r = libc::pthread_mutexattr_settype(attr.as_mut_ptr(), libc::PTHREAD_MUTEX_NORMAL);
4747
debug_assert_eq!(r, 0);
48-
let r = libc::pthread_mutex_init(self.inner.get(), &attr);
48+
let r = libc::pthread_mutex_init(self.inner.get(), attr.as_ptr());
4949
debug_assert_eq!(r, 0);
50-
let r = libc::pthread_mutexattr_destroy(&mut attr);
50+
let r = libc::pthread_mutexattr_destroy(attr.as_mut_ptr());
5151
debug_assert_eq!(r, 0);
5252
}
5353
#[inline]
@@ -89,19 +89,19 @@ unsafe impl Sync for ReentrantMutex {}
8989

9090
impl ReentrantMutex {
9191
pub unsafe fn uninitialized() -> ReentrantMutex {
92-
ReentrantMutex { inner: mem::uninitialized() }
92+
ReentrantMutex { inner: UnsafeCell::new(libc::PTHREAD_MUTEX_INITIALIZER) }
9393
}
9494

9595
pub unsafe fn init(&mut self) {
96-
let mut attr: libc::pthread_mutexattr_t = mem::uninitialized();
97-
let result = libc::pthread_mutexattr_init(&mut attr as *mut _);
96+
let mut attr = MaybeUninit::<libc::pthread_mutexattr_t>::uninit();
97+
let result = libc::pthread_mutexattr_init(attr.as_mut_ptr());
9898
debug_assert_eq!(result, 0);
99-
let result = libc::pthread_mutexattr_settype(&mut attr as *mut _,
99+
let result = libc::pthread_mutexattr_settype(attr.as_mut_ptr(),
100100
libc::PTHREAD_MUTEX_RECURSIVE);
101101
debug_assert_eq!(result, 0);
102-
let result = libc::pthread_mutex_init(self.inner.get(), &attr as *const _);
102+
let result = libc::pthread_mutex_init(self.inner.get(), attr.as_ptr());
103103
debug_assert_eq!(result, 0);
104-
let result = libc::pthread_mutexattr_destroy(&mut attr as *mut _);
104+
let result = libc::pthread_mutexattr_destroy(attr.as_mut_ptr());
105105
debug_assert_eq!(result, 0);
106106
}
107107

src/libstd/sys/unix/process/process_common.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -437,7 +437,7 @@ mod tests {
437437

438438
#[cfg(target_os = "android")]
439439
unsafe fn sigemptyset(set: *mut libc::sigset_t) -> libc::c_int {
440-
libc::memset(set as *mut _, 0, mem::size_of::<libc::sigset_t>());
440+
set.write_bytes(0u8, 1);
441441
return 0;
442442
}
443443

@@ -466,11 +466,11 @@ mod tests {
466466
// Test to make sure that a signal mask does not get inherited.
467467
let mut cmd = Command::new(OsStr::new("cat"));
468468

469-
let mut set: libc::sigset_t = mem::uninitialized();
470-
let mut old_set: libc::sigset_t = mem::uninitialized();
471-
t!(cvt(sigemptyset(&mut set)));
472-
t!(cvt(sigaddset(&mut set, libc::SIGINT)));
473-
t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, &set, &mut old_set)));
469+
let mut set = mem::MaybeUninit::<libc::sigset_t>::uninit();
470+
let mut old_set = mem::MaybeUninit::<libc::sigset_t>::uninit();
471+
t!(cvt(sigemptyset(set.as_mut_ptr())));
472+
t!(cvt(sigaddset(set.as_mut_ptr(), libc::SIGINT)));
473+
t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, set.as_ptr(), old_set.as_mut_ptr())));
474474

475475
cmd.stdin(Stdio::MakePipe);
476476
cmd.stdout(Stdio::MakePipe);
@@ -479,7 +479,7 @@ mod tests {
479479
let stdin_write = pipes.stdin.take().unwrap();
480480
let stdout_read = pipes.stdout.take().unwrap();
481481

482-
t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, &old_set,
482+
t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, old_set.as_ptr(),
483483
ptr::null_mut())));
484484

485485
t!(cvt(libc::kill(cat.id() as libc::pid_t, libc::SIGINT)));

src/libstd/sys/unix/process/process_unix.rs

+28-30
Original file line numberDiff line numberDiff line change
@@ -202,26 +202,24 @@ impl Command {
202202
// emscripten has no signal support.
203203
#[cfg(not(any(target_os = "emscripten")))]
204204
{
205-
use crate::mem;
205+
use crate::mem::MaybeUninit;
206206
// Reset signal handling so the child process starts in a
207207
// standardized state. libstd ignores SIGPIPE, and signal-handling
208208
// libraries often set a mask. Child processes inherit ignored
209209
// signals and the signal mask from their parent, but most
210210
// UNIX programs do not reset these things on their own, so we
211211
// need to clean things up now to avoid confusing the program
212212
// we're about to run.
213-
let mut set: libc::sigset_t = mem::uninitialized();
213+
let mut set = MaybeUninit::<libc::sigset_t>::uninit();
214214
if cfg!(target_os = "android") {
215215
// Implementing sigemptyset allow us to support older Android
216216
// versions. See the comment about Android and sig* functions in
217217
// process_common.rs
218-
libc::memset(&mut set as *mut _ as *mut _,
219-
0,
220-
mem::size_of::<libc::sigset_t>());
218+
set.as_mut_ptr().write_bytes(0u8, 1);
221219
} else {
222-
cvt(libc::sigemptyset(&mut set))?;
220+
cvt(libc::sigemptyset(set.as_mut_ptr()))?;
223221
}
224-
cvt(libc::pthread_sigmask(libc::SIG_SETMASK, &set,
222+
cvt(libc::pthread_sigmask(libc::SIG_SETMASK, set.as_ptr(),
225223
ptr::null_mut()))?;
226224
let ret = sys::signal(libc::SIGPIPE, libc::SIG_DFL);
227225
if ret == libc::SIG_ERR {
@@ -273,7 +271,7 @@ impl Command {
273271
fn posix_spawn(&mut self, stdio: &ChildPipes, envp: Option<&CStringArray>)
274272
-> io::Result<Option<Process>>
275273
{
276-
use crate::mem;
274+
use crate::mem::MaybeUninit;
277275
use crate::sys;
278276

279277
if self.get_gid().is_some() ||
@@ -315,63 +313,63 @@ impl Command {
315313

316314
let mut p = Process { pid: 0, status: None };
317315

318-
struct PosixSpawnFileActions(libc::posix_spawn_file_actions_t);
316+
struct PosixSpawnFileActions(MaybeUninit<libc::posix_spawn_file_actions_t>);
319317

320318
impl Drop for PosixSpawnFileActions {
321319
fn drop(&mut self) {
322320
unsafe {
323-
libc::posix_spawn_file_actions_destroy(&mut self.0);
321+
libc::posix_spawn_file_actions_destroy(self.0.as_mut_ptr());
324322
}
325323
}
326324
}
327325

328-
struct PosixSpawnattr(libc::posix_spawnattr_t);
326+
struct PosixSpawnattr(MaybeUninit<libc::posix_spawnattr_t>);
329327

330328
impl Drop for PosixSpawnattr {
331329
fn drop(&mut self) {
332330
unsafe {
333-
libc::posix_spawnattr_destroy(&mut self.0);
331+
libc::posix_spawnattr_destroy(self.0.as_mut_ptr());
334332
}
335333
}
336334
}
337335

338336
unsafe {
339-
let mut file_actions = PosixSpawnFileActions(mem::uninitialized());
340-
let mut attrs = PosixSpawnattr(mem::uninitialized());
337+
let mut file_actions = PosixSpawnFileActions(MaybeUninit::uninit());
338+
let mut attrs = PosixSpawnattr(MaybeUninit::uninit());
341339

342-
libc::posix_spawnattr_init(&mut attrs.0);
343-
libc::posix_spawn_file_actions_init(&mut file_actions.0);
340+
libc::posix_spawnattr_init(attrs.0.as_mut_ptr());
341+
libc::posix_spawn_file_actions_init(file_actions.0.as_mut_ptr());
344342

345343
if let Some(fd) = stdio.stdin.fd() {
346-
cvt(libc::posix_spawn_file_actions_adddup2(&mut file_actions.0,
344+
cvt(libc::posix_spawn_file_actions_adddup2(file_actions.0.as_mut_ptr(),
347345
fd,
348346
libc::STDIN_FILENO))?;
349347
}
350348
if let Some(fd) = stdio.stdout.fd() {
351-
cvt(libc::posix_spawn_file_actions_adddup2(&mut file_actions.0,
349+
cvt(libc::posix_spawn_file_actions_adddup2(file_actions.0.as_mut_ptr(),
352350
fd,
353351
libc::STDOUT_FILENO))?;
354352
}
355353
if let Some(fd) = stdio.stderr.fd() {
356-
cvt(libc::posix_spawn_file_actions_adddup2(&mut file_actions.0,
354+
cvt(libc::posix_spawn_file_actions_adddup2(file_actions.0.as_mut_ptr(),
357355
fd,
358356
libc::STDERR_FILENO))?;
359357
}
360358
if let Some((f, cwd)) = addchdir {
361-
cvt(f(&mut file_actions.0, cwd.as_ptr()))?;
359+
cvt(f(file_actions.0.as_mut_ptr(), cwd.as_ptr()))?;
362360
}
363361

364-
let mut set: libc::sigset_t = mem::uninitialized();
365-
cvt(libc::sigemptyset(&mut set))?;
366-
cvt(libc::posix_spawnattr_setsigmask(&mut attrs.0,
367-
&set))?;
368-
cvt(libc::sigaddset(&mut set, libc::SIGPIPE))?;
369-
cvt(libc::posix_spawnattr_setsigdefault(&mut attrs.0,
370-
&set))?;
362+
let mut set = MaybeUninit::<libc::sigset_t>::uninit();
363+
cvt(libc::sigemptyset(set.as_mut_ptr()))?;
364+
cvt(libc::posix_spawnattr_setsigmask(attrs.0.as_mut_ptr(),
365+
set.as_ptr()))?;
366+
cvt(libc::sigaddset(set.as_mut_ptr(), libc::SIGPIPE))?;
367+
cvt(libc::posix_spawnattr_setsigdefault(attrs.0.as_mut_ptr(),
368+
set.as_ptr()))?;
371369

372370
let flags = libc::POSIX_SPAWN_SETSIGDEF |
373371
libc::POSIX_SPAWN_SETSIGMASK;
374-
cvt(libc::posix_spawnattr_setflags(&mut attrs.0, flags as _))?;
372+
cvt(libc::posix_spawnattr_setflags(attrs.0.as_mut_ptr(), flags as _))?;
375373

376374
// Make sure we synchronize access to the global `environ` resource
377375
let _env_lock = sys::os::env_lock();
@@ -380,8 +378,8 @@ impl Command {
380378
let ret = libc::posix_spawnp(
381379
&mut p.pid,
382380
self.get_argv()[0],
383-
&file_actions.0,
384-
&attrs.0,
381+
file_actions.0.as_ptr(),
382+
attrs.0.as_ptr(),
385383
self.get_argv().as_ptr() as *const _,
386384
envp as *const _,
387385
);

0 commit comments

Comments
 (0)