commit 45f249f3ad1c40ad254c3fd026187744acaa4b99
parent e15652b32701ef43535fe018f05ebf6f3718ecfc
Author: Drew DeVault <sir@cmpwn.com>
Date: Wed, 24 Feb 2021 12:39:00 -0500
fs: implement mode_str
Diffstat:
M | fs/util.ha | | | 41 | ++++++++++++++++++++++++++++++++++++++--- |
1 file changed, 38 insertions(+), 3 deletions(-)
diff --git a/fs/util.ha b/fs/util.ha
@@ -1,4 +1,6 @@
+use fmt;
use io;
+use strio;
// Returns a human-friendly representation of an error.
export fn errstr(err: error) const str = match (err) {
@@ -7,10 +9,43 @@ export fn errstr(err: error) const str = match (err) {
err: io::error => io::errstr(err),
};
-// Converts a mode into a Unix-like mode string (e.g. "-rw-r--r--")
+// Converts a mode into a Unix-like mode string (e.g. "-rw-r--r--"). The string
+// is statically allocated, use [strings::dup] to duplicate it or it will be
+// overwritten on subsequent calls.
export fn mode_str(m: mode) const str = {
- // TODO: blocked on bufio::fixed
- abort();
+ // TODO: This could be more efficient without fmt
+ static let buf: [11]u8 = [0...];
+ let sink = strio::fixed(buf);
+ fmt::fprintf(sink, "{}{}{}{}{}{}{}{}{}{}",
+ if (m & mode::DIR == mode::DIR) "d"
+ else if (m & mode::FIFO == mode::FIFO) "p"
+ else if (m & mode::SOCK == mode::SOCK) "s"
+ else "-",
+ if (m & mode::USER_R == mode::USER_R) "r" else "-",
+ if (m & mode::USER_W == mode::USER_W) "w" else "-",
+ if (m & mode::SETUID == mode::SETUID) "s"
+ else if (m & mode::USER_X == mode::USER_X) "x"
+ else "-",
+ if (m & mode::GROUP_R == mode::GROUP_R) "r" else "-",
+ if (m & mode::GROUP_W == mode::GROUP_W) "w" else "-",
+ if (m & mode::SETGID == mode::SETGID) "s"
+ else if (m & mode::GROUP_X == mode::GROUP_X) "x"
+ else "-",
+ if (m & mode::OTHER_R == mode::OTHER_R) "r" else "-",
+ if (m & mode::OTHER_W == mode::OTHER_W) "w" else "-",
+ if (m & mode::STICKY == mode::STICKY) "t"
+ else if (m & mode::OTHER_X == mode::OTHER_X) "x"
+ else "-",
+ );
+ return strio::string(sink);
+};
+
+@test fn mode_str() void = {
+ assert(mode_str(0o777: mode) == "-rwxrwxrwx");
+ assert(mode_str(mode::DIR | 0o755: mode) == "drwxr-xr-x");
+ assert(mode_str(0o755: mode | mode::SETUID) == "-rwsr-xr-x");
+ assert(mode_str(0o644: mode) == "-rw-r--r--");
+ assert(mode_str(0: mode) == "----------");
};
// Returns the permission bits of a file mode.