diff options
| author | bors <bors@rust-lang.org> | 2020-07-11 06:28:04 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2020-07-11 06:28:04 +0000 |
| commit | 346aec9b02f3c74f3fce97fd6bda24709d220e49 (patch) | |
| tree | 8ddad2b3c566486f44ea01f6305e1beeb11140f7 /src/libstd/sys | |
| parent | daecab3a784f28082df90cebb204998051f3557d (diff) | |
| parent | 79fc3861dfd1190b257ef7f4208533c3945254b7 (diff) | |
| download | rust-346aec9b02f3c74f3fce97fd6bda24709d220e49.tar.gz rust-346aec9b02f3c74f3fce97fd6bda24709d220e49.zip | |
Auto merge of #74235 - Manishearth:rollup-bgs3q14, r=Manishearth
Rollup of 19 pull requests
Successful merges:
- #71322 (Accept tuple.0.0 as tuple indexing (take 2))
- #72303 (Add core::future::{poll_fn, PollFn})
- #73862 (Stabilize casts and coercions to `&[T]` in const fn)
- #73887 (stabilize const mem::forget)
- #73989 (adjust ub-enum test to be endianess-independent)
- #74045 (Explain effects of debugging options from config.toml)
- #74076 (Add `read_exact_at` and `write_all_at` to WASI's `FileExt`)
- #74099 (Add VecDeque::range* methods)
- #74100 (Use str::strip* in bootstrap)
- #74103 (Only add CFGuard on `windows-msvc` targets)
- #74109 (Only allow `repr(i128/u128)` on enum)
- #74122 (Start-up clean-up)
- #74125 (Correctly mark the ending span of a match arm)
- #74127 (Avoid "whitelist")
- #74129 (:arrow_up: rust-analyzer)
- #74135 (Update books)
- #74145 (Update rust-installer to latest version)
- #74161 (Fix disabled dockerfiles)
- #74162 (take self by value in ToPredicate)
Failed merges:
r? @ghost
Diffstat (limited to 'src/libstd/sys')
| -rw-r--r-- | src/libstd/sys/wasi/ext/fs.rs | 141 |
1 files changed, 137 insertions, 4 deletions
diff --git a/src/libstd/sys/wasi/ext/fs.rs b/src/libstd/sys/wasi/ext/fs.rs index 6696efa8871..f41c6626ccf 100644 --- a/src/libstd/sys/wasi/ext/fs.rs +++ b/src/libstd/sys/wasi/ext/fs.rs @@ -21,11 +21,102 @@ pub trait FileExt { /// /// The current file cursor is not affected by this function. /// + /// Note that similar to [`File::read`], it is not an error to return with a + /// short read. + /// + /// [`File::read`]: ../../../../std/fs/struct.File.html#method.read + fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> { + let bufs = &mut [IoSliceMut::new(buf)]; + self.read_vectored_at(bufs, offset) + } + + /// Reads a number of bytes starting from a given offset. + /// + /// Returns the number of bytes read. + /// + /// The offset is relative to the start of the file and thus independent + /// from the current cursor. + /// + /// The current file cursor is not affected by this function. + /// /// Note that similar to [`File::read_vectored`], it is not an error to /// return with a short read. /// /// [`File::read`]: ../../../../std/fs/struct.File.html#method.read_vectored - fn read_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize>; + fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize>; + + /// Reads the exact number of byte required to fill `buf` from the given offset. + /// + /// The offset is relative to the start of the file and thus independent + /// from the current cursor. + /// + /// The current file cursor is not affected by this function. + /// + /// Similar to [`Read::read_exact`] but uses [`read_at`] instead of `read`. + /// + /// [`Read::read_exact`]: ../../../../std/io/trait.Read.html#method.read_exact + /// [`read_at`]: #tymethod.read_at + /// + /// # Errors + /// + /// If this function encounters an error of the kind + /// [`ErrorKind::Interrupted`] then the error is ignored and the operation + /// will continue. + /// + /// If this function encounters an "end of file" before completely filling + /// the buffer, it returns an error of the kind [`ErrorKind::UnexpectedEof`]. + /// The contents of `buf` are unspecified in this case. + /// + /// If any other read error is encountered then this function immediately + /// returns. The contents of `buf` are unspecified in this case. + /// + /// If this function returns an error, it is unspecified how many bytes it + /// has read, but it will never read more than would be necessary to + /// completely fill the buffer. + /// + /// [`ErrorKind::Interrupted`]: ../../../../std/io/enum.ErrorKind.html#variant.Interrupted + /// [`ErrorKind::UnexpectedEof`]: ../../../../std/io/enum.ErrorKind.html#variant.UnexpectedEof + #[stable(feature = "rw_exact_all_at", since = "1.33.0")] + fn read_exact_at(&self, mut buf: &mut [u8], mut offset: u64) -> io::Result<()> { + while !buf.is_empty() { + match self.read_at(buf, offset) { + Ok(0) => break, + Ok(n) => { + let tmp = buf; + buf = &mut tmp[n..]; + offset += n as u64; + } + Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {} + Err(e) => return Err(e), + } + } + if !buf.is_empty() { + Err(io::Error::new(io::ErrorKind::UnexpectedEof, "failed to fill whole buffer")) + } else { + Ok(()) + } + } + + /// Writes a number of bytes starting from a given offset. + /// + /// Returns the number of bytes written. + /// + /// The offset is relative to the start of the file and thus independent + /// from the current cursor. + /// + /// The current file cursor is not affected by this function. + /// + /// When writing beyond the end of the file, the file is appropriately + /// extended and the intermediate bytes are initialized with the value 0. + /// + /// Note that similar to [`File::write`], it is not an error to return a + /// short write. + /// + /// [`File::write`]: ../../../../std/fs/struct.File.html#write.v + fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> { + let bufs = &[IoSlice::new(buf)]; + self.write_vectored_at(bufs, offset) + } /// Writes a number of bytes starting from a given offset. /// @@ -43,7 +134,49 @@ pub trait FileExt { /// short write. /// /// [`File::write`]: ../../../../std/fs/struct.File.html#method.write_vectored - fn write_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result<usize>; + fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result<usize>; + + /// Attempts to write an entire buffer starting from a given offset. + /// + /// The offset is relative to the start of the file and thus independent + /// from the current cursor. + /// + /// The current file cursor is not affected by this function. + /// + /// This method will continuously call [`write_at`] until there is no more data + /// to be written or an error of non-[`ErrorKind::Interrupted`] kind is + /// returned. This method will not return until the entire buffer has been + /// successfully written or such an error occurs. The first error that is + /// not of [`ErrorKind::Interrupted`] kind generated from this method will be + /// returned. + /// + /// # Errors + /// + /// This function will return the first error of + /// non-[`ErrorKind::Interrupted`] kind that [`write_at`] returns. + /// + /// [`ErrorKind::Interrupted`]: ../../../../std/io/enum.ErrorKind.html#variant.Interrupted + /// [`write_at`]: #tymethod.write_at + #[stable(feature = "rw_exact_all_at", since = "1.33.0")] + fn write_all_at(&self, mut buf: &[u8], mut offset: u64) -> io::Result<()> { + while !buf.is_empty() { + match self.write_at(buf, offset) { + Ok(0) => { + return Err(io::Error::new( + io::ErrorKind::WriteZero, + "failed to write whole buffer", + )); + } + Ok(n) => { + buf = &buf[n..]; + offset += n as u64 + } + Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {} + Err(e) => return Err(e), + } + } + Ok(()) + } /// Returns the current position within the file. /// @@ -105,11 +238,11 @@ pub trait FileExt { // FIXME: bind random_get maybe? - on crates.io for unix impl FileExt for fs::File { - fn read_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize> { + fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize> { self.as_inner().fd().pread(bufs, offset) } - fn write_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result<usize> { + fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result<usize> { self.as_inner().fd().pwrite(bufs, offset) } |
