about summary refs log tree commit diff
path: root/src/libstd/sys/windows/ext
diff options
context:
space:
mode:
authorTobias Bucher <tobiasbucher5991@gmail.com>2016-08-16 01:11:33 +0200
committerTobias Bucher <tobiasbucher5991@gmail.com>2016-10-09 10:48:07 +0200
commitb3f2644b66647d47338051d783cae8e661312472 (patch)
tree681ee7fee5cea595cfadbcaf44e7219b61c31338 /src/libstd/sys/windows/ext
parentb98cc352cbb428f3c9a0e608bc57a83109a26a57 (diff)
downloadrust-b3f2644b66647d47338051d783cae8e661312472.tar.gz
rust-b3f2644b66647d47338051d783cae8e661312472.zip
Implement reading and writing atomically at certain offsets
These functions allow to read from and write to a file in one atomic
action from multiple threads, avoiding the race between the seek and the
read.

The functions are named `{read,write}_at` on non-Windows (which don't
change the file cursor), and `seek_{read,write}` on Windows (which
change the file cursor).
Diffstat (limited to 'src/libstd/sys/windows/ext')
-rw-r--r--src/libstd/sys/windows/ext/fs.rs51
-rw-r--r--src/libstd/sys/windows/ext/mod.rs2
2 files changed, 52 insertions, 1 deletions
diff --git a/src/libstd/sys/windows/ext/fs.rs b/src/libstd/sys/windows/ext/fs.rs
index 4388a0bdff2..1e2b8bf38fa 100644
--- a/src/libstd/sys/windows/ext/fs.rs
+++ b/src/libstd/sys/windows/ext/fs.rs
@@ -12,12 +12,61 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use fs::{OpenOptions, Metadata};
+use fs::{self, OpenOptions, Metadata};
 use io;
 use path::Path;
 use sys;
 use sys_common::{AsInnerMut, AsInner};
 
+/// Windows-specific extensions to `File`
+#[unstable(feature = "file_offset", issue = "35918")]
+pub trait FileExt {
+    /// Seeks to a given position and reads a number of bytes.
+    ///
+    /// 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 cursor **is** affected by this
+    /// function, it is set to the end of the read.
+    ///
+    /// Reading beyond the end of the file will always return with a length of
+    /// 0.
+    ///
+    /// Note that similar to `File::read`, it is not an error to return with a
+    /// short read. When returning from such a short read, the file pointer is
+    /// still updated.
+    #[unstable(feature = "file_offset", issue = "35918")]
+    fn seek_read(&self, buf: &mut [u8], offset: u64) -> io::Result<usize>;
+
+    /// Seeks to a given position and writes a number of bytes.
+    ///
+    /// 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 cursor **is** affected by this
+    /// function, it is set to the end of the write.
+    ///
+    /// When writing beyond the end of the file, the file is appropiately
+    /// extended and the intermediate bytes are left uninitialized.
+    ///
+    /// Note that similar to `File::write`, it is not an error to return a
+    /// short write. When returning from such a short write, the file pointer
+    /// is still updated.
+    #[unstable(feature = "file_offset", issue = "35918")]
+    fn seek_write(&self, buf: &[u8], offset: u64) -> io::Result<usize>;
+}
+
+#[unstable(feature = "file_offset", issue = "35918")]
+impl FileExt for fs::File {
+    fn seek_read(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
+        self.as_inner().read_at(buf, offset)
+    }
+
+    fn seek_write(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
+        self.as_inner().write_at(buf, offset)
+    }
+}
+
 /// Windows-specific extensions to `OpenOptions`
 #[stable(feature = "open_options_ext", since = "1.10.0")]
 pub trait OpenOptionsExt {
diff --git a/src/libstd/sys/windows/ext/mod.rs b/src/libstd/sys/windows/ext/mod.rs
index c3578fdfdb1..932bb5e9564 100644
--- a/src/libstd/sys/windows/ext/mod.rs
+++ b/src/libstd/sys/windows/ext/mod.rs
@@ -36,4 +36,6 @@ pub mod prelude {
     pub use super::ffi::{OsStrExt, OsStringExt};
     #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
     pub use super::fs::{OpenOptionsExt, MetadataExt};
+    #[doc(no_inline)] #[unstable(feature = "file_offset", issue = "35918")]
+    pub use super::fs::FileExt;
 }