summaryrefslogtreecommitdiff
path: root/vendor/same-file/src/win.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/same-file/src/win.rs')
-rw-r--r--vendor/same-file/src/win.rs172
1 files changed, 0 insertions, 172 deletions
diff --git a/vendor/same-file/src/win.rs b/vendor/same-file/src/win.rs
deleted file mode 100644
index 69247399..00000000
--- a/vendor/same-file/src/win.rs
+++ /dev/null
@@ -1,172 +0,0 @@
-use std::fs::File;
-use std::hash::{Hash, Hasher};
-use std::io;
-use std::os::windows::io::{AsRawHandle, IntoRawHandle, RawHandle};
-use std::path::Path;
-
-use winapi_util as winutil;
-
-// For correctness, it is critical that both file handles remain open while
-// their attributes are checked for equality. In particular, the file index
-// numbers on a Windows stat object are not guaranteed to remain stable over
-// time.
-//
-// See the docs and remarks on MSDN:
-// https://msdn.microsoft.com/en-us/library/windows/desktop/aa363788(v=vs.85).aspx
-//
-// It gets worse. It appears that the index numbers are not always
-// guaranteed to be unique. Namely, ReFS uses 128 bit numbers for unique
-// identifiers. This requires a distinct syscall to get `FILE_ID_INFO`
-// documented here:
-// https://msdn.microsoft.com/en-us/library/windows/desktop/hh802691(v=vs.85).aspx
-//
-// It seems straight-forward enough to modify this code to use
-// `FILE_ID_INFO` when available (minimum Windows Server 2012), but I don't
-// have access to such Windows machines.
-//
-// Two notes.
-//
-// 1. Java's NIO uses the approach implemented here and appears to ignore
-// `FILE_ID_INFO` altogether. So Java's NIO and this code are
-// susceptible to bugs when running on a file system where
-// `nFileIndex{Low,High}` are not unique.
-//
-// 2. LLVM has a bug where they fetch the id of a file and continue to use
-// it even after the handle has been closed, so that uniqueness is no
-// longer guaranteed (when `nFileIndex{Low,High}` are unique).
-// bug report: http://lists.llvm.org/pipermail/llvm-bugs/2014-December/037218.html
-//
-// All said and done, checking whether two files are the same on Windows
-// seems quite tricky. Moreover, even if the code is technically incorrect,
-// it seems like the chances of actually observing incorrect behavior are
-// extremely small. Nevertheless, we mitigate this by checking size too.
-//
-// In the case where this code is erroneous, two files will be reported
-// as equivalent when they are in fact distinct. This will cause the loop
-// detection code to report a false positive, which will prevent descending
-// into the offending directory. As far as failure modes goes, this isn't
-// that bad.
-
-#[derive(Debug)]
-pub struct Handle {
- kind: HandleKind,
- key: Option<Key>,
-}
-
-#[derive(Debug)]
-enum HandleKind {
- /// Used when opening a file or acquiring ownership of a file.
- Owned(winutil::Handle),
- /// Used for stdio.
- Borrowed(winutil::HandleRef),
-}
-
-#[derive(Debug, Eq, PartialEq, Hash)]
-struct Key {
- volume: u64,
- index: u64,
-}
-
-impl Eq for Handle {}
-
-impl PartialEq for Handle {
- fn eq(&self, other: &Handle) -> bool {
- // Need this branch to satisfy `Eq` since `Handle`s with
- // `key.is_none()` wouldn't otherwise.
- if self as *const Handle == other as *const Handle {
- return true;
- } else if self.key.is_none() || other.key.is_none() {
- return false;
- }
- self.key == other.key
- }
-}
-
-impl AsRawHandle for crate::Handle {
- fn as_raw_handle(&self) -> RawHandle {
- match self.0.kind {
- HandleKind::Owned(ref h) => h.as_raw_handle(),
- HandleKind::Borrowed(ref h) => h.as_raw_handle(),
- }
- }
-}
-
-impl IntoRawHandle for crate::Handle {
- fn into_raw_handle(self) -> RawHandle {
- match self.0.kind {
- HandleKind::Owned(h) => h.into_raw_handle(),
- HandleKind::Borrowed(h) => h.as_raw_handle(),
- }
- }
-}
-
-impl Hash for Handle {
- fn hash<H: Hasher>(&self, state: &mut H) {
- self.key.hash(state);
- }
-}
-
-impl Handle {
- pub fn from_path<P: AsRef<Path>>(p: P) -> io::Result<Handle> {
- let h = winutil::Handle::from_path_any(p)?;
- let info = winutil::file::information(&h)?;
- Ok(Handle::from_info(HandleKind::Owned(h), info))
- }
-
- pub fn from_file(file: File) -> io::Result<Handle> {
- let h = winutil::Handle::from_file(file);
- let info = winutil::file::information(&h)?;
- Ok(Handle::from_info(HandleKind::Owned(h), info))
- }
-
- fn from_std_handle(h: winutil::HandleRef) -> io::Result<Handle> {
- match winutil::file::information(&h) {
- Ok(info) => Ok(Handle::from_info(HandleKind::Borrowed(h), info)),
- // In a Windows console, if there is no pipe attached to a STD
- // handle, then GetFileInformationByHandle will return an error.
- // We don't really care. The only thing we care about is that
- // this handle is never equivalent to any other handle, which is
- // accomplished by setting key to None.
- Err(_) => Ok(Handle { kind: HandleKind::Borrowed(h), key: None }),
- }
- }
-
- fn from_info(
- kind: HandleKind,
- info: winutil::file::Information,
- ) -> Handle {
- Handle {
- kind: kind,
- key: Some(Key {
- volume: info.volume_serial_number(),
- index: info.file_index(),
- }),
- }
- }
-
- pub fn stdin() -> io::Result<Handle> {
- Handle::from_std_handle(winutil::HandleRef::stdin())
- }
-
- pub fn stdout() -> io::Result<Handle> {
- Handle::from_std_handle(winutil::HandleRef::stdout())
- }
-
- pub fn stderr() -> io::Result<Handle> {
- Handle::from_std_handle(winutil::HandleRef::stderr())
- }
-
- pub fn as_file(&self) -> &File {
- match self.kind {
- HandleKind::Owned(ref h) => h.as_file(),
- HandleKind::Borrowed(ref h) => h.as_file(),
- }
- }
-
- pub fn as_file_mut(&mut self) -> &mut File {
- match self.kind {
- HandleKind::Owned(ref mut h) => h.as_file_mut(),
- HandleKind::Borrowed(ref mut h) => h.as_file_mut(),
- }
- }
-}