diff options
| author | The Miri Cronjob Bot <miri@cron.bot> | 2025-06-07 05:01:19 +0000 |
|---|---|---|
| committer | The Miri Cronjob Bot <miri@cron.bot> | 2025-06-07 05:01:19 +0000 |
| commit | 4c4904b54a2d9db26e8a164b8388c586c3c5fd16 (patch) | |
| tree | 432eb7bbe6cc257bcfdc879c7ab5dd0ed4603782 /library/std | |
| parent | cf5aea57cc741ad10a80841a3ec2fde52a939279 (diff) | |
| parent | 775e0c8aeb8f63192854b27156f8b05a06b51814 (diff) | |
| download | rust-4c4904b54a2d9db26e8a164b8388c586c3c5fd16.tar.gz rust-4c4904b54a2d9db26e8a164b8388c586c3c5fd16.zip | |
Merge from rustc
Diffstat (limited to 'library/std')
| -rw-r--r-- | library/std/src/ffi/mod.rs | 2 | ||||
| -rw-r--r-- | library/std/src/fs.rs | 36 | ||||
| -rw-r--r-- | library/std/src/io/mod.rs | 26 | ||||
| -rw-r--r-- | library/std/src/keyword_docs.rs | 27 | ||||
| -rw-r--r-- | library/std/src/sys/fs/hermit.rs | 4 | ||||
| -rw-r--r-- | library/std/src/sys/fs/solid.rs | 4 | ||||
| -rw-r--r-- | library/std/src/sys/fs/uefi.rs | 4 | ||||
| -rw-r--r-- | library/std/src/sys/fs/unix.rs | 9 | ||||
| -rw-r--r-- | library/std/src/sys/fs/unsupported.rs | 4 | ||||
| -rw-r--r-- | library/std/src/sys/fs/wasi.rs | 4 | ||||
| -rw-r--r-- | library/std/src/sys/fs/windows.rs | 8 | ||||
| -rw-r--r-- | library/std/src/sys/pal/unix/os.rs | 2 | ||||
| -rw-r--r-- | library/std/src/sys/pal/windows/c/bindings.txt | 1 | ||||
| -rw-r--r-- | library/std/src/sys/pal/windows/c/windows_sys.rs | 1 |
14 files changed, 104 insertions, 28 deletions
diff --git a/library/std/src/ffi/mod.rs b/library/std/src/ffi/mod.rs index 024cb71b915..f44e12d48ad 100644 --- a/library/std/src/ffi/mod.rs +++ b/library/std/src/ffi/mod.rs @@ -178,6 +178,8 @@ pub use core::ffi::{ c_char, c_double, c_float, c_int, c_long, c_longlong, c_schar, c_short, c_uchar, c_uint, c_ulong, c_ulonglong, c_ushort, }; +#[unstable(feature = "c_size_t", issue = "88345")] +pub use core::ffi::{c_ptrdiff_t, c_size_t, c_ssize_t}; #[doc(inline)] #[stable(feature = "cstr_from_bytes_until_nul", since = "1.69.0")] diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index 711efc7d011..6cbf8301e01 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -1311,9 +1311,39 @@ impl Write for &File { } #[stable(feature = "rust1", since = "1.0.0")] impl Seek for &File { + /// Seek to an offset, in bytes in a file. + /// + /// See [`Seek::seek`] docs for more info. + /// + /// # Platform-specific behavior + /// + /// This function currently corresponds to the `lseek64` function on Unix + /// and the `SetFilePointerEx` function on Windows. Note that this [may + /// change in the future][changes]. + /// + /// [changes]: io#platform-specific-behavior fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> { self.inner.seek(pos) } + + /// Returns the length of this file (in bytes). + /// + /// See [`Seek::stream_len`] docs for more info. + /// + /// # Platform-specific behavior + /// + /// This function currently corresponds to the `statx` function on Linux + /// (with fallbacks) and the `GetFileSizeEx` function on Windows. Note that + /// this [may change in the future][changes]. + /// + /// [changes]: io#platform-specific-behavior + fn stream_len(&mut self) -> io::Result<u64> { + if let Some(result) = self.inner.size() { + return result; + } + io::stream_len_default(self) + } + fn stream_position(&mut self) -> io::Result<u64> { self.inner.tell() } @@ -1363,6 +1393,9 @@ impl Seek for File { fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> { (&*self).seek(pos) } + fn stream_len(&mut self) -> io::Result<u64> { + (&*self).stream_len() + } fn stream_position(&mut self) -> io::Result<u64> { (&*self).stream_position() } @@ -1412,6 +1445,9 @@ impl Seek for Arc<File> { fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> { (&**self).seek(pos) } + fn stream_len(&mut self) -> io::Result<u64> { + (&**self).stream_len() + } fn stream_position(&mut self) -> io::Result<u64> { (&**self).stream_position() } diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index 03f5f838311..20c82b64bcc 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -2028,7 +2028,7 @@ pub trait Seek { /// Returns the length of this stream (in bytes). /// - /// This method is implemented using up to three seek operations. If this + /// The default implementation uses up to three seek operations. If this /// method returns successfully, the seek position is unchanged (i.e. the /// position before calling this method is the same as afterwards). /// However, if this method returns an error, the seek position is @@ -2062,16 +2062,7 @@ pub trait Seek { /// ``` #[unstable(feature = "seek_stream_len", issue = "59359")] fn stream_len(&mut self) -> Result<u64> { - let old_pos = self.stream_position()?; - let len = self.seek(SeekFrom::End(0))?; - - // Avoid seeking a third time when we were already at the end of the - // stream. The branch is usually way cheaper than a seek operation. - if old_pos != len { - self.seek(SeekFrom::Start(old_pos))?; - } - - Ok(len) + stream_len_default(self) } /// Returns the current seek position from the start of the stream. @@ -2132,6 +2123,19 @@ pub trait Seek { } } +pub(crate) fn stream_len_default<T: Seek + ?Sized>(self_: &mut T) -> Result<u64> { + let old_pos = self_.stream_position()?; + let len = self_.seek(SeekFrom::End(0))?; + + // Avoid seeking a third time when we were already at the end of the + // stream. The branch is usually way cheaper than a seek operation. + if old_pos != len { + self_.seek(SeekFrom::Start(old_pos))?; + } + + Ok(len) +} + /// Enumeration of possible methods to seek within an I/O object. /// /// It is used by the [`Seek`] trait. diff --git a/library/std/src/keyword_docs.rs b/library/std/src/keyword_docs.rs index 79b25040ef6..1c55824ab90 100644 --- a/library/std/src/keyword_docs.rs +++ b/library/std/src/keyword_docs.rs @@ -1916,10 +1916,6 @@ mod type_keyword {} /// - and to declare that a programmer has checked that these contracts have been upheld (`unsafe /// {}` and `unsafe impl`, but also `unsafe fn` -- see below). /// -/// They are not mutually exclusive, as can be seen in `unsafe fn`: the body of an `unsafe fn` is, -/// by default, treated like an unsafe block. The `unsafe_op_in_unsafe_fn` lint can be enabled to -/// change that. -/// /// # Unsafe abilities /// /// **No matter what, Safe Rust can't cause Undefined Behavior**. This is @@ -1961,13 +1957,6 @@ mod type_keyword {} /// - `unsafe impl`: the contract necessary to implement the trait has been /// checked by the programmer and is guaranteed to be respected. /// -/// By default, `unsafe fn` also acts like an `unsafe {}` block -/// around the code inside the function. This means it is not just a signal to -/// the caller, but also promises that the preconditions for the operations -/// inside the function are upheld. Mixing these two meanings can be confusing, so the -/// `unsafe_op_in_unsafe_fn` lint can be enabled to warn against that and require explicit unsafe -/// blocks even inside `unsafe fn`. -/// /// See the [Rustonomicon] and the [Reference] for more information. /// /// # Examples @@ -2109,6 +2098,7 @@ mod type_keyword {} /// impl Indexable for i32 { /// const LEN: usize = 1; /// +/// /// See `Indexable` for the safety contract. /// unsafe fn idx_unchecked(&self, idx: usize) -> i32 { /// debug_assert_eq!(idx, 0); /// *self @@ -2120,6 +2110,7 @@ mod type_keyword {} /// impl Indexable for [i32; 42] { /// const LEN: usize = 42; /// +/// /// See `Indexable` for the safety contract. /// unsafe fn idx_unchecked(&self, idx: usize) -> i32 { /// // SAFETY: As per this trait's documentation, the caller ensures /// // that `idx < 42`. @@ -2132,6 +2123,7 @@ mod type_keyword {} /// impl Indexable for ! { /// const LEN: usize = 0; /// +/// /// See `Indexable` for the safety contract. /// unsafe fn idx_unchecked(&self, idx: usize) -> i32 { /// // SAFETY: As per this trait's documentation, the caller ensures /// // that `idx < 0`, which is impossible, so this is dead code. @@ -2153,11 +2145,14 @@ mod type_keyword {} /// contract of `idx_unchecked`. Implementing `Indexable` is safe because when writing /// `idx_unchecked`, we don't have to worry: our *callers* need to discharge a proof obligation /// (like `use_indexable` does), but the *implementation* of `get_unchecked` has no proof obligation -/// to contend with. Of course, the implementation of `Indexable` may choose to call other unsafe -/// operations, and then it needs an `unsafe` *block* to indicate it discharged the proof -/// obligations of its callees. (We enabled `unsafe_op_in_unsafe_fn`, so the body of `idx_unchecked` -/// is not implicitly an unsafe block.) For that purpose it can make use of the contract that all -/// its callers must uphold -- the fact that `idx < LEN`. +/// to contend with. Of course, the implementation may choose to call other unsafe operations, and +/// then it needs an `unsafe` *block* to indicate it discharged the proof obligations of its +/// callees. For that purpose it can make use of the contract that all its callers must uphold -- +/// the fact that `idx < LEN`. +/// +/// Note that unlike normal `unsafe fn`, an `unsafe fn` in a trait implementation does not get to +/// just pick an arbitrary safety contract! It *has* to use the safety contract defined by the trait +/// (or one with weaker preconditions). /// /// Formally speaking, an `unsafe fn` in a trait is a function with *preconditions* that go beyond /// those encoded by the argument types (such as `idx < LEN`), whereas an `unsafe trait` can declare diff --git a/library/std/src/sys/fs/hermit.rs b/library/std/src/sys/fs/hermit.rs index a9774bef9e3..175d919c289 100644 --- a/library/std/src/sys/fs/hermit.rs +++ b/library/std/src/sys/fs/hermit.rs @@ -422,6 +422,10 @@ impl File { self.0.seek(pos) } + pub fn size(&self) -> Option<io::Result<u64>> { + None + } + pub fn tell(&self) -> io::Result<u64> { self.0.tell() } diff --git a/library/std/src/sys/fs/solid.rs b/library/std/src/sys/fs/solid.rs index 3bfb39bac95..808a9582911 100644 --- a/library/std/src/sys/fs/solid.rs +++ b/library/std/src/sys/fs/solid.rs @@ -459,6 +459,10 @@ impl File { self.tell() } + pub fn size(&self) -> Option<io::Result<u64>> { + None + } + pub fn tell(&self) -> io::Result<u64> { unsafe { let mut out_offset = MaybeUninit::uninit(); diff --git a/library/std/src/sys/fs/uefi.rs b/library/std/src/sys/fs/uefi.rs index 416c90b98b6..5763d7862f5 100644 --- a/library/std/src/sys/fs/uefi.rs +++ b/library/std/src/sys/fs/uefi.rs @@ -280,6 +280,10 @@ impl File { self.0 } + pub fn size(&self) -> Option<io::Result<u64>> { + self.0 + } + pub fn tell(&self) -> io::Result<u64> { self.0 } diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs index a3e520fdeef..dc278274f00 100644 --- a/library/std/src/sys/fs/unix.rs +++ b/library/std/src/sys/fs/unix.rs @@ -1464,6 +1464,15 @@ impl File { Ok(n as u64) } + pub fn size(&self) -> Option<io::Result<u64>> { + match self.file_attr().map(|attr| attr.size()) { + // Fall back to default implementation if the returned size is 0, + // we might be in a proc mount. + Ok(0) => None, + result => Some(result), + } + } + pub fn tell(&self) -> io::Result<u64> { self.seek(SeekFrom::Current(0)) } diff --git a/library/std/src/sys/fs/unsupported.rs b/library/std/src/sys/fs/unsupported.rs index 0ff9533c047..efaddb51b37 100644 --- a/library/std/src/sys/fs/unsupported.rs +++ b/library/std/src/sys/fs/unsupported.rs @@ -259,6 +259,10 @@ impl File { self.0 } + pub fn size(&self) -> Option<io::Result<u64>> { + self.0 + } + pub fn tell(&self) -> io::Result<u64> { self.0 } diff --git a/library/std/src/sys/fs/wasi.rs b/library/std/src/sys/fs/wasi.rs index ebfc7377a2e..b65d86de12a 100644 --- a/library/std/src/sys/fs/wasi.rs +++ b/library/std/src/sys/fs/wasi.rs @@ -516,6 +516,10 @@ impl File { self.fd.seek(pos) } + pub fn size(&self) -> Option<io::Result<u64>> { + None + } + pub fn tell(&self) -> io::Result<u64> { self.fd.tell() } diff --git a/library/std/src/sys/fs/windows.rs b/library/std/src/sys/fs/windows.rs index d01a572ac73..a95709b4891 100644 --- a/library/std/src/sys/fs/windows.rs +++ b/library/std/src/sys/fs/windows.rs @@ -616,6 +616,14 @@ impl File { Ok(newpos as u64) } + pub fn size(&self) -> Option<io::Result<u64>> { + let mut result = 0; + Some( + cvt(unsafe { c::GetFileSizeEx(self.handle.as_raw_handle(), &mut result) }) + .map(|_| result as u64), + ) + } + pub fn tell(&self) -> io::Result<u64> { self.seek(SeekFrom::Current(0)) } diff --git a/library/std/src/sys/pal/unix/os.rs b/library/std/src/sys/pal/unix/os.rs index 48609030aed..850bdfdf5b5 100644 --- a/library/std/src/sys/pal/unix/os.rs +++ b/library/std/src/sys/pal/unix/os.rs @@ -282,7 +282,7 @@ pub fn current_exe() -> io::Result<PathBuf> { return getcwd().map(|cwd| cwd.join(path))?.canonicalize(); } // Search PATH to infer current_exe. - if let Some(p) = getenv(OsStr::from_bytes("PATH".as_bytes())) { + if let Some(p) = env::var_os(OsStr::from_bytes("PATH".as_bytes())) { for search_path in split_paths(&p) { let pb = search_path.join(&path); if pb.is_file() diff --git a/library/std/src/sys/pal/windows/c/bindings.txt b/library/std/src/sys/pal/windows/c/bindings.txt index d5fbb453c6f..a99c474c763 100644 --- a/library/std/src/sys/pal/windows/c/bindings.txt +++ b/library/std/src/sys/pal/windows/c/bindings.txt @@ -2156,6 +2156,7 @@ GetExitCodeProcess GetFileAttributesW GetFileInformationByHandle GetFileInformationByHandleEx +GetFileSizeEx GetFileType GETFINALPATHNAMEBYHANDLE_FLAGS GetFinalPathNameByHandleW diff --git a/library/std/src/sys/pal/windows/c/windows_sys.rs b/library/std/src/sys/pal/windows/c/windows_sys.rs index eb2914b8644..95bf8040229 100644 --- a/library/std/src/sys/pal/windows/c/windows_sys.rs +++ b/library/std/src/sys/pal/windows/c/windows_sys.rs @@ -44,6 +44,7 @@ windows_targets::link!("kernel32.dll" "system" fn GetExitCodeProcess(hprocess : windows_targets::link!("kernel32.dll" "system" fn GetFileAttributesW(lpfilename : PCWSTR) -> u32); windows_targets::link!("kernel32.dll" "system" fn GetFileInformationByHandle(hfile : HANDLE, lpfileinformation : *mut BY_HANDLE_FILE_INFORMATION) -> BOOL); windows_targets::link!("kernel32.dll" "system" fn GetFileInformationByHandleEx(hfile : HANDLE, fileinformationclass : FILE_INFO_BY_HANDLE_CLASS, lpfileinformation : *mut core::ffi::c_void, dwbuffersize : u32) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn GetFileSizeEx(hfile : HANDLE, lpfilesize : *mut i64) -> BOOL); windows_targets::link!("kernel32.dll" "system" fn GetFileType(hfile : HANDLE) -> FILE_TYPE); windows_targets::link!("kernel32.dll" "system" fn GetFinalPathNameByHandleW(hfile : HANDLE, lpszfilepath : PWSTR, cchfilepath : u32, dwflags : GETFINALPATHNAMEBYHANDLE_FLAGS) -> u32); windows_targets::link!("kernel32.dll" "system" fn GetFullPathNameW(lpfilename : PCWSTR, nbufferlength : u32, lpbuffer : PWSTR, lpfilepart : *mut PWSTR) -> u32); |
