зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1785002 - Update memmap2 to 0.5.7. r=emilio,supply-chain-reviewers
Differential Revision: https://phabricator.services.mozilla.com/D154733
This commit is contained in:
Родитель
15ba8b1b3d
Коммит
2bf2b3dec1
|
@ -332,7 +332,7 @@ dependencies = [
|
|||
"iovec",
|
||||
"libc",
|
||||
"log",
|
||||
"memmap2 0.5.4",
|
||||
"memmap2 0.5.7",
|
||||
"mio 0.8.0",
|
||||
"scopeguard",
|
||||
"serde",
|
||||
|
@ -3179,14 +3179,14 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
|||
name = "memmap2"
|
||||
version = "0.2.999"
|
||||
dependencies = [
|
||||
"memmap2 0.5.4",
|
||||
"memmap2 0.5.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memmap2"
|
||||
version = "0.5.4"
|
||||
version = "0.5.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d5172b50c23043ff43dd53e51392f36519d9b35a8f3a410d30ece5d1aedd58ae"
|
||||
checksum = "95af15f345b17af2efc8ead6080fb8bc376f8cec1b35277b935637595fe77498"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
@ -4195,7 +4195,7 @@ dependencies = [
|
|||
name = "profiler_helper"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"memmap2 0.5.4",
|
||||
"memmap2 0.5.7",
|
||||
"object",
|
||||
"rustc-demangle",
|
||||
"thin-vec",
|
||||
|
|
|
@ -435,6 +435,11 @@ criteria = "safe-to-deploy"
|
|||
version = "0.1.9"
|
||||
notes = "This is a trivial crate."
|
||||
|
||||
[[audits.memmap2]]
|
||||
who = "Mike Hommey <mh+mozilla@glandium.org>"
|
||||
criteria = "safe-to-deploy"
|
||||
delta = "0.5.4 -> 0.5.7"
|
||||
|
||||
[[audits.naga]]
|
||||
who = "Dzmitry Malyshau <kvark@fastmail.com>"
|
||||
criteria = "safe-to-deploy"
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"files":{"CHANGELOG.md":"9a280d0719b9d9a1fb12d31a2da544d103cb15f01ee2cf40bdcf28c6484eb1b8","Cargo.lock":"47b6feef3907ecbd586b49aadff92eaf84695d7508214210978fbf58b4f00ab6","Cargo.toml":"b93bec2a5377b79002ab53089a9ea9c0a8107f25c1dfb796ba0c01a50e7a1dec","LICENSE-APACHE":"04ea4849dba9dcae07113850c6f1b1a69052c625210639914eee352023f750ad","LICENSE-MIT":"0d25d03b5ab49576178ad0cae7a2648d12c17ad0452fe49c07e55e4b59aa5257","README.md":"c7b3cd928f0d1a10faa255e2f84a2a06636e55ea3e7edd4f6334dd9215151205","examples/cat.rs":"ab0b575d19662e2d5b6c7cea2756b57530e495d56acdb4fd2b56c0ba4d768dfd","src/advice.rs":"194bfd6a32495f6b0c739d083b06230ae656927767f15c1b49b245b63431cc4d","src/lib.rs":"2fa8c6162297441c82471132b9e26d3effcb9c06ae414a0104f9d871eba0aa00","src/stub.rs":"f276bb5e4bc29c2129ebc660b01a1de173b9575e2e866ea5a34e0ee6318f1177","src/unix.rs":"4fa52c514f15dd5e990e03671599a0c3f15770b8fb5f8fea3ea6333766b1e31c","src/windows.rs":"73838f8b2dc8b0c8d37045db36c3c7eb2dc00e6f5d5a7bc0c693bdb55d3ec721"},"package":"d5172b50c23043ff43dd53e51392f36519d9b35a8f3a410d30ece5d1aedd58ae"}
|
||||
{"files":{"CHANGELOG.md":"fb280b4d71ea601557e7ab637a7f82f73eb519dd9d16d38684bf6fe4e800a020","Cargo.lock":"80c9c7be560eee59e3eded68a49b53278198fc23495807c6a22e9c5190914ebe","Cargo.toml":"4738a7e9e1f236b95d41ef8837c351f895fcb1cc1cb82ab7e3bf39c72849cba4","LICENSE-APACHE":"04ea4849dba9dcae07113850c6f1b1a69052c625210639914eee352023f750ad","LICENSE-MIT":"0d25d03b5ab49576178ad0cae7a2648d12c17ad0452fe49c07e55e4b59aa5257","README.md":"c7b3cd928f0d1a10faa255e2f84a2a06636e55ea3e7edd4f6334dd9215151205","examples/cat.rs":"ab0b575d19662e2d5b6c7cea2756b57530e495d56acdb4fd2b56c0ba4d768dfd","src/advice.rs":"194bfd6a32495f6b0c739d083b06230ae656927767f15c1b49b245b63431cc4d","src/lib.rs":"ea214bce1c2409b8ee7a390c85f5114bc681a551d02aba23280030fe58588eb9","src/stub.rs":"f276bb5e4bc29c2129ebc660b01a1de173b9575e2e866ea5a34e0ee6318f1177","src/unix.rs":"03fe91a320d0146993019ea51e486275b8c8e13e42a995e649b8c76690e3f167","src/windows.rs":"bbb39200ac35b5517626c12efad4886f7b5d34e56256284914c556dec1567e38"},"package":"95af15f345b17af2efc8ead6080fb8bc376f8cec1b35277b935637595fe77498"}
|
|
@ -6,6 +6,23 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||
|
||||
## [Unreleased]
|
||||
|
||||
## [0.5.7] - 2022-08-15
|
||||
### Changed
|
||||
- Simplify file size retrieving code.
|
||||
[@saethlin](https://github.com/saethlin)
|
||||
|
||||
## [0.5.6] - 2022-08-11
|
||||
### Added
|
||||
- Memory locking and unlocking. See `Mmap::lock`, `Mmap::unlock`,
|
||||
`MmapMut::lock` and `MmapMut::unlock`.
|
||||
[@vmx](https://github.com/vmx)
|
||||
|
||||
## [0.5.5] - 2022-07-09
|
||||
### Fixed
|
||||
- Limit mapping length to `isize::MAX` to prevent undefined behavior
|
||||
on calling `std::slice::from_raw_parts`. Technically affects only 32-bit systems.
|
||||
[@adamreichold](https://github.com/adamreichold)
|
||||
|
||||
## [0.5.4] - 2022-06-04
|
||||
### Added
|
||||
- Add madvice operations specific to Darwin. [@turbocool3r](https://github.com/turbocool3r)
|
||||
|
@ -100,7 +117,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||
### Removed
|
||||
- `winapi` dependency. [memmap-rs/pull/89](https://github.com/danburkert/memmap-rs/pull/89)
|
||||
|
||||
[Unreleased]: https://github.com/RazrFalcon/memmap2-rs/compare/v0.5.4...HEAD
|
||||
[Unreleased]: https://github.com/RazrFalcon/memmap2-rs/compare/v0.5.7...HEAD
|
||||
[0.5.7]: https://github.com/RazrFalcon/memmap2-rs/compare/v0.5.6...v0.5.7
|
||||
[0.5.6]: https://github.com/RazrFalcon/memmap2-rs/compare/v0.5.5...v0.5.6
|
||||
[0.5.5]: https://github.com/RazrFalcon/memmap2-rs/compare/v0.5.4...v0.5.5
|
||||
[0.5.4]: https://github.com/RazrFalcon/memmap2-rs/compare/v0.5.3...v0.5.4
|
||||
[0.5.3]: https://github.com/RazrFalcon/memmap2-rs/compare/v0.5.2...v0.5.3
|
||||
[0.5.2]: https://github.com/RazrFalcon/memmap2-rs/compare/v0.5.1...v0.5.2
|
||||
|
|
|
@ -40,7 +40,7 @@ checksum = "a7f823d141fe0a24df1e23b4af4e3c7ba9e5966ec514ea068c93024aa7deb765"
|
|||
|
||||
[[package]]
|
||||
name = "memmap2"
|
||||
version = "0.5.4"
|
||||
version = "0.5.7"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"owning_ref",
|
||||
|
|
|
@ -12,13 +12,14 @@
|
|||
[package]
|
||||
edition = "2018"
|
||||
name = "memmap2"
|
||||
version = "0.5.4"
|
||||
version = "0.5.7"
|
||||
authors = [
|
||||
"Dan Burkert <dan@danburkert.com>",
|
||||
"Yevhenii Reizner <razrfalcon@gmail.com>",
|
||||
]
|
||||
description = "Cross-platform Rust API for memory-mapped file IO"
|
||||
documentation = "https://docs.rs/memmap2"
|
||||
readme = "README.md"
|
||||
keywords = [
|
||||
"mmap",
|
||||
"memory-map",
|
||||
|
|
|
@ -51,13 +51,14 @@ use std::fmt;
|
|||
#[cfg(not(any(unix, windows)))]
|
||||
use std::fs::File;
|
||||
use std::io::{Error, ErrorKind, Result};
|
||||
use std::isize;
|
||||
use std::mem;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
#[cfg(unix)]
|
||||
use std::os::unix::io::{AsRawFd, RawFd};
|
||||
#[cfg(windows)]
|
||||
use std::os::windows::io::{AsRawHandle, RawHandle};
|
||||
use std::slice;
|
||||
use std::usize;
|
||||
|
||||
#[cfg(not(any(unix, windows)))]
|
||||
pub struct MmapRawDescriptor<'a>(&'a File);
|
||||
|
@ -237,15 +238,20 @@ impl MmapOptions {
|
|||
}
|
||||
let len = file_len - self.offset;
|
||||
|
||||
// This check it not relevant on 64bit targets, because usize == u64
|
||||
#[cfg(not(target_pointer_width = "64"))]
|
||||
{
|
||||
if len > (usize::MAX as u64) {
|
||||
return Err(Error::new(
|
||||
ErrorKind::InvalidData,
|
||||
"memory map length overflows usize",
|
||||
));
|
||||
}
|
||||
// Rust's slice cannot be larger than isize::MAX.
|
||||
// See https://doc.rust-lang.org/std/slice/fn.from_raw_parts.html
|
||||
//
|
||||
// This is not a problem on 64-bit targets, but on 32-bit one
|
||||
// having a file or an anonymous mapping larger than 2GB is quite normal
|
||||
// and we have to prevent it.
|
||||
//
|
||||
// The code below is essentially the same as in Rust's std:
|
||||
// https://github.com/rust-lang/rust/blob/db78ab70a88a0a5e89031d7ee4eccec835dcdbde/library/alloc/src/raw_vec.rs#L495
|
||||
if mem::size_of::<usize>() < 8 && len > isize::MAX as u64 {
|
||||
return Err(Error::new(
|
||||
ErrorKind::InvalidData,
|
||||
"memory map length overflows isize",
|
||||
));
|
||||
}
|
||||
|
||||
Ok(len as usize)
|
||||
|
@ -457,14 +463,26 @@ impl MmapOptions {
|
|||
|
||||
/// Creates an anonymous memory map.
|
||||
///
|
||||
/// Note: the memory map length must be configured to be greater than 0 before creating an
|
||||
/// anonymous memory map using `MmapOptions::len()`.
|
||||
/// The memory map length should be configured using [`MmapOptions::len()`]
|
||||
/// before creating an anonymous memory map, otherwise a zero-length mapping
|
||||
/// will be crated.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// This method returns an error when the underlying system call fails.
|
||||
/// This method returns an error when the underlying system call fails or
|
||||
/// when `len > isize::MAX`.
|
||||
pub fn map_anon(&self) -> Result<MmapMut> {
|
||||
MmapInner::map_anon(self.len.unwrap_or(0), self.stack).map(|inner| MmapMut { inner })
|
||||
let len = self.len.unwrap_or(0);
|
||||
|
||||
// See get_len() for details.
|
||||
if mem::size_of::<usize>() < 8 && len > isize::MAX as usize {
|
||||
return Err(Error::new(
|
||||
ErrorKind::InvalidData,
|
||||
"memory map length overflows isize",
|
||||
));
|
||||
}
|
||||
|
||||
MmapInner::map_anon(len, self.stack).map(|inner| MmapMut { inner })
|
||||
}
|
||||
|
||||
/// Creates a raw memory map.
|
||||
|
@ -611,6 +629,22 @@ impl Mmap {
|
|||
pub fn advise(&self, advice: Advice) -> Result<()> {
|
||||
self.inner.advise(advice)
|
||||
}
|
||||
|
||||
/// Lock the whole memory map into RAM. Only supported on Unix.
|
||||
///
|
||||
/// See [mlock()](https://man7.org/linux/man-pages/man2/mlock.2.html) map page.
|
||||
#[cfg(unix)]
|
||||
pub fn lock(&mut self) -> Result<()> {
|
||||
self.inner.lock()
|
||||
}
|
||||
|
||||
/// Unlock the whole memory map. Only supported on Unix.
|
||||
///
|
||||
/// See [munlock()](https://man7.org/linux/man-pages/man2/munlock.2.html) map page.
|
||||
#[cfg(unix)]
|
||||
pub fn unlock(&mut self) -> Result<()> {
|
||||
self.inner.unlock()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "stable_deref_trait")]
|
||||
|
@ -856,7 +890,8 @@ impl MmapMut {
|
|||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// This method returns an error when the underlying system call fails.
|
||||
/// This method returns an error when the underlying system call fails or
|
||||
/// when `len > isize::MAX`.
|
||||
pub fn map_anon(length: usize) -> Result<MmapMut> {
|
||||
MmapOptions::new().len(length).map_anon()
|
||||
}
|
||||
|
@ -987,6 +1022,22 @@ impl MmapMut {
|
|||
pub fn advise(&self, advice: Advice) -> Result<()> {
|
||||
self.inner.advise(advice)
|
||||
}
|
||||
|
||||
/// Lock the whole memory map into RAM. Only supported on Unix.
|
||||
///
|
||||
/// See [mlock()](https://man7.org/linux/man-pages/man2/mlock.2.html) map page.
|
||||
#[cfg(unix)]
|
||||
pub fn lock(&mut self) -> Result<()> {
|
||||
self.inner.lock()
|
||||
}
|
||||
|
||||
/// Unlock the whole memory map. Only supported on Unix.
|
||||
///
|
||||
/// See [munlock()](https://man7.org/linux/man-pages/man2/munlock.2.html) map page.
|
||||
#[cfg(unix)]
|
||||
pub fn unlock(&mut self) -> Result<()> {
|
||||
self.inner.unlock()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "stable_deref_trait")]
|
||||
|
@ -1037,7 +1088,7 @@ mod test {
|
|||
|
||||
#[cfg(unix)]
|
||||
use crate::advice::Advice;
|
||||
use std::fs::OpenOptions;
|
||||
use std::fs::{self, OpenOptions};
|
||||
use std::io::{Read, Write};
|
||||
#[cfg(unix)]
|
||||
use std::os::unix::io::AsRawFd;
|
||||
|
@ -1157,6 +1208,17 @@ mod test {
|
|||
assert!(MmapOptions::new().map_anon().unwrap().is_empty())
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
fn map_anon_len_overflow() {
|
||||
let res = MmapMut::map_anon(0x80000000);
|
||||
|
||||
assert_eq!(
|
||||
res.unwrap_err().to_string(),
|
||||
"memory map length overflows isize"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn file_write() {
|
||||
let tempdir = tempfile::tempdir().unwrap();
|
||||
|
@ -1333,7 +1395,6 @@ mod test {
|
|||
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
fn jit_x86(mut mmap: MmapMut) {
|
||||
use std::mem;
|
||||
mmap[0] = 0xB8; // mov eax, 0xAB
|
||||
mmap[1] = 0xAB;
|
||||
mmap[2] = 0x00;
|
||||
|
@ -1343,7 +1404,7 @@ mod test {
|
|||
|
||||
let mmap = mmap.make_exec().expect("make_exec");
|
||||
|
||||
let jitfn: extern "C" fn() -> u8 = unsafe { mem::transmute(mmap.as_ptr()) };
|
||||
let jitfn: extern "C" fn() -> u8 = unsafe { std::mem::transmute(mmap.as_ptr()) };
|
||||
assert_eq!(jitfn(), 0xab);
|
||||
}
|
||||
|
||||
|
@ -1557,4 +1618,56 @@ mod test {
|
|||
// read values back
|
||||
assert_eq!(&incr[..], &mmap[..]);
|
||||
}
|
||||
|
||||
/// Returns true if a non-zero amount of memory is locked.
|
||||
#[cfg(target_os = "linux")]
|
||||
fn is_locked() -> bool {
|
||||
let status = &fs::read_to_string("/proc/self/status")
|
||||
.expect("/proc/self/status should be available");
|
||||
for line in status.lines() {
|
||||
if line.starts_with("VmLck:") {
|
||||
let numbers = line.replace(|c: char| !c.is_ascii_digit(), "");
|
||||
return numbers != "0";
|
||||
}
|
||||
}
|
||||
panic!("cannot get VmLck information")
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(unix)]
|
||||
fn lock() {
|
||||
let tempdir = tempfile::tempdir().unwrap();
|
||||
let path = tempdir.path().join("mmap_lock");
|
||||
|
||||
let file = OpenOptions::new()
|
||||
.read(true)
|
||||
.write(true)
|
||||
.create(true)
|
||||
.open(&path)
|
||||
.unwrap();
|
||||
file.set_len(128).unwrap();
|
||||
|
||||
let mut mmap = unsafe { Mmap::map(&file).unwrap() };
|
||||
#[cfg(target_os = "linux")]
|
||||
assert!(!is_locked());
|
||||
|
||||
mmap.lock().expect("mmap lock should be supported on unix");
|
||||
#[cfg(target_os = "linux")]
|
||||
assert!(is_locked());
|
||||
|
||||
mmap.lock()
|
||||
.expect("mmap lock again should not cause problems");
|
||||
#[cfg(target_os = "linux")]
|
||||
assert!(is_locked());
|
||||
|
||||
mmap.unlock()
|
||||
.expect("mmap unlock should be supported on unix");
|
||||
#[cfg(target_os = "linux")]
|
||||
assert!(!is_locked());
|
||||
|
||||
mmap.unlock()
|
||||
.expect("mmap unlock again should not cause problems");
|
||||
#[cfg(target_os = "linux")]
|
||||
assert!(!is_locked());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
extern crate libc;
|
||||
|
||||
use std::mem::MaybeUninit;
|
||||
use std::os::unix::io::RawFd;
|
||||
use std::fs::File;
|
||||
use std::mem::ManuallyDrop;
|
||||
use std::os::unix::io::{FromRawFd, RawFd};
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::{io, ptr};
|
||||
|
||||
|
@ -248,6 +249,26 @@ impl MmapInner {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lock(&self) -> io::Result<()> {
|
||||
unsafe {
|
||||
if libc::mlock(self.ptr, self.len) != 0 {
|
||||
Err(io::Error::last_os_error())
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unlock(&self) -> io::Result<()> {
|
||||
unsafe {
|
||||
if libc::munlock(self.ptr, self.len) != 0 {
|
||||
Err(io::Error::last_os_error())
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for MmapInner {
|
||||
|
@ -284,19 +305,10 @@ fn page_size() -> usize {
|
|||
}
|
||||
|
||||
pub fn file_len(file: RawFd) -> io::Result<u64> {
|
||||
#[cfg(not(any(target_os = "linux", target_os = "emscripten", target_os = "l4re")))]
|
||||
use libc::{fstat, stat};
|
||||
#[cfg(any(target_os = "linux", target_os = "emscripten", target_os = "l4re"))]
|
||||
use libc::{fstat64 as fstat, stat64 as stat};
|
||||
|
||||
// SAFETY: We must not close the passed-in fd by dropping the File we create,
|
||||
// we ensure this by immediately wrapping it in a ManuallyDrop.
|
||||
unsafe {
|
||||
let mut stat = MaybeUninit::<stat>::uninit();
|
||||
|
||||
let result = fstat(file, stat.as_mut_ptr());
|
||||
if result == 0 {
|
||||
Ok(stat.assume_init().st_size as u64)
|
||||
} else {
|
||||
Err(io::Error::last_os_error())
|
||||
}
|
||||
let file = ManuallyDrop::new(File::from_raw_fd(file));
|
||||
Ok(file.metadata()?.len())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
#![allow(non_camel_case_types)]
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
use std::fs::File;
|
||||
use std::mem::ManuallyDrop;
|
||||
use std::os::raw::c_void;
|
||||
use std::os::windows::io::RawHandle;
|
||||
use std::os::windows::io::{FromRawHandle, RawHandle};
|
||||
use std::{io, mem, ptr};
|
||||
|
||||
type BOOL = i32;
|
||||
|
@ -82,22 +84,6 @@ pub struct FILETIME {
|
|||
pub dwHighDateTime: DWORD,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
struct BY_HANDLE_FILE_INFORMATION {
|
||||
dwFileAttributes: DWORD,
|
||||
ftCreationTime: FILETIME,
|
||||
ftLastAccessTime: FILETIME,
|
||||
ftLastWriteTime: FILETIME,
|
||||
dwVolumeSerialNumber: DWORD,
|
||||
nFileSizeHigh: DWORD,
|
||||
nFileSizeLow: DWORD,
|
||||
nNumberOfLinks: DWORD,
|
||||
nFileIndexHigh: DWORD,
|
||||
nFileIndexLow: DWORD,
|
||||
}
|
||||
|
||||
type LPBY_HANDLE_FILE_INFORMATION = *mut BY_HANDLE_FILE_INFORMATION;
|
||||
|
||||
extern "system" {
|
||||
fn GetCurrentProcess() -> HANDLE;
|
||||
|
||||
|
@ -124,11 +110,6 @@ extern "system" {
|
|||
|
||||
fn FlushFileBuffers(hFile: HANDLE) -> BOOL;
|
||||
|
||||
fn GetFileInformationByHandle(
|
||||
hFile: HANDLE,
|
||||
lpFileInformation: LPBY_HANDLE_FILE_INFORMATION,
|
||||
) -> BOOL;
|
||||
|
||||
fn FlushViewOfFile(lpBaseAddress: LPCVOID, dwNumberOfBytesToFlush: SIZE_T) -> BOOL;
|
||||
|
||||
fn UnmapViewOfFile(lpBaseAddress: LPCVOID) -> BOOL;
|
||||
|
@ -526,16 +507,10 @@ fn allocation_granularity() -> usize {
|
|||
}
|
||||
|
||||
pub fn file_len(handle: RawHandle) -> io::Result<u64> {
|
||||
let info = unsafe {
|
||||
let mut info = mem::MaybeUninit::<BY_HANDLE_FILE_INFORMATION>::uninit();
|
||||
|
||||
let ok = GetFileInformationByHandle(handle, info.as_mut_ptr());
|
||||
if ok == 0 {
|
||||
return Err(io::Error::last_os_error());
|
||||
}
|
||||
|
||||
info.assume_init()
|
||||
};
|
||||
|
||||
Ok((info.nFileSizeHigh as u64) << 32 | info.nFileSizeLow as u64)
|
||||
// SAFETY: We must not close the passed-in fd by dropping the File we create,
|
||||
// we ensure this by immediately wrapping it in a ManuallyDrop.
|
||||
unsafe {
|
||||
let file = ManuallyDrop::new(File::from_raw_handle(handle));
|
||||
Ok(file.metadata()?.len())
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче