summary refs log tree commit diff
path: root/ripple/minitrace/src/syscall_abi/fd.rs
diff options
context:
space:
mode:
Diffstat (limited to 'ripple/minitrace/src/syscall_abi/fd.rs')
-rw-r--r--ripple/minitrace/src/syscall_abi/fd.rs62
1 files changed, 62 insertions, 0 deletions
diff --git a/ripple/minitrace/src/syscall_abi/fd.rs b/ripple/minitrace/src/syscall_abi/fd.rs
new file mode 100644
index 0000000..cd0c008
--- /dev/null
+++ b/ripple/minitrace/src/syscall_abi/fd.rs
@@ -0,0 +1,62 @@
+// SPDX-FileCopyrightText: edef <edef@unfathomable.blue>
+// SPDX-License-Identifier: OSL-3.0
+
+use {
+	super::SyscallArg,
+	std::fmt::{self, Debug},
+};
+
+#[derive(Clone, Copy, Eq, PartialEq)]
+pub(crate) struct FileDesc(i32);
+
+impl Debug for FileDesc {
+	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+		write!(f, "{}", self.0)
+	}
+}
+
+impl SyscallArg for FileDesc {
+	fn try_from_reg(reg: u64) -> Option<Self> {
+		Some(match i32::try_from_reg(reg)? {
+			fd @ 0..=i32::MAX => FileDesc(fd),
+			_ => return None,
+		})
+	}
+}
+
+impl SyscallArg for Option<FileDesc> {
+	fn try_from_reg(reg: u64) -> Option<Self> {
+		Some(match i32::try_from_reg(reg)? {
+			-1 => None,
+			fd @ 0..=i32::MAX => Some(FileDesc(fd)),
+			_ => return None,
+		})
+	}
+}
+
+#[derive(Clone, Copy, Eq, PartialEq)]
+pub(crate) enum DirFd {
+	Cwd,
+	Fd(FileDesc),
+}
+
+const AT_FDCWD: i32 = -100;
+
+impl Debug for DirFd {
+	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+		match *self {
+			DirFd::Cwd => write!(f, "AT_FDCWD"),
+			DirFd::Fd(FileDesc(fd)) => write!(f, "{fd}"),
+		}
+	}
+}
+
+impl SyscallArg for DirFd {
+	fn try_from_reg(reg: u64) -> Option<Self> {
+		Some(match i32::try_from_reg(reg)? {
+			AT_FDCWD => Self::Cwd,
+			fd @ 0..=i32::MAX => DirFd::Fd(FileDesc(fd)),
+			_ => return None,
+		})
+	}
+}