Repository: Canop/broot (language: rust)

Issue:
broot fail to recognize `suid` and `sgid` bits when showing permission
This is a comparison between `broot` and `lsd`, both showing the same file `mount.cifs`, which has permission `rwsr-sr-x`:

![comparison between `broot` and `lsd`](https://github.com/Canop/broot/assets/31986081/c1e7c014-1fb9-4295-bb11-74a8fbc6b4c9)

The two `s` in permission means `setuid` and `setgid` respectively, but broot does not recognize those bit and only shows `x` instead.


Discussion / hints:
I think this is the code involved:

https://github.com/Canop/broot/blob/df315d6b11a74b289c5276e741b854c0d47738ae/src/display/permissions.rs#L63-L67

The [`has_extra`](https://docs.rs/umask/latest/umask/struct.Mode.html#method.has_extra) method can check the correspond permission.
Yes. 
As you searched til the umask crate, you may as well make a PR, right ?

Fix patch:
diff --git a/src/display/permissions.rs b/src/display/permissions.rs
index 241795db..3cfd3bae 100644
--- a/src/display/permissions.rs
+++ b/src/display/permissions.rs
@@ -7,10 +7,7 @@ use {
         skin::StyleMap,
         tree::{Tree, TreeLine},
     },
-    std::{
-        io::Write,
-        os::unix::fs::MetadataExt,
-    },
+    std::{io::Write, os::unix::fs::MetadataExt},
     umask::*,
 };
 
@@ -22,13 +19,16 @@ pub struct PermWriter<'s> {
 }
 
 impl<'s> PermWriter<'s> {
-
     pub fn new(
         skin: &'s StyleMap,
         max_user_len: usize,
         max_group_len: usize,
     ) -> Self {
-        Self { skin, max_user_len, max_group_len }
+        Self {
+            skin,
+            max_user_len,
+            max_group_len,
+        }
     }
 
     pub fn for_tree(
@@ -61,9 +61,9 @@ impl<'s> PermWriter<'s> {
             cw.queue_char(n_style, '_')?;
         }
         if mode.has(USER_EXEC) {
-            cw.queue_char(x_style, 'x')?;
+            cw.queue_char(x_style, if mode.has_extra(SETUID) { 's' } else { 'x' })?;
         } else {
-            cw.queue_char(n_style, '_')?;
+            cw.queue_char(n_style, if mode.has_extra(SETUID) { 'S' } else { '_' })?;
         }
 
         if mode.has(GROUP_READ) {
@@ -77,9 +77,9 @@ impl<'s> PermWriter<'s> {
             cw.queue_char(n_style, '_')?;
         }
         if mode.has(GROUP_EXEC) {
-            cw.queue_char(x_style, 'x')?;
+            cw.queue_char(x_style, if mode.has_extra(SETGID) { 's' } else { 'x' })?;
         } else {
-            cw.queue_char(n_style, '_')?;
+            cw.queue_char(n_style, if mode.has_extra(SETGID) { 'S' } else { '_' })?;
         }
 
         if mode.has(OTHERS_READ) {
@@ -93,9 +93,9 @@ impl<'s> PermWriter<'s> {
             cw.queue_char(n_style, '_')?;
         }
         if mode.has(OTHERS_EXEC) {
-            cw.queue_char(x_style, 'x')?;
+            cw.queue_char(x_style, if mode.has_extra(STICKY) { 't' } else { 'x' })?;
         } else {
-            cw.queue_char(n_style, '_')?;
+            cw.queue_char(n_style, if mode.has_extra(STICKY) { 'T' } else { '_' })?;
         }
 
         Ok(())
@@ -127,7 +127,6 @@ impl<'s> PermWriter<'s> {
             9 + 1 + self.max_user_len + 1 + self.max_group_len + 1
         })
     }
-
 }
 
 fn user_group_max_lengths(tree: &Tree) -> (usize, usize) {


Test patch: