diff --git a/crates/cargo-util/src/read2.rs b/crates/cargo-util/src/read2.rs index 8c2e070db4b..447c53482fe 100644 --- a/crates/cargo-util/src/read2.rs +++ b/crates/cargo-util/src/read2.rs @@ -141,17 +141,21 @@ mod imp { impl<'a> Pipe<'a> { unsafe fn new(p: P, dst: &'a mut Vec) -> Pipe<'a> { + // SAFETY: Handle must be owned, open, and closeable with CloseHandle. + let pipe = unsafe { NamedPipe::from_raw_handle(p.into_raw_handle()) }; Pipe { dst, - pipe: NamedPipe::from_raw_handle(p.into_raw_handle()), + pipe, overlapped: Overlapped::zero(), done: false, } } unsafe fn read(&mut self) -> io::Result<()> { - let dst = slice_to_end(self.dst); - match self.pipe.read_overlapped(dst, self.overlapped.raw()) { + let dst = unsafe { slice_to_end(self.dst) }; + // SAFETY: The buffer must be valid until the end of the I/O, + // which is handled in `read2`. + match unsafe { self.pipe.read_overlapped(dst, self.overlapped.raw()) } { Ok(_) => Ok(()), Err(e) => { if e.raw_os_error() == Some(ERROR_BROKEN_PIPE as i32) { @@ -166,7 +170,7 @@ mod imp { unsafe fn complete(&mut self, status: &CompletionStatus) { let prev = self.dst.len(); - self.dst.set_len(prev + status.bytes_transferred() as usize); + unsafe { self.dst.set_len(prev + status.bytes_transferred() as usize) }; if status.bytes_transferred() == 0 { self.done = true; } @@ -180,6 +184,6 @@ mod imp { if v.capacity() == v.len() { v.reserve(1); } - slice::from_raw_parts_mut(v.as_mut_ptr().add(v.len()), v.capacity() - v.len()) + unsafe { slice::from_raw_parts_mut(v.as_mut_ptr().add(v.len()), v.capacity() - v.len()) } } } diff --git a/src/cargo/util/job.rs b/src/cargo/util/job.rs index 23a070633a2..233ddaa66d3 100644 --- a/src/cargo/util/job.rs +++ b/src/cargo/util/job.rs @@ -87,7 +87,7 @@ mod imp { // use job objects, so we instead just ignore errors and assume that // we're otherwise part of someone else's job object in this case. - let job = CreateJobObjectW(ptr::null_mut(), ptr::null()); + let job = unsafe { CreateJobObjectW(ptr::null_mut(), ptr::null()) }; if job == INVALID_HANDLE_VALUE { return None; } @@ -98,22 +98,24 @@ mod imp { // entire process tree by default because we've added ourselves and // our children will reside in the job once we spawn a process. let mut info: JOBOBJECT_EXTENDED_LIMIT_INFORMATION; - info = mem::zeroed(); + info = unsafe { mem::zeroed() }; info.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; - let r = SetInformationJobObject( - job.inner, - JobObjectExtendedLimitInformation, - addr_of!(info) as *const _, - mem::size_of_val(&info) as u32, - ); + let r = unsafe { + SetInformationJobObject( + job.inner, + JobObjectExtendedLimitInformation, + addr_of!(info) as *const _, + mem::size_of_val(&info) as u32, + ) + }; if r == 0 { return None; } // Assign our process to this job object, meaning that our children will // now live or die based on our existence. - let me = GetCurrentProcess(); - let r = AssignProcessToJobObject(job.inner, me); + let me = unsafe { GetCurrentProcess() }; + let r = unsafe { AssignProcessToJobObject(job.inner, me) }; if r == 0 { return None; }