starnix_core/vfs/
fd_number.rs

1// Copyright 2021 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use std::fmt;
6use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
7
8use crate::vfs::FsStr;
9use starnix_syscalls::{SyscallArg, SyscallResult};
10use starnix_uapi::errors::Errno;
11use starnix_uapi::{AT_FDCWD, errno};
12
13// NB: We believe deriving Default (i.e., have a default FdNumber of 0) will be error-prone.
14#[derive(
15    Hash,
16    PartialEq,
17    Eq,
18    PartialOrd,
19    Ord,
20    Debug,
21    Copy,
22    Clone,
23    IntoBytes,
24    KnownLayout,
25    FromBytes,
26    Immutable,
27)]
28#[repr(transparent)]
29pub struct FdNumber(i32);
30
31impl FdNumber {
32    pub const AT_FDCWD: FdNumber = FdNumber(AT_FDCWD);
33
34    pub fn from_raw(n: i32) -> FdNumber {
35        FdNumber(n)
36    }
37
38    pub fn raw(&self) -> i32 {
39        self.0
40    }
41
42    /// Parses a file descriptor number from a byte string.
43    pub fn from_fs_str(s: &FsStr) -> Result<Self, Errno> {
44        let name = std::str::from_utf8(s).map_err(|_| errno!(EINVAL))?;
45        let num = name.parse::<i32>().map_err(|_| errno!(EINVAL))?;
46        Ok(FdNumber(num))
47    }
48}
49
50impl std::convert::From<FdNumber> for SyscallResult {
51    fn from(value: FdNumber) -> Self {
52        value.raw().into()
53    }
54}
55
56impl std::convert::From<SyscallArg> for FdNumber {
57    fn from(value: SyscallArg) -> Self {
58        FdNumber::from_raw(value.into())
59    }
60}
61
62impl std::str::FromStr for FdNumber {
63    type Err = Errno;
64
65    fn from_str(s: &str) -> Result<Self, Self::Err> {
66        Ok(FdNumber::from_raw(s.parse::<i32>().map_err(|e| errno!(EINVAL, e))?))
67    }
68}
69
70impl fmt::Display for FdNumber {
71    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
72        write!(f, "fd({})", self.0)
73    }
74}