Auto merge of #127757 - workingjubilee:rollup-4dbks5r, r=workingjubilee

Rollup of 3 pull requests

Successful merges:

 - #127712 (Windows: Remove some unnecessary type aliases)
 - #127744 (std: `#![deny(unsafe_op_in_unsafe_fn)]` in platform-independent code)
 - #127750 (Make os/windows and pal/windows default to `#![deny(unsafe_op_in_unsafe_fn)]`)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2024-07-15 10:57:49 +00:00
commit d3dd34a1d4
45 changed files with 306 additions and 291 deletions

View file

@ -1018,7 +1018,7 @@ where
K: Borrow<Q>,
Q: Hash + Eq,
{
self.base.get_many_unchecked_mut(ks)
unsafe { self.base.get_many_unchecked_mut(ks) }
}
/// Returns `true` if the map contains a value for the specified key.

View file

@ -366,11 +366,8 @@ impl Error for VarError {
#[rustc_deprecated_safe_2024]
#[stable(feature = "env", since = "1.0.0")]
pub unsafe fn set_var<K: AsRef<OsStr>, V: AsRef<OsStr>>(key: K, value: V) {
_set_var(key.as_ref(), value.as_ref())
}
unsafe fn _set_var(key: &OsStr, value: &OsStr) {
os_imp::setenv(key, value).unwrap_or_else(|e| {
let (key, value) = (key.as_ref(), value.as_ref());
unsafe { os_imp::setenv(key, value) }.unwrap_or_else(|e| {
panic!("failed to set environment variable `{key:?}` to `{value:?}`: {e}")
})
}
@ -433,11 +430,8 @@ unsafe fn _set_var(key: &OsStr, value: &OsStr) {
#[rustc_deprecated_safe_2024]
#[stable(feature = "env", since = "1.0.0")]
pub unsafe fn remove_var<K: AsRef<OsStr>>(key: K) {
_remove_var(key.as_ref())
}
unsafe fn _remove_var(key: &OsStr) {
os_imp::unsetenv(key)
let key = key.as_ref();
unsafe { os_imp::unsetenv(key) }
.unwrap_or_else(|e| panic!("failed to remove environment variable `{key:?}`: {e}"))
}

View file

@ -184,7 +184,7 @@ impl OsString {
#[inline]
#[stable(feature = "os_str_bytes", since = "1.74.0")]
pub unsafe fn from_encoded_bytes_unchecked(bytes: Vec<u8>) -> Self {
OsString { inner: Buf::from_encoded_bytes_unchecked(bytes) }
OsString { inner: unsafe { Buf::from_encoded_bytes_unchecked(bytes) } }
}
/// Converts to an [`OsStr`] slice.
@ -813,7 +813,7 @@ impl OsStr {
#[inline]
#[stable(feature = "os_str_bytes", since = "1.74.0")]
pub unsafe fn from_encoded_bytes_unchecked(bytes: &[u8]) -> &Self {
Self::from_inner(Slice::from_encoded_bytes_unchecked(bytes))
Self::from_inner(unsafe { Slice::from_encoded_bytes_unchecked(bytes) })
}
#[inline]

View file

@ -433,9 +433,11 @@ impl<W: ?Sized + Write> BufWriter<W> {
let old_len = self.buf.len();
let buf_len = buf.len();
let src = buf.as_ptr();
let dst = self.buf.as_mut_ptr().add(old_len);
ptr::copy_nonoverlapping(src, dst, buf_len);
self.buf.set_len(old_len + buf_len);
unsafe {
let dst = self.buf.as_mut_ptr().add(old_len);
ptr::copy_nonoverlapping(src, dst, buf_len);
self.buf.set_len(old_len + buf_len);
}
}
#[inline]

View file

@ -482,7 +482,7 @@ where
A: Allocator,
{
debug_assert!(vec.capacity() >= pos + buf.len());
vec.as_mut_ptr().add(pos).copy_from(buf.as_ptr(), buf.len());
unsafe { vec.as_mut_ptr().add(pos).copy_from(buf.as_ptr(), buf.len()) };
pos + buf.len()
}

View file

@ -267,11 +267,14 @@ where
// Using this rather than unwrap meaningfully improves the code
// for callers which only care about one variant (usually
// `Custom`)
core::hint::unreachable_unchecked();
unsafe { core::hint::unreachable_unchecked() };
});
ErrorData::Simple(kind)
}
TAG_SIMPLE_MESSAGE => ErrorData::SimpleMessage(&*ptr.cast::<SimpleMessage>().as_ptr()),
TAG_SIMPLE_MESSAGE => {
// SAFETY: per tag
unsafe { ErrorData::SimpleMessage(&*ptr.cast::<SimpleMessage>().as_ptr()) }
}
TAG_CUSTOM => {
// It would be correct for us to use `ptr::byte_sub` here (see the
// comment above the `wrapping_add` call in `new_custom` for why),

View file

@ -382,11 +382,11 @@ pub(crate) unsafe fn append_to_string<F>(buf: &mut String, f: F) -> Result<usize
where
F: FnOnce(&mut Vec<u8>) -> Result<usize>,
{
let mut g = Guard { len: buf.len(), buf: buf.as_mut_vec() };
let mut g = Guard { len: buf.len(), buf: unsafe { buf.as_mut_vec() } };
let ret = f(g.buf);
// SAFETY: the caller promises to only append data to `buf`
let appended = g.buf.get_unchecked(g.len..);
let appended = unsafe { g.buf.get_unchecked(g.len..) };
if str::from_utf8(appended).is_err() {
ret.and_then(|_| Err(Error::INVALID_UTF8))
} else {

View file

@ -252,6 +252,7 @@
#![allow(internal_features)]
#![deny(rustc::existing_doc_keyword)]
#![deny(fuzzy_provenance_casts)]
#![deny(unsafe_op_in_unsafe_fn)]
#![allow(rustdoc::redundant_explicit_links)]
// Ensure that std can be linked against panic_abort despite compiled with `-C panic=unwind`
#![deny(ffi_unwind_calls)]
@ -664,7 +665,7 @@ pub mod alloc;
mod panicking;
#[path = "../../backtrace/src/lib.rs"]
#[allow(dead_code, unused_attributes, fuzzy_provenance_casts)]
#[allow(dead_code, unused_attributes, fuzzy_provenance_casts, unsafe_op_in_unsafe_fn)]
mod backtrace_rs;
// Re-export macros defined in core.

View file

@ -2,6 +2,7 @@
#![stable(feature = "os", since = "1.0.0")]
#![allow(missing_docs, nonstandard_style, missing_debug_implementations)]
#![allow(unsafe_op_in_unsafe_fn)]
pub mod raw;

View file

@ -159,10 +159,12 @@ fn stdio_handle(raw: RawHandle) -> RawHandle {
impl FromRawHandle for fs::File {
#[inline]
unsafe fn from_raw_handle(handle: RawHandle) -> fs::File {
let handle = handle as sys::c::HANDLE;
fs::File::from_inner(sys::fs::File::from_inner(FromInner::from_inner(
OwnedHandle::from_raw_handle(handle),
)))
unsafe {
let handle = handle as sys::c::HANDLE;
fs::File::from_inner(sys::fs::File::from_inner(FromInner::from_inner(
OwnedHandle::from_raw_handle(handle),
)))
}
}
}
@ -260,24 +262,30 @@ impl AsRawSocket for net::UdpSocket {
impl FromRawSocket for net::TcpStream {
#[inline]
unsafe fn from_raw_socket(sock: RawSocket) -> net::TcpStream {
let sock = sys::net::Socket::from_inner(OwnedSocket::from_raw_socket(sock));
net::TcpStream::from_inner(sys_common::net::TcpStream::from_inner(sock))
unsafe {
let sock = sys::net::Socket::from_inner(OwnedSocket::from_raw_socket(sock));
net::TcpStream::from_inner(sys_common::net::TcpStream::from_inner(sock))
}
}
}
#[stable(feature = "from_raw_os", since = "1.1.0")]
impl FromRawSocket for net::TcpListener {
#[inline]
unsafe fn from_raw_socket(sock: RawSocket) -> net::TcpListener {
let sock = sys::net::Socket::from_inner(OwnedSocket::from_raw_socket(sock));
net::TcpListener::from_inner(sys_common::net::TcpListener::from_inner(sock))
unsafe {
let sock = sys::net::Socket::from_inner(OwnedSocket::from_raw_socket(sock));
net::TcpListener::from_inner(sys_common::net::TcpListener::from_inner(sock))
}
}
}
#[stable(feature = "from_raw_os", since = "1.1.0")]
impl FromRawSocket for net::UdpSocket {
#[inline]
unsafe fn from_raw_socket(sock: RawSocket) -> net::UdpSocket {
let sock = sys::net::Socket::from_inner(OwnedSocket::from_raw_socket(sock));
net::UdpSocket::from_inner(sys_common::net::UdpSocket::from_inner(sock))
unsafe {
let sock = sys::net::Socket::from_inner(OwnedSocket::from_raw_socket(sock));
net::UdpSocket::from_inner(sys_common::net::UdpSocket::from_inner(sock))
}
}
}

View file

@ -76,7 +76,7 @@ impl BorrowedSocket<'_> {
#[stable(feature = "io_safety", since = "1.63.0")]
pub const unsafe fn borrow_raw(socket: RawSocket) -> Self {
assert!(socket != sys::c::INVALID_SOCKET as RawSocket);
Self { socket, _phantom: PhantomData }
unsafe { Self { socket, _phantom: PhantomData } }
}
}
@ -201,8 +201,10 @@ impl IntoRawSocket for OwnedSocket {
impl FromRawSocket for OwnedSocket {
#[inline]
unsafe fn from_raw_socket(socket: RawSocket) -> Self {
debug_assert_ne!(socket, sys::c::INVALID_SOCKET as RawSocket);
Self { socket }
unsafe {
debug_assert_ne!(socket, sys::c::INVALID_SOCKET as RawSocket);
Self { socket }
}
}
}

View file

@ -24,6 +24,7 @@
#![stable(feature = "rust1", since = "1.0.0")]
#![doc(cfg(windows))]
#![deny(unsafe_op_in_unsafe_fn)]
pub mod ffi;
pub mod fs;

View file

@ -16,7 +16,7 @@ use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
#[stable(feature = "process_extensions", since = "1.2.0")]
impl FromRawHandle for process::Stdio {
unsafe fn from_raw_handle(handle: RawHandle) -> process::Stdio {
let handle = sys::handle::Handle::from_raw_handle(handle as *mut _);
let handle = unsafe { sys::handle::Handle::from_raw_handle(handle as *mut _) };
let io = sys::process::Stdio::Handle(handle);
process::Stdio::from_inner(io)
}
@ -407,7 +407,7 @@ impl CommandExt for process::Command {
attribute: usize,
value: T,
) -> &mut process::Command {
self.as_inner_mut().raw_attribute(attribute, value);
unsafe { self.as_inner_mut().raw_attribute(attribute, value) };
self
}
}

View file

@ -385,29 +385,25 @@ fn test_interior_nul_in_env_value_is_error() {
#[cfg(windows)]
fn test_creation_flags() {
use crate::os::windows::process::CommandExt;
use crate::sys::c::{BOOL, DWORD, INFINITE};
use crate::sys::c::{BOOL, INFINITE};
#[repr(C)]
struct DEBUG_EVENT {
pub event_code: DWORD,
pub process_id: DWORD,
pub thread_id: DWORD,
pub event_code: u32,
pub process_id: u32,
pub thread_id: u32,
// This is a union in the real struct, but we don't
// need this data for the purposes of this test.
pub _junk: [u8; 164],
}
extern "system" {
fn WaitForDebugEvent(lpDebugEvent: *mut DEBUG_EVENT, dwMilliseconds: DWORD) -> BOOL;
fn ContinueDebugEvent(
dwProcessId: DWORD,
dwThreadId: DWORD,
dwContinueStatus: DWORD,
) -> BOOL;
fn WaitForDebugEvent(lpDebugEvent: *mut DEBUG_EVENT, dwMilliseconds: u32) -> BOOL;
fn ContinueDebugEvent(dwProcessId: u32, dwThreadId: u32, dwContinueStatus: u32) -> BOOL;
}
const DEBUG_PROCESS: DWORD = 1;
const EXIT_PROCESS_DEBUG_EVENT: DWORD = 5;
const DBG_EXCEPTION_NOT_HANDLED: DWORD = 0x80010001;
const DEBUG_PROCESS: u32 = 1;
const EXIT_PROCESS_DEBUG_EVENT: u32 = 5;
const DBG_EXCEPTION_NOT_HANDLED: u32 = 0x80010001;
let mut child =
Command::new("cmd").creation_flags(DEBUG_PROCESS).stdin(Stdio::piped()).spawn().unwrap();

View file

@ -200,11 +200,12 @@ impl<T> Channel<T> {
return Err(msg);
}
let slot: &Slot<T> = &*(token.array.slot as *const Slot<T>);
// Write the message into the slot and update the stamp.
slot.msg.get().write(MaybeUninit::new(msg));
slot.stamp.store(token.array.stamp, Ordering::Release);
unsafe {
let slot: &Slot<T> = &*(token.array.slot as *const Slot<T>);
slot.msg.get().write(MaybeUninit::new(msg));
slot.stamp.store(token.array.stamp, Ordering::Release);
}
// Wake a sleeping receiver.
self.receivers.notify();
@ -291,11 +292,14 @@ impl<T> Channel<T> {
return Err(());
}
let slot: &Slot<T> = &*(token.array.slot as *const Slot<T>);
// Read the message from the slot and update the stamp.
let msg = slot.msg.get().read().assume_init();
slot.stamp.store(token.array.stamp, Ordering::Release);
let msg = unsafe {
let slot: &Slot<T> = &*(token.array.slot as *const Slot<T>);
let msg = slot.msg.get().read().assume_init();
slot.stamp.store(token.array.stamp, Ordering::Release);
msg
};
// Wake a sleeping sender.
self.senders.notify();
@ -471,7 +475,7 @@ impl<T> Channel<T> {
false
};
self.discard_all_messages(tail);
unsafe { self.discard_all_messages(tail) };
disconnected
}

View file

@ -63,7 +63,7 @@ impl<C> Sender<C> {
disconnect(&self.counter().chan);
if self.counter().destroy.swap(true, Ordering::AcqRel) {
drop(Box::from_raw(self.counter));
drop(unsafe { Box::from_raw(self.counter) });
}
}
}
@ -116,7 +116,7 @@ impl<C> Receiver<C> {
disconnect(&self.counter().chan);
if self.counter().destroy.swap(true, Ordering::AcqRel) {
drop(Box::from_raw(self.counter));
drop(unsafe { Box::from_raw(self.counter) });
}
}
}

View file

@ -91,7 +91,7 @@ impl<T> Block<T> {
// It is not necessary to set the `DESTROY` bit in the last slot because that slot has
// begun destruction of the block.
for i in start..BLOCK_CAP - 1 {
let slot = (*this).slots.get_unchecked(i);
let slot = unsafe { (*this).slots.get_unchecked(i) };
// Mark the `DESTROY` bit if a thread is still using the slot.
if slot.state.load(Ordering::Acquire) & READ == 0
@ -103,7 +103,7 @@ impl<T> Block<T> {
}
// No thread is using the block, now it is safe to destroy it.
drop(Box::from_raw(this));
drop(unsafe { Box::from_raw(this) });
}
}
@ -265,9 +265,11 @@ impl<T> Channel<T> {
// Write the message into the slot.
let block = token.list.block as *mut Block<T>;
let offset = token.list.offset;
let slot = (*block).slots.get_unchecked(offset);
slot.msg.get().write(MaybeUninit::new(msg));
slot.state.fetch_or(WRITE, Ordering::Release);
unsafe {
let slot = (*block).slots.get_unchecked(offset);
slot.msg.get().write(MaybeUninit::new(msg));
slot.state.fetch_or(WRITE, Ordering::Release);
}
// Wake a sleeping receiver.
self.receivers.notify();
@ -369,19 +371,21 @@ impl<T> Channel<T> {
// Read the message.
let block = token.list.block as *mut Block<T>;
let offset = token.list.offset;
let slot = (*block).slots.get_unchecked(offset);
slot.wait_write();
let msg = slot.msg.get().read().assume_init();
unsafe {
let slot = (*block).slots.get_unchecked(offset);
slot.wait_write();
let msg = slot.msg.get().read().assume_init();
// Destroy the block if we've reached the end, or if another thread wanted to destroy but
// couldn't because we were busy reading from the slot.
if offset + 1 == BLOCK_CAP {
Block::destroy(block, 0);
} else if slot.state.fetch_or(READ, Ordering::AcqRel) & DESTROY != 0 {
Block::destroy(block, offset + 1);
// Destroy the block if we've reached the end, or if another thread wanted to destroy but
// couldn't because we were busy reading from the slot.
if offset + 1 == BLOCK_CAP {
Block::destroy(block, 0);
} else if slot.state.fetch_or(READ, Ordering::AcqRel) & DESTROY != 0 {
Block::destroy(block, offset + 1);
}
Ok(msg)
}
Ok(msg)
}
/// Attempts to send a message into the channel.

View file

@ -103,9 +103,11 @@ impl<T> Channel<T> {
return Err(msg);
}
let packet = &*(token.zero.0 as *const Packet<T>);
packet.msg.get().write(Some(msg));
packet.ready.store(true, Ordering::Release);
unsafe {
let packet = &*(token.zero.0 as *const Packet<T>);
packet.msg.get().write(Some(msg));
packet.ready.store(true, Ordering::Release);
}
Ok(())
}
@ -116,22 +118,24 @@ impl<T> Channel<T> {
return Err(());
}
let packet = &*(token.zero.0 as *const Packet<T>);
let packet = unsafe { &*(token.zero.0 as *const Packet<T>) };
if packet.on_stack {
// The message has been in the packet from the beginning, so there is no need to wait
// for it. However, after reading the message, we need to set `ready` to `true` in
// order to signal that the packet can be destroyed.
let msg = packet.msg.get().replace(None).unwrap();
let msg = unsafe { packet.msg.get().replace(None) }.unwrap();
packet.ready.store(true, Ordering::Release);
Ok(msg)
} else {
// Wait until the message becomes available, then read it and destroy the
// heap-allocated packet.
packet.wait_ready();
let msg = packet.msg.get().replace(None).unwrap();
drop(Box::from_raw(token.zero.0 as *mut Packet<T>));
Ok(msg)
unsafe {
let msg = packet.msg.get().replace(None).unwrap();
drop(Box::from_raw(token.zero.0 as *mut Packet<T>));
Ok(msg)
}
}
}

View file

@ -502,7 +502,7 @@ impl<T> OnceLock<T> {
#[inline]
unsafe fn get_unchecked(&self) -> &T {
debug_assert!(self.is_initialized());
(&*self.value.get()).assume_init_ref()
unsafe { (&*self.value.get()).assume_init_ref() }
}
/// # Safety
@ -511,7 +511,7 @@ impl<T> OnceLock<T> {
#[inline]
unsafe fn get_unchecked_mut(&mut self) -> &mut T {
debug_assert!(self.is_initialized());
(&mut *self.value.get()).assume_init_mut()
unsafe { (&mut *self.value.get()).assume_init_mut() }
}
}

View file

@ -244,7 +244,9 @@ impl<T: ?Sized> ReentrantLock<T> {
}
unsafe fn increment_lock_count(&self) -> Option<()> {
*self.lock_count.get() = (*self.lock_count.get()).checked_add(1)?;
unsafe {
*self.lock_count.get() = (*self.lock_count.get()).checked_add(1)?;
}
Some(())
}
}

View file

@ -578,7 +578,7 @@ impl<'rwlock, T: ?Sized> RwLockReadGuard<'rwlock, T> {
// successfully called from the same thread before instantiating this object.
unsafe fn new(lock: &'rwlock RwLock<T>) -> LockResult<RwLockReadGuard<'rwlock, T>> {
poison::map_result(lock.poison.borrow(), |()| RwLockReadGuard {
data: NonNull::new_unchecked(lock.data.get()),
data: unsafe { NonNull::new_unchecked(lock.data.get()) },
inner_lock: &lock.inner,
})
}

View file

@ -1,3 +1,5 @@
#![allow(unsafe_op_in_unsafe_fn)]
/// The PAL (platform abstraction layer) contains platform-specific abstractions
/// for implementing the features in the other submodules, e.g. UNIX file
/// descriptors.

View file

@ -15,7 +15,7 @@ mod tests;
// See https://docs.microsoft.com/windows/win32/api/heapapi/
// Flag to indicate that the memory returned by `HeapAlloc` should be zeroed.
const HEAP_ZERO_MEMORY: c::DWORD = 0x00000008;
const HEAP_ZERO_MEMORY: u32 = 0x00000008;
// Get a handle to the default heap of the current process, or null if the operation fails.
//
@ -113,9 +113,9 @@ fn init_or_get_process_heap() -> c::HANDLE {
#[cold]
extern "C" fn process_heap_init_and_alloc(
_heap: MaybeUninit<c::HANDLE>, // We pass this argument to match the ABI of `HeapAlloc`
flags: c::DWORD,
dwBytes: c::SIZE_T,
) -> c::LPVOID {
flags: u32,
dwBytes: usize,
) -> *mut c_void {
let heap = init_or_get_process_heap();
if core::intrinsics::unlikely(heap.is_null()) {
return ptr::null_mut();
@ -127,9 +127,9 @@ extern "C" fn process_heap_init_and_alloc(
#[inline(never)]
fn process_heap_alloc(
_heap: MaybeUninit<c::HANDLE>, // We pass this argument to match the ABI of `HeapAlloc`,
flags: c::DWORD,
dwBytes: c::SIZE_T,
) -> c::LPVOID {
flags: u32,
dwBytes: usize,
) -> *mut c_void {
let heap = HEAP.load(Ordering::Relaxed);
if core::intrinsics::likely(!heap.is_null()) {
// SAFETY: `heap` is a non-null handle returned by `GetProcessHeap`.
@ -240,7 +240,7 @@ unsafe impl GlobalAlloc for System {
// SAFETY: `heap` is a non-null handle returned by `GetProcessHeap`,
// `block` is a pointer to the start of an allocated block.
unsafe { HeapFree(heap, 0, block as c::LPVOID) };
unsafe { HeapFree(heap, 0, block.cast::<c_void>()) };
}
#[inline]
@ -253,7 +253,7 @@ unsafe impl GlobalAlloc for System {
// SAFETY: `heap` is a non-null handle returned by `GetProcessHeap`,
// `ptr` is a pointer to the start of an allocated block.
// The returned pointer points to the start of an allocated block.
unsafe { HeapReAlloc(heap, 0, ptr as c::LPVOID, new_size) as *mut u8 }
unsafe { HeapReAlloc(heap, 0, ptr.cast::<c_void>(), new_size).cast::<u8>() }
} else {
// SAFETY: `realloc_fallback` is implemented using `dealloc` and `alloc`, which will
// correctly handle `ptr` and return a pointer satisfying the guarantees of `System`

View file

@ -227,8 +227,10 @@ pub fn set_file_information_by_handle<T: SetFileInformation>(
info: *const c_void,
size: u32,
) -> Result<(), WinError> {
let result = c::SetFileInformationByHandle(handle, class, info, size);
(result != 0).then_some(()).ok_or_else(get_last_error)
unsafe {
let result = c::SetFileInformationByHandle(handle, class, info, size);
(result != 0).then_some(()).ok_or_else(get_last_error)
}
}
// SAFETY: The `SetFileInformation` trait ensures that this is safe.
unsafe { set_info(handle, T::CLASS, info.as_ptr(), info.size()) }

View file

@ -4,12 +4,11 @@
#![cfg_attr(test, allow(dead_code))]
#![unstable(issue = "none", feature = "windows_c")]
#![allow(clippy::style)]
#![allow(unsafe_op_in_unsafe_fn)]
use crate::ffi::CStr;
use crate::mem;
use crate::num::NonZero;
pub use crate::os::raw::c_int;
use crate::os::raw::{c_char, c_long, c_longlong, c_uint, c_ulong, c_ushort, c_void};
use crate::os::raw::{c_char, c_int, c_uint, c_ulong, c_ushort, c_void};
use crate::os::windows::io::{AsRawHandle, BorrowedHandle};
use crate::ptr;
@ -18,30 +17,10 @@ pub(super) mod windows_targets;
mod windows_sys;
pub use windows_sys::*;
pub type DWORD = c_ulong;
pub type NonZeroDWORD = NonZero<c_ulong>;
pub type LARGE_INTEGER = c_longlong;
#[cfg_attr(target_vendor = "uwp", allow(unused))]
pub type LONG = c_long;
pub type UINT = c_uint;
pub type WCHAR = u16;
pub type USHORT = c_ushort;
pub type SIZE_T = usize;
pub type CHAR = c_char;
pub type ULONG = c_ulong;
pub type LPCVOID = *const c_void;
pub type LPOVERLAPPED = *mut OVERLAPPED;
pub type LPSECURITY_ATTRIBUTES = *mut SECURITY_ATTRIBUTES;
pub type LPVOID = *mut c_void;
pub type LPWCH = *mut WCHAR;
pub type LPWSTR = *mut WCHAR;
#[cfg(target_vendor = "win7")]
pub type PSRWLOCK = *mut SRWLOCK;
pub type socklen_t = c_int;
pub type ADDRESS_FAMILY = USHORT;
pub type ADDRESS_FAMILY = c_ushort;
pub use FD_SET as fd_set;
pub use LINGER as linger;
pub use TIMEVAL as timeval;
@ -151,25 +130,25 @@ pub struct MOUNT_POINT_REPARSE_BUFFER {
#[repr(C)]
pub struct SOCKADDR_STORAGE_LH {
pub ss_family: ADDRESS_FAMILY,
pub __ss_pad1: [CHAR; 6],
pub __ss_pad1: [c_char; 6],
pub __ss_align: i64,
pub __ss_pad2: [CHAR; 112],
pub __ss_pad2: [c_char; 112],
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct sockaddr_in {
pub sin_family: ADDRESS_FAMILY,
pub sin_port: USHORT,
pub sin_port: c_ushort,
pub sin_addr: in_addr,
pub sin_zero: [CHAR; 8],
pub sin_zero: [c_char; 8],
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct sockaddr_in6 {
pub sin6_family: ADDRESS_FAMILY,
pub sin6_port: USHORT,
pub sin6_port: c_ushort,
pub sin6_flowinfo: c_ulong,
pub sin6_addr: in6_addr,
pub sin6_scope_id: c_ulong,
@ -271,9 +250,9 @@ pub unsafe fn NtReadFile(
apccontext: *mut c_void,
iostatusblock: &mut IO_STATUS_BLOCK,
buffer: *mut crate::mem::MaybeUninit<u8>,
length: ULONG,
byteoffset: Option<&LARGE_INTEGER>,
key: Option<&ULONG>,
length: u32,
byteoffset: Option<&i64>,
key: Option<&u32>,
) -> NTSTATUS {
windows_sys::NtReadFile(
filehandle.as_raw_handle(),
@ -294,9 +273,9 @@ pub unsafe fn NtWriteFile(
apccontext: *mut c_void,
iostatusblock: &mut IO_STATUS_BLOCK,
buffer: *const u8,
length: ULONG,
byteoffset: Option<&LARGE_INTEGER>,
key: Option<&ULONG>,
length: u32,
byteoffset: Option<&i64>,
key: Option<&u32>,
) -> NTSTATUS {
windows_sys::NtWriteFile(
filehandle.as_raw_handle(),
@ -336,13 +315,13 @@ compat_fn_with_fallback! {
// >= Win10 1607
// https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setthreaddescription
pub fn SetThreadDescription(hthread: HANDLE, lpthreaddescription: PCWSTR) -> HRESULT {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); E_NOTIMPL
SetLastError(ERROR_CALL_NOT_IMPLEMENTED as u32); E_NOTIMPL
}
// >= Win10 1607
// https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getthreaddescription
pub fn GetThreadDescription(hthread: HANDLE, lpthreaddescription: *mut PWSTR) -> HRESULT {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); E_NOTIMPL
SetLastError(ERROR_CALL_NOT_IMPLEMENTED as u32); E_NOTIMPL
}
// >= Win8 / Server 2012
@ -403,27 +382,27 @@ compat_fn_with_fallback! {
#[cfg(target_vendor = "win7")]
pub fn NtCreateKeyedEvent(
KeyedEventHandle: *mut HANDLE,
DesiredAccess: DWORD,
ObjectAttributes: LPVOID,
Flags: ULONG
DesiredAccess: u32,
ObjectAttributes: *mut c_void,
Flags: u32
) -> NTSTATUS {
panic!("keyed events not available")
}
#[cfg(target_vendor = "win7")]
pub fn NtReleaseKeyedEvent(
EventHandle: HANDLE,
Key: LPVOID,
Key: *const c_void,
Alertable: BOOLEAN,
Timeout: *mut c_longlong
Timeout: *mut i64
) -> NTSTATUS {
panic!("keyed events not available")
}
#[cfg(target_vendor = "win7")]
pub fn NtWaitForKeyedEvent(
EventHandle: HANDLE,
Key: LPVOID,
Key: *const c_void,
Alertable: BOOLEAN,
Timeout: *mut c_longlong
Timeout: *mut i64
) -> NTSTATUS {
panic!("keyed events not available")
}
@ -453,9 +432,9 @@ compat_fn_with_fallback! {
apccontext: *mut c_void,
iostatusblock: &mut IO_STATUS_BLOCK,
buffer: *mut crate::mem::MaybeUninit<u8>,
length: ULONG,
byteoffset: Option<&LARGE_INTEGER>,
key: Option<&ULONG>
length: u32,
byteoffset: Option<&i64>,
key: Option<&u32>
) -> NTSTATUS {
STATUS_NOT_IMPLEMENTED
}
@ -467,9 +446,9 @@ compat_fn_with_fallback! {
apccontext: *mut c_void,
iostatusblock: &mut IO_STATUS_BLOCK,
buffer: *const u8,
length: ULONG,
byteoffset: Option<&LARGE_INTEGER>,
key: Option<&ULONG>
length: u32,
byteoffset: Option<&i64>,
key: Option<&u32>
) -> NTSTATUS {
STATUS_NOT_IMPLEMENTED
}

View file

@ -112,8 +112,10 @@ impl Module {
/// (e.g. kernel32 and ntdll).
pub unsafe fn new(name: &CStr) -> Option<Self> {
// SAFETY: A CStr is always null terminated.
let module = c::GetModuleHandleA(name.as_ptr().cast::<u8>());
NonNull::new(module).map(Self)
unsafe {
let module = c::GetModuleHandleA(name.as_ptr().cast::<u8>());
NonNull::new(module).map(Self)
}
}
// Try to get the address of a function.

View file

@ -1,3 +1,4 @@
#![allow(unsafe_op_in_unsafe_fn)]
use core::ptr::addr_of;
use crate::os::windows::prelude::*;
@ -28,12 +29,12 @@ pub struct File {
#[derive(Clone)]
pub struct FileAttr {
attributes: c::DWORD,
attributes: u32,
creation_time: c::FILETIME,
last_access_time: c::FILETIME,
last_write_time: c::FILETIME,
file_size: u64,
reparse_tag: c::DWORD,
reparse_tag: u32,
volume_serial_number: Option<u32>,
number_of_links: Option<u32>,
file_index: Option<u64>,
@ -41,8 +42,8 @@ pub struct FileAttr {
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub struct FileType {
attributes: c::DWORD,
reparse_tag: c::DWORD,
attributes: u32,
reparse_tag: u32,
}
pub struct ReadDir {
@ -75,16 +76,16 @@ pub struct OpenOptions {
create_new: bool,
// system-specific
custom_flags: u32,
access_mode: Option<c::DWORD>,
attributes: c::DWORD,
share_mode: c::DWORD,
security_qos_flags: c::DWORD,
security_attributes: c::LPSECURITY_ATTRIBUTES,
access_mode: Option<u32>,
attributes: u32,
share_mode: u32,
security_qos_flags: u32,
security_attributes: *mut c::SECURITY_ATTRIBUTES,
}
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct FilePermissions {
attrs: c::DWORD,
attrs: u32,
}
#[derive(Copy, Clone, Debug, Default)]
@ -241,11 +242,11 @@ impl OpenOptions {
// receive is `SECURITY_ANONYMOUS = 0x0`, which we can't check for later on.
self.security_qos_flags = flags | c::SECURITY_SQOS_PRESENT;
}
pub fn security_attributes(&mut self, attrs: c::LPSECURITY_ATTRIBUTES) {
pub fn security_attributes(&mut self, attrs: *mut c::SECURITY_ATTRIBUTES) {
self.security_attributes = attrs;
}
fn get_access_mode(&self) -> io::Result<c::DWORD> {
fn get_access_mode(&self) -> io::Result<u32> {
match (self.read, self.write, self.append, self.access_mode) {
(.., Some(mode)) => Ok(mode),
(true, false, false, None) => Ok(c::GENERIC_READ),
@ -261,7 +262,7 @@ impl OpenOptions {
}
}
fn get_creation_mode(&self) -> io::Result<c::DWORD> {
fn get_creation_mode(&self) -> io::Result<u32> {
match (self.write, self.append) {
(true, false) => {}
(false, false) => {
@ -287,7 +288,7 @@ impl OpenOptions {
})
}
fn get_flags_and_attributes(&self) -> c::DWORD {
fn get_flags_and_attributes(&self) -> u32 {
self.custom_flags
| self.attributes
| self.security_qos_flags
@ -397,21 +398,21 @@ impl File {
self.handle.as_raw_handle(),
c::FileBasicInfo,
core::ptr::addr_of_mut!(info) as *mut c_void,
size as c::DWORD,
size as u32,
))?;
let mut attr = FileAttr {
attributes: info.FileAttributes,
creation_time: c::FILETIME {
dwLowDateTime: info.CreationTime as c::DWORD,
dwHighDateTime: (info.CreationTime >> 32) as c::DWORD,
dwLowDateTime: info.CreationTime as u32,
dwHighDateTime: (info.CreationTime >> 32) as u32,
},
last_access_time: c::FILETIME {
dwLowDateTime: info.LastAccessTime as c::DWORD,
dwHighDateTime: (info.LastAccessTime >> 32) as c::DWORD,
dwLowDateTime: info.LastAccessTime as u32,
dwHighDateTime: (info.LastAccessTime >> 32) as u32,
},
last_write_time: c::FILETIME {
dwLowDateTime: info.LastWriteTime as c::DWORD,
dwHighDateTime: (info.LastWriteTime >> 32) as c::DWORD,
dwLowDateTime: info.LastWriteTime as u32,
dwHighDateTime: (info.LastWriteTime >> 32) as u32,
},
file_size: 0,
reparse_tag: 0,
@ -425,7 +426,7 @@ impl File {
self.handle.as_raw_handle(),
c::FileStandardInfo,
core::ptr::addr_of_mut!(info) as *mut c_void,
size as c::DWORD,
size as u32,
))?;
attr.file_size = info.AllocationSize as u64;
attr.number_of_links = Some(info.NumberOfLinks);
@ -495,7 +496,7 @@ impl File {
SeekFrom::End(n) => (c::FILE_END, n),
SeekFrom::Current(n) => (c::FILE_CURRENT, n),
};
let pos = pos as c::LARGE_INTEGER;
let pos = pos as i64;
let mut newpos = 0;
cvt(unsafe { c::SetFilePointerEx(self.handle.as_raw_handle(), pos, &mut newpos, whence) })?;
Ok(newpos as u64)
@ -511,7 +512,7 @@ impl File {
fn reparse_point(
&self,
space: &mut Align8<[MaybeUninit<u8>]>,
) -> io::Result<(c::DWORD, *mut c::REPARSE_DATA_BUFFER)> {
) -> io::Result<(u32, *mut c::REPARSE_DATA_BUFFER)> {
unsafe {
let mut bytes = 0;
cvt({
@ -524,7 +525,7 @@ impl File {
ptr::null_mut(),
0,
space.0.as_mut_ptr().cast(),
len as c::DWORD,
len as u32,
&mut bytes,
ptr::null_mut(),
)
@ -609,8 +610,7 @@ impl File {
"Cannot set file timestamp to 0",
));
}
let is_max =
|t: c::FILETIME| t.dwLowDateTime == c::DWORD::MAX && t.dwHighDateTime == c::DWORD::MAX;
let is_max = |t: c::FILETIME| t.dwLowDateTime == u32::MAX && t.dwHighDateTime == u32::MAX;
if times.accessed.map_or(false, is_max)
|| times.modified.map_or(false, is_max)
|| times.created.map_or(false, is_max)
@ -641,7 +641,7 @@ impl File {
self.handle.as_raw_handle(),
c::FileBasicInfo,
core::ptr::addr_of_mut!(info) as *mut c_void,
size as c::DWORD,
size as u32,
))?;
Ok(info)
}
@ -1020,7 +1020,7 @@ impl FileTimes {
}
impl FileType {
fn new(attrs: c::DWORD, reparse_tag: c::DWORD) -> FileType {
fn new(attrs: u32, reparse_tag: u32) -> FileType {
FileType { attributes: attrs, reparse_tag }
}
pub fn is_dir(&self) -> bool {
@ -1417,16 +1417,16 @@ pub fn canonicalize(p: &Path) -> io::Result<PathBuf> {
pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
unsafe extern "system" fn callback(
_TotalFileSize: c::LARGE_INTEGER,
_TotalBytesTransferred: c::LARGE_INTEGER,
_StreamSize: c::LARGE_INTEGER,
StreamBytesTransferred: c::LARGE_INTEGER,
dwStreamNumber: c::DWORD,
_dwCallbackReason: c::DWORD,
_TotalFileSize: i64,
_TotalBytesTransferred: i64,
_StreamSize: i64,
StreamBytesTransferred: i64,
dwStreamNumber: u32,
_dwCallbackReason: u32,
_hSourceFile: c::HANDLE,
_hDestinationFile: c::HANDLE,
lpData: c::LPCVOID,
) -> c::DWORD {
lpData: *const c_void,
) -> u32 {
if dwStreamNumber == 1 {
*(lpData as *mut i64) = StreamBytesTransferred;
}

View file

@ -1,4 +1,5 @@
#![unstable(issue = "none", feature = "windows_handle")]
#![allow(unsafe_op_in_unsafe_fn)]
#[cfg(test)]
mod tests;
@ -141,7 +142,7 @@ impl Handle {
buf: &mut [u8],
overlapped: *mut c::OVERLAPPED,
) -> io::Result<Option<usize>> {
let len = cmp::min(buf.len(), <c::DWORD>::MAX as usize) as c::DWORD;
let len = cmp::min(buf.len(), u32::MAX as usize) as u32;
let mut amt = 0;
let res =
cvt(c::ReadFile(self.as_raw_handle(), buf.as_mut_ptr(), len, &mut amt, overlapped));
@ -209,12 +210,7 @@ impl Handle {
Ok(Self(self.0.try_clone()?))
}
pub fn duplicate(
&self,
access: c::DWORD,
inherit: bool,
options: c::DWORD,
) -> io::Result<Self> {
pub fn duplicate(&self, access: u32, inherit: bool, options: u32) -> io::Result<Self> {
Ok(Self(self.0.as_handle().duplicate(access, inherit, options)?))
}
@ -233,7 +229,7 @@ impl Handle {
let mut io_status = c::IO_STATUS_BLOCK::PENDING;
// The length is clamped at u32::MAX.
let len = cmp::min(len, c::DWORD::MAX as usize) as c::DWORD;
let len = cmp::min(len, u32::MAX as usize) as u32;
let status = c::NtReadFile(
self.as_handle(),
ptr::null_mut(),
@ -281,7 +277,7 @@ impl Handle {
let mut io_status = c::IO_STATUS_BLOCK::PENDING;
// The length is clamped at u32::MAX.
let len = cmp::min(buf.len(), c::DWORD::MAX as usize) as c::DWORD;
let len = cmp::min(buf.len(), u32::MAX as usize) as u32;
let status = unsafe {
c::NtWriteFile(
self.as_handle(),

View file

@ -1,3 +1,4 @@
#![allow(unsafe_op_in_unsafe_fn)]
use crate::marker::PhantomData;
use crate::mem::size_of;
use crate::os::windows::io::{AsHandle, AsRawHandle, BorrowedHandle};
@ -15,9 +16,9 @@ pub struct IoSlice<'a> {
impl<'a> IoSlice<'a> {
#[inline]
pub fn new(buf: &'a [u8]) -> IoSlice<'a> {
assert!(buf.len() <= c::ULONG::MAX as usize);
assert!(buf.len() <= u32::MAX as usize);
IoSlice {
vec: c::WSABUF { len: buf.len() as c::ULONG, buf: buf.as_ptr() as *mut u8 },
vec: c::WSABUF { len: buf.len() as u32, buf: buf.as_ptr() as *mut u8 },
_p: PhantomData,
}
}
@ -29,7 +30,7 @@ impl<'a> IoSlice<'a> {
}
unsafe {
self.vec.len -= n as c::ULONG;
self.vec.len -= n as u32;
self.vec.buf = self.vec.buf.add(n);
}
}
@ -49,9 +50,9 @@ pub struct IoSliceMut<'a> {
impl<'a> IoSliceMut<'a> {
#[inline]
pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> {
assert!(buf.len() <= c::ULONG::MAX as usize);
assert!(buf.len() <= u32::MAX as usize);
IoSliceMut {
vec: c::WSABUF { len: buf.len() as c::ULONG, buf: buf.as_mut_ptr() },
vec: c::WSABUF { len: buf.len() as u32, buf: buf.as_mut_ptr() },
_p: PhantomData,
}
}
@ -63,7 +64,7 @@ impl<'a> IoSliceMut<'a> {
}
unsafe {
self.vec.len -= n as c::ULONG;
self.vec.len -= n as u32;
self.vec.buf = self.vec.buf.add(n);
}
}

View file

@ -1,4 +1,5 @@
#![allow(missing_docs, nonstandard_style)]
#![deny(unsafe_op_in_unsafe_fn)]
use crate::ffi::{OsStr, OsString};
use crate::io::ErrorKind;
@ -54,11 +55,13 @@ impl<T> IoResult<T> for Result<T, api::WinError> {
// SAFETY: must be called only once during runtime initialization.
// NOTE: this is not guaranteed to run, for example when Rust code is called externally.
pub unsafe fn init(_argc: isize, _argv: *const *const u8, _sigpipe: u8) {
stack_overflow::init();
unsafe {
stack_overflow::init();
// Normally, `thread::spawn` will call `Thread::set_name` but since this thread already
// exists, we have to call it ourselves.
thread::Thread::set_name_wide(wide_str!("main"));
// Normally, `thread::spawn` will call `Thread::set_name` but since this thread already
// exists, we have to call it ourselves.
thread::Thread::set_name_wide(wide_str!("main"));
}
}
// SAFETY: must be called only once during runtime cleanup.
@ -75,7 +78,7 @@ pub fn is_interrupted(_errno: i32) -> bool {
pub fn decode_error_kind(errno: i32) -> ErrorKind {
use ErrorKind::*;
match errno as c::DWORD {
match errno as u32 {
c::ERROR_ACCESS_DENIED => return PermissionDenied,
c::ERROR_ALREADY_EXISTS => return AlreadyExists,
c::ERROR_FILE_EXISTS => return AlreadyExists,
@ -216,7 +219,7 @@ pub fn to_u16s<S: AsRef<OsStr>>(s: S) -> crate::io::Result<Vec<u16>> {
// from this closure is then the return value of the function.
pub fn fill_utf16_buf<F1, F2, T>(mut f1: F1, f2: F2) -> crate::io::Result<T>
where
F1: FnMut(*mut u16, c::DWORD) -> c::DWORD,
F1: FnMut(*mut u16, u32) -> u32,
F2: FnOnce(&[u16]) -> T,
{
// Start off with a stack buf but then spill over to the heap if we end up
@ -238,7 +241,7 @@ where
// We used `reserve` and not `reserve_exact`, so in theory we
// may have gotten more than requested. If so, we'd like to use
// it... so long as we won't cause overflow.
n = heap_buf.capacity().min(c::DWORD::MAX as usize);
n = heap_buf.capacity().min(u32::MAX as usize);
// Safety: MaybeUninit<u16> does not need initialization
heap_buf.set_len(n);
&mut heap_buf[..]
@ -254,13 +257,13 @@ where
// error" is still 0 then we interpret it as a 0 length buffer and
// not an actual error.
c::SetLastError(0);
let k = match f1(buf.as_mut_ptr().cast::<u16>(), n as c::DWORD) {
let k = match f1(buf.as_mut_ptr().cast::<u16>(), n as u32) {
0 if api::get_last_error().code == 0 => 0,
0 => return Err(crate::io::Error::last_os_error()),
n => n,
} as usize;
if k == n && api::get_last_error().code == c::ERROR_INSUFFICIENT_BUFFER {
n = n.saturating_mul(2).min(c::DWORD::MAX as usize);
n = n.saturating_mul(2).min(u32::MAX as usize);
} else if k > n {
n = k;
} else if k == n {
@ -308,7 +311,7 @@ pub fn cvt<I: IsZero>(i: I) -> crate::io::Result<I> {
if i.is_zero() { Err(crate::io::Error::last_os_error()) } else { Ok(i) }
}
pub fn dur2timeout(dur: Duration) -> c::DWORD {
pub fn dur2timeout(dur: Duration) -> u32 {
// Note that a duration is a (u64, u32) (seconds, nanoseconds) pair, and the
// timeouts in windows APIs are typically u32 milliseconds. To translate, we
// have two pieces to take care of:
@ -320,7 +323,7 @@ pub fn dur2timeout(dur: Duration) -> c::DWORD {
.checked_mul(1000)
.and_then(|ms| ms.checked_add((dur.subsec_nanos() as u64) / 1_000_000))
.and_then(|ms| ms.checked_add(if dur.subsec_nanos() % 1_000_000 > 0 { 1 } else { 0 }))
.map(|ms| if ms > <c::DWORD>::MAX as u64 { c::INFINITE } else { ms as c::DWORD })
.map(|ms| if ms > <u32>::MAX as u64 { c::INFINITE } else { ms as u32 })
.unwrap_or(c::INFINITE)
}

View file

@ -250,7 +250,7 @@ impl Socket {
pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
// On unix when a socket is shut down all further reads return 0, so we
// do the same on windows to map a shut down socket to returning EOF.
let length = cmp::min(bufs.len(), c::DWORD::MAX as usize) as c::DWORD;
let length = cmp::min(bufs.len(), u32::MAX as usize) as u32;
let mut nread = 0;
let mut flags = 0;
let result = unsafe {
@ -335,7 +335,7 @@ impl Socket {
}
pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
let length = cmp::min(bufs.len(), c::DWORD::MAX as usize) as c::DWORD;
let length = cmp::min(bufs.len(), u32::MAX as usize) as u32;
let mut nwritten = 0;
let result = unsafe {
c::WSASend(
@ -371,7 +371,7 @@ impl Socket {
}
pub fn timeout(&self, kind: c_int) -> io::Result<Option<Duration>> {
let raw: c::DWORD = net::getsockopt(self, c::SOL_SOCKET, kind)?;
let raw: u32 = net::getsockopt(self, c::SOL_SOCKET, kind)?;
if raw == 0 {
Ok(None)
} else {
@ -436,7 +436,7 @@ impl Socket {
pub unsafe fn from_raw(raw: c::SOCKET) -> Self {
debug_assert_eq!(mem::size_of::<c::SOCKET>(), mem::size_of::<RawSocket>());
debug_assert_eq!(mem::align_of::<c::SOCKET>(), mem::align_of::<RawSocket>());
Self::from_raw_socket(raw as RawSocket)
unsafe { Self::from_raw_socket(raw as RawSocket) }
}
}
@ -486,6 +486,6 @@ impl IntoRawSocket for Socket {
impl FromRawSocket for Socket {
unsafe fn from_raw_socket(raw_socket: RawSocket) -> Self {
Self(FromRawSocket::from_raw_socket(raw_socket))
unsafe { Self(FromRawSocket::from_raw_socket(raw_socket)) }
}
}

View file

@ -1,6 +1,7 @@
//! Implementation of `std::os` functionality for Windows.
#![allow(nonstandard_style)]
#![allow(unsafe_op_in_unsafe_fn)]
#[cfg(test)]
mod tests;
@ -52,10 +53,10 @@ pub fn error_string(mut errnum: i32) -> String {
let res = c::FormatMessageW(
flags | c::FORMAT_MESSAGE_FROM_SYSTEM | c::FORMAT_MESSAGE_IGNORE_INSERTS,
module,
errnum as c::DWORD,
errnum as u32,
0,
buf.as_mut_ptr(),
buf.len() as c::DWORD,
buf.len() as u32,
ptr::null(),
) as usize;
if res == 0 {
@ -81,7 +82,7 @@ pub fn error_string(mut errnum: i32) -> String {
}
pub struct Env {
base: c::LPWCH,
base: *mut c::WCHAR,
iter: EnvIterator,
}
@ -126,7 +127,7 @@ impl Iterator for Env {
}
#[derive(Clone)]
struct EnvIterator(c::LPWCH);
struct EnvIterator(*mut c::WCHAR);
impl Iterator for EnvIterator {
type Item = (OsString, OsString);
@ -383,7 +384,7 @@ pub fn home_dir() -> Option<PathBuf> {
}
pub fn exit(code: i32) -> ! {
unsafe { c::ExitProcess(code as c::UINT) }
unsafe { c::ExitProcess(code as u32) }
}
pub fn getpid() -> u32 {

View file

@ -1,3 +1,4 @@
#![allow(unsafe_op_in_unsafe_fn)]
use crate::os::windows::prelude::*;
use crate::ffi::OsStr;
@ -156,7 +157,7 @@ pub fn anon_pipe(ours_readable: bool, their_handle_inheritable: bool) -> io::Res
opts.share_mode(0);
let size = mem::size_of::<c::SECURITY_ATTRIBUTES>();
let mut sa = c::SECURITY_ATTRIBUTES {
nLength: size as c::DWORD,
nLength: size as u32,
lpSecurityDescriptor: ptr::null_mut(),
bInheritHandle: their_handle_inheritable as i32,
};
@ -225,9 +226,9 @@ fn random_number() -> usize {
// Abstracts over `ReadFileEx` and `WriteFileEx`
type AlertableIoFn = unsafe extern "system" fn(
BorrowedHandle<'_>,
c::LPVOID,
c::DWORD,
c::LPOVERLAPPED,
*mut core::ffi::c_void,
u32,
*mut c::OVERLAPPED,
c::LPOVERLAPPED_COMPLETION_ROUTINE,
) -> c::BOOL;
@ -244,7 +245,7 @@ impl AnonPipe {
pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
let result = unsafe {
let len = crate::cmp::min(buf.len(), c::DWORD::MAX as usize) as c::DWORD;
let len = crate::cmp::min(buf.len(), u32::MAX as usize) as u32;
self.alertable_io_internal(c::ReadFileEx, buf.as_mut_ptr() as _, len)
};
@ -260,7 +261,7 @@ impl AnonPipe {
pub fn read_buf(&self, mut buf: BorrowedCursor<'_>) -> io::Result<()> {
let result = unsafe {
let len = crate::cmp::min(buf.capacity(), c::DWORD::MAX as usize) as c::DWORD;
let len = crate::cmp::min(buf.capacity(), u32::MAX as usize) as u32;
self.alertable_io_internal(c::ReadFileEx, buf.as_mut().as_mut_ptr() as _, len)
};
@ -295,7 +296,7 @@ impl AnonPipe {
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
unsafe {
let len = crate::cmp::min(buf.len(), c::DWORD::MAX as usize) as c::DWORD;
let len = crate::cmp::min(buf.len(), u32::MAX as usize) as u32;
self.alertable_io_internal(c::WriteFileEx, buf.as_ptr() as _, len)
}
}
@ -327,8 +328,8 @@ impl AnonPipe {
unsafe fn alertable_io_internal(
&self,
io: AlertableIoFn,
buf: c::LPVOID,
len: c::DWORD,
buf: *mut core::ffi::c_void,
len: u32,
) -> io::Result<usize> {
// Use "alertable I/O" to synchronize the pipe I/O.
// This has four steps.

View file

@ -19,7 +19,7 @@ use crate::path::{Path, PathBuf};
use crate::ptr;
use crate::sync::Mutex;
use crate::sys::args::{self, Arg};
use crate::sys::c::{self, NonZeroDWORD, EXIT_FAILURE, EXIT_SUCCESS};
use crate::sys::c::{self, EXIT_FAILURE, EXIT_SUCCESS};
use crate::sys::cvt;
use crate::sys::fs::{File, OpenOptions};
use crate::sys::handle::Handle;
@ -174,7 +174,7 @@ pub struct Command {
pub enum Stdio {
Inherit,
InheritSpecific { from_stdio_id: c::DWORD },
InheritSpecific { from_stdio_id: u32 },
Null,
MakePipe,
Pipe(AnonPipe),
@ -364,7 +364,7 @@ impl Command {
};
si_ptr = core::ptr::addr_of_mut!(si_ex) as _;
} else {
si.cb = mem::size_of::<c::STARTUPINFOW>() as c::DWORD;
si.cb = mem::size_of::<c::STARTUPINFOW>() as u32;
si_ptr = core::ptr::addr_of_mut!(si) as _;
}
@ -566,7 +566,7 @@ fn program_exists(path: &Path) -> Option<Vec<u16>> {
}
impl Stdio {
fn to_handle(&self, stdio_id: c::DWORD, pipe: &mut Option<AnonPipe>) -> io::Result<Handle> {
fn to_handle(&self, stdio_id: u32, pipe: &mut Option<AnonPipe>) -> io::Result<Handle> {
let use_stdio_id = |stdio_id| match stdio::get_handle(stdio_id) {
Ok(io) => unsafe {
let io = Handle::from_raw_handle(io);
@ -601,7 +601,7 @@ impl Stdio {
Stdio::Null => {
let size = mem::size_of::<c::SECURITY_ATTRIBUTES>();
let mut sa = c::SECURITY_ATTRIBUTES {
nLength: size as c::DWORD,
nLength: size as u32,
lpSecurityDescriptor: ptr::null_mut(),
bInheritHandle: 1,
};
@ -713,11 +713,11 @@ impl Process {
}
#[derive(PartialEq, Eq, Clone, Copy, Debug, Default)]
pub struct ExitStatus(c::DWORD);
pub struct ExitStatus(u32);
impl ExitStatus {
pub fn exit_ok(&self) -> Result<(), ExitStatusError> {
match NonZeroDWORD::try_from(self.0) {
match NonZero::<u32>::try_from(self.0) {
/* was nonzero */ Ok(failure) => Err(ExitStatusError(failure)),
/* was zero, couldn't convert */ Err(_) => Ok(()),
}
@ -727,9 +727,9 @@ impl ExitStatus {
}
}
/// Converts a raw `c::DWORD` to a type-safe `ExitStatus` by wrapping it without copying.
impl From<c::DWORD> for ExitStatus {
fn from(u: c::DWORD) -> ExitStatus {
/// Converts a raw `u32` to a type-safe `ExitStatus` by wrapping it without copying.
impl From<u32> for ExitStatus {
fn from(u: u32) -> ExitStatus {
ExitStatus(u)
}
}
@ -750,7 +750,7 @@ impl fmt::Display for ExitStatus {
}
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub struct ExitStatusError(c::NonZeroDWORD);
pub struct ExitStatusError(NonZero<u32>);
impl Into<ExitStatus> for ExitStatusError {
fn into(self) -> ExitStatus {
@ -765,7 +765,7 @@ impl ExitStatusError {
}
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub struct ExitCode(c::DWORD);
pub struct ExitCode(u32);
impl ExitCode {
pub const SUCCESS: ExitCode = ExitCode(EXIT_SUCCESS as _);
@ -779,13 +779,13 @@ impl ExitCode {
impl From<u8> for ExitCode {
fn from(code: u8) -> Self {
ExitCode(c::DWORD::from(code))
ExitCode(u32::from(code))
}
}
impl From<u32> for ExitCode {
fn from(code: u32) -> Self {
ExitCode(c::DWORD::from(code))
ExitCode(u32::from(code))
}
}

View file

@ -20,7 +20,7 @@ pub fn hashmap_random_keys() -> (u64, u64) {
let mut v = (0, 0);
let ret = unsafe {
c::RtlGenRandom(ptr::addr_of_mut!(v).cast::<c_void>(), mem::size_of_val(&v) as c::ULONG)
c::RtlGenRandom(ptr::addr_of_mut!(v).cast::<c_void>(), mem::size_of_val(&v) as u32)
};
if ret != 0 { v } else { panic!("RNG broken: {}", io::Error::last_os_error()) }

View file

@ -1,4 +1,5 @@
#![cfg_attr(test, allow(dead_code))]
#![allow(unsafe_op_in_unsafe_fn)]
use crate::sys::c;
use crate::thread;
@ -11,7 +12,7 @@ pub unsafe fn reserve_stack() {
debug_assert_ne!(result, 0, "failed to reserve stack space for exception handling");
}
unsafe extern "system" fn vectored_handler(ExceptionInfo: *mut c::EXCEPTION_POINTERS) -> c::LONG {
unsafe extern "system" fn vectored_handler(ExceptionInfo: *mut c::EXCEPTION_POINTERS) -> i32 {
unsafe {
let rec = &(*(*ExceptionInfo).ExceptionRecord);
let code = rec.ExceptionCode;

View file

@ -68,7 +68,7 @@ const MAX_BUFFER_SIZE: usize = 8192;
// UTF-16 to UTF-8.
pub const STDIN_BUF_SIZE: usize = MAX_BUFFER_SIZE / 2 * 3;
pub fn get_handle(handle_id: c::DWORD) -> io::Result<c::HANDLE> {
pub fn get_handle(handle_id: u32) -> io::Result<c::HANDLE> {
let handle = unsafe { c::GetStdHandle(handle_id) };
if handle == c::INVALID_HANDLE_VALUE {
Err(io::Error::last_os_error())
@ -87,11 +87,7 @@ fn is_console(handle: c::HANDLE) -> bool {
unsafe { c::GetConsoleMode(handle, &mut mode) != 0 }
}
fn write(
handle_id: c::DWORD,
data: &[u8],
incomplete_utf8: &mut IncompleteUtf8,
) -> io::Result<usize> {
fn write(handle_id: u32, data: &[u8], incomplete_utf8: &mut IncompleteUtf8) -> io::Result<usize> {
if data.is_empty() {
return Ok(0);
}
@ -182,12 +178,12 @@ fn write_valid_utf8_to_console(handle: c::HANDLE, utf8: &str) -> io::Result<usiz
// Note that this theoretically checks validity twice in the (most common) case
// where the underlying byte sequence is valid utf-8 (given the check in `write()`).
let result = c::MultiByteToWideChar(
c::CP_UTF8, // CodePage
c::MB_ERR_INVALID_CHARS, // dwFlags
utf8.as_ptr(), // lpMultiByteStr
utf8.len() as c::c_int, // cbMultiByte
utf16.as_mut_ptr() as c::LPWSTR, // lpWideCharStr
utf16.len() as c::c_int, // cchWideChar
c::CP_UTF8, // CodePage
c::MB_ERR_INVALID_CHARS, // dwFlags
utf8.as_ptr(), // lpMultiByteStr
utf8.len() as i32, // cbMultiByte
utf16.as_mut_ptr() as *mut c::WCHAR, // lpWideCharStr
utf16.len() as i32, // cchWideChar
);
assert!(result != 0, "Unexpected error in MultiByteToWideChar");
@ -341,9 +337,9 @@ fn read_u16s(handle: c::HANDLE, buf: &mut [MaybeUninit<u16>]) -> io::Result<usiz
// traditional DOS method to indicate end of character stream / user input (SUB).
// See #38274 and https://stackoverflow.com/questions/43836040/win-api-readconsole.
const CTRL_Z: u16 = 0x1A;
const CTRL_Z_MASK: c::ULONG = 1 << CTRL_Z;
const CTRL_Z_MASK: u32 = 1 << CTRL_Z;
let input_control = c::CONSOLE_READCONSOLE_CONTROL {
nLength: crate::mem::size_of::<c::CONSOLE_READCONSOLE_CONTROL>() as c::ULONG,
nLength: crate::mem::size_of::<c::CONSOLE_READCONSOLE_CONTROL>() as u32,
nInitialChars: 0,
dwCtrlWakeupMask: CTRL_Z_MASK,
dwControlKeyState: 0,
@ -355,7 +351,7 @@ fn read_u16s(handle: c::HANDLE, buf: &mut [MaybeUninit<u16>]) -> io::Result<usiz
c::SetLastError(0);
c::ReadConsoleW(
handle,
buf.as_mut_ptr() as c::LPVOID,
buf.as_mut_ptr() as *mut core::ffi::c_void,
buf.len() as u32,
&mut amount,
&input_control,
@ -378,8 +374,8 @@ fn read_u16s(handle: c::HANDLE, buf: &mut [MaybeUninit<u16>]) -> io::Result<usiz
}
fn utf16_to_utf8(utf16: &[u16], utf8: &mut [u8]) -> io::Result<usize> {
debug_assert!(utf16.len() <= c::c_int::MAX as usize);
debug_assert!(utf8.len() <= c::c_int::MAX as usize);
debug_assert!(utf16.len() <= i32::MAX as usize);
debug_assert!(utf8.len() <= i32::MAX as usize);
if utf16.is_empty() {
return Ok(0);
@ -390,9 +386,9 @@ fn utf16_to_utf8(utf16: &[u16], utf8: &mut [u8]) -> io::Result<usize> {
c::CP_UTF8, // CodePage
c::WC_ERR_INVALID_CHARS, // dwFlags
utf16.as_ptr(), // lpWideCharStr
utf16.len() as c::c_int, // cchWideChar
utf16.len() as i32, // cchWideChar
utf8.as_mut_ptr(), // lpMultiByteStr
utf8.len() as c::c_int, // cbMultiByte
utf8.len() as i32, // cbMultiByte
ptr::null(), // lpDefaultChar
ptr::null_mut(), // lpUsedDefaultChar
)

View file

@ -1,3 +1,4 @@
#![allow(unsafe_op_in_unsafe_fn)]
use crate::ffi::CStr;
use crate::io;
use crate::num::NonZero;
@ -45,7 +46,7 @@ impl Thread {
Err(io::Error::last_os_error())
};
unsafe extern "system" fn thread_start(main: *mut c_void) -> c::DWORD {
unsafe extern "system" fn thread_start(main: *mut c_void) -> u32 {
// Next, reserve some stack space for if we otherwise run out of stack.
stack_overflow::reserve_stack();
// Finally, let's run some code.

View file

@ -76,8 +76,8 @@ impl SystemTime {
fn from_intervals(intervals: i64) -> SystemTime {
SystemTime {
t: c::FILETIME {
dwLowDateTime: intervals as c::DWORD,
dwHighDateTime: (intervals >> 32) as c::DWORD,
dwLowDateTime: intervals as u32,
dwHighDateTime: (intervals >> 32) as u32,
},
}
}
@ -172,7 +172,7 @@ mod perf_counter {
use crate::time::Duration;
pub struct PerformanceCounterInstant {
ts: c::LARGE_INTEGER,
ts: i64,
}
impl PerformanceCounterInstant {
pub fn now() -> Self {
@ -196,7 +196,7 @@ mod perf_counter {
}
}
fn frequency() -> c::LARGE_INTEGER {
fn frequency() -> i64 {
// Either the cached result of `QueryPerformanceFrequency` or `0` for
// uninitialized. Storing this as a single `AtomicU64` allows us to use
// `Relaxed` operations, as we are only interested in the effects on a
@ -206,7 +206,7 @@ mod perf_counter {
let cached = FREQUENCY.load(Ordering::Relaxed);
// If a previous thread has filled in this global state, use that.
if cached != 0 {
return cached as c::LARGE_INTEGER;
return cached as i64;
}
// ... otherwise learn for ourselves ...
let mut frequency = 0;
@ -218,8 +218,8 @@ mod perf_counter {
frequency
}
fn query() -> c::LARGE_INTEGER {
let mut qpc_value: c::LARGE_INTEGER = 0;
fn query() -> i64 {
let mut qpc_value: i64 = 0;
cvt(unsafe { c::QueryPerformanceCounter(&mut qpc_value) }).unwrap();
qpc_value
}

View file

@ -25,7 +25,7 @@ unsafe impl Send for Mutex {}
unsafe impl Sync for Mutex {}
#[inline]
pub unsafe fn raw(m: &Mutex) -> c::PSRWLOCK {
pub unsafe fn raw(m: &Mutex) -> *mut c::SRWLOCK {
m.srwlock.get()
}

View file

@ -64,6 +64,7 @@ use crate::sync::atomic::{
};
use crate::sys::{c, dur2timeout};
use crate::time::Duration;
use core::ffi::c_void;
pub struct Parker {
state: AtomicI8,
@ -117,7 +118,7 @@ impl Parker {
loop {
// Wait for something to happen, assuming it's still set to PARKED.
c::WaitOnAddress(self.ptr(), &PARKED as *const _ as c::LPVOID, 1, c::INFINITE);
c::WaitOnAddress(self.ptr(), &PARKED as *const _ as *const c_void, 1, c::INFINITE);
// Change NOTIFIED=>EMPTY but leave PARKED alone.
if self.state.compare_exchange(NOTIFIED, EMPTY, Acquire, Acquire).is_ok() {
// Actually woken up by unpark().
@ -144,7 +145,7 @@ impl Parker {
}
// Wait for something to happen, assuming it's still set to PARKED.
c::WaitOnAddress(self.ptr(), &PARKED as *const _ as c::LPVOID, 1, dur2timeout(timeout));
c::WaitOnAddress(self.ptr(), &PARKED as *const _ as *const c_void, 1, dur2timeout(timeout));
// Set the state back to EMPTY (from either PARKED or NOTIFIED).
// Note that we don't just write EMPTY, but use swap() to also
// include an acquire-ordered read to synchronize with unpark()'s
@ -177,8 +178,8 @@ impl Parker {
}
}
fn ptr(&self) -> c::LPVOID {
core::ptr::addr_of!(self.state) as c::LPVOID
fn ptr(&self) -> *const c_void {
core::ptr::addr_of!(self.state).cast::<c_void>()
}
}

View file

@ -65,6 +65,7 @@
use crate::ptr;
use crate::sys::c;
use core::ffi::c_void;
pub fn enable() {
// When destructors are used, we don't want LLVM eliminating CALLBACK for any
@ -74,9 +75,9 @@ pub fn enable() {
#[link_section = ".CRT$XLB"]
#[cfg_attr(miri, used)] // Miri only considers explicitly `#[used]` statics for `lookup_link_section`
pub static CALLBACK: unsafe extern "system" fn(c::LPVOID, c::DWORD, c::LPVOID) = tls_callback;
pub static CALLBACK: unsafe extern "system" fn(*mut c_void, u32, *mut c_void) = tls_callback;
unsafe extern "system" fn tls_callback(_h: c::LPVOID, dw_reason: c::DWORD, _pv: c::LPVOID) {
unsafe extern "system" fn tls_callback(_h: *mut c_void, dw_reason: u32, _pv: *mut c_void) {
// See comments above for what this is doing. Note that we don't need this
// trickery on GNU windows, just on MSVC.
#[cfg(all(target_env = "msvc", not(target_thread_local)))]

View file

@ -33,11 +33,11 @@ use crate::sync::atomic::{
use crate::sys::c;
use crate::sys::thread_local::guard;
pub type Key = c::DWORD;
pub type Key = u32;
type Dtor = unsafe extern "C" fn(*mut u8);
pub struct LazyKey {
/// The key value shifted up by one. Since TLS_OUT_OF_INDEXES == DWORD::MAX
/// The key value shifted up by one. Since TLS_OUT_OF_INDEXES == u32::MAX
/// is not a valid key value, this allows us to use zero as sentinel value
/// without risking overflow.
key: AtomicU32,

View file

@ -602,7 +602,8 @@ impl Wtf8 {
/// marked unsafe.
#[inline]
pub unsafe fn from_bytes_unchecked(value: &[u8]) -> &Wtf8 {
mem::transmute(value)
// SAFETY: start with &[u8], end with fancy &[u8]
unsafe { &*(value as *const [u8] as *const Wtf8) }
}
/// Creates a mutable WTF-8 slice from a mutable WTF-8 byte slice.
@ -611,7 +612,8 @@ impl Wtf8 {
/// marked unsafe.
#[inline]
unsafe fn from_mut_bytes_unchecked(value: &mut [u8]) -> &mut Wtf8 {
mem::transmute(value)
// SAFETY: start with &mut [u8], end with fancy &mut [u8]
unsafe { &mut *(value as *mut [u8] as *mut Wtf8) }
}
/// Returns the length, in WTF-8 bytes.
@ -942,8 +944,12 @@ pub fn check_utf8_boundary(slice: &Wtf8, index: usize) {
/// Copied from core::str::raw::slice_unchecked
#[inline]
pub unsafe fn slice_unchecked(s: &Wtf8, begin: usize, end: usize) -> &Wtf8 {
// memory layout of a &[u8] and &Wtf8 are the same
Wtf8::from_bytes_unchecked(slice::from_raw_parts(s.bytes.as_ptr().add(begin), end - begin))
// SAFETY: memory layout of a &[u8] and &Wtf8 are the same
unsafe {
let len = end - begin;
let start = s.as_bytes().as_ptr().add(begin);
Wtf8::from_bytes_unchecked(slice::from_raw_parts(start, len))
}
}
/// Copied from core::str::raw::slice_error_fail

View file

@ -4,7 +4,7 @@
//@normalize-stderr-test: "using [A-Za-z]+ heap deallocation operation" -> "using PLATFORM heap deallocation operation"
//@normalize-stderr-test: "\| +\^+" -> "| ^"
//@normalize-stderr-test: "libc::free\([^()]*\)|unsafe \{ HeapFree\([^()]*\) \};" -> "FREE();"
//@normalize-stderr-test: "libc::free\([^()]*\)|unsafe \{ HeapFree\([^}]*\};" -> "FREE();"
#![feature(allocator_api, slice_ptr_get)]