summary refs log tree commit diff
path: root/ripple/minitrace/src/syscall_abi/fd.rs
blob: cd0c0084d120b07d9ff3d2149b11cc35da0f9d6e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
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,
		})
	}
}