about summary refs log tree commit diff
path: root/library/std/src
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2022-12-10 09:24:42 +0100
committerGitHub <noreply@github.com>2022-12-10 09:24:42 +0100
commiteb1159cbd811301fc6a681934ba930cf00bc85fa (patch)
treedd7cdabfc7d11cc7bda125c5220a3658409e7cbe /library/std/src
parent1ce18d2d658eb8b1625965e5a50d040d5c8f05c1 (diff)
parent24cd863a3815f7ae7828c9f161a0b3f863218106 (diff)
downloadrust-eb1159cbd811301fc6a681934ba930cf00bc85fa.tar.gz
rust-eb1159cbd811301fc6a681934ba930cf00bc85fa.zip
Rollup merge of #104901 - krtab:filetype_compare, r=the8472
Implement masking in FileType comparison on Unix

Fixes: https://github.com/rust-lang/rust/issues/104900
Diffstat (limited to 'library/std/src')
-rw-r--r--library/std/src/fs/tests.rs16
-rw-r--r--library/std/src/sys/unix/fs.rs20
2 files changed, 34 insertions, 2 deletions
diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs
index b8959316de1..4748ac9d97e 100644
--- a/library/std/src/fs/tests.rs
+++ b/library/std/src/fs/tests.rs
@@ -1551,3 +1551,19 @@ fn hiberfil_sys() {
     fs::metadata(hiberfil).unwrap();
     assert_eq!(true, hiberfil.exists());
 }
+
+/// Test that two different ways of obtaining the FileType give the same result.
+/// Cf. https://github.com/rust-lang/rust/issues/104900
+#[test]
+fn test_eq_direntry_metadata() {
+    let tmpdir = tmpdir();
+    let file_path = tmpdir.join("file");
+    File::create(file_path).unwrap();
+    for e in fs::read_dir(tmpdir.path()).unwrap() {
+        let e = e.unwrap();
+        let p = e.path();
+        let ft1 = e.file_type().unwrap();
+        let ft2 = p.metadata().unwrap().file_type();
+        assert_eq!(ft1, ft2);
+    }
+}
diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs
index 37a49f2d78a..fb8d06c6682 100644
--- a/library/std/src/sys/unix/fs.rs
+++ b/library/std/src/sys/unix/fs.rs
@@ -332,11 +332,23 @@ pub struct FileTimes {
     modified: Option<SystemTime>,
 }
 
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
+#[derive(Copy, Clone, Eq, Debug)]
 pub struct FileType {
     mode: mode_t,
 }
 
+impl PartialEq for FileType {
+    fn eq(&self, other: &Self) -> bool {
+        self.masked() == other.masked()
+    }
+}
+
+impl core::hash::Hash for FileType {
+    fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
+        self.masked().hash(state);
+    }
+}
+
 #[derive(Debug)]
 pub struct DirBuilder {
     mode: mode_t,
@@ -548,7 +560,11 @@ impl FileType {
     }
 
     pub fn is(&self, mode: mode_t) -> bool {
-        self.mode & libc::S_IFMT == mode
+        self.masked() == mode
+    }
+
+    fn masked(&self) -> mode_t {
+        self.mode & libc::S_IFMT
     }
 }