Skip to content

Commit 4f8cdfc

Browse files
committed
Adds openat
1 parent 279e563 commit 4f8cdfc

File tree

2 files changed

+52
-0
lines changed

2 files changed

+52
-0
lines changed

src/fd/mod.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
use crate::errno::Errno;
2+
use crate::fcntl::OpenFlags;
3+
use crate::pcpu::Pcpu;
4+
use crate::thread::Thread;
5+
use crate::uio::UioSeg;
6+
use crate::Kernel;
7+
use core::ffi::{c_char, c_int};
8+
use core::marker::PhantomData;
9+
10+
/// # Safety
11+
/// `path` cannot be null and must point to a null-terminated string if `seg` is [`UioSeg::Kernel`].
12+
pub unsafe fn openat<K: Kernel>(
13+
kern: K,
14+
fd: c_int,
15+
path: *const c_char,
16+
seg: UioSeg,
17+
flags: OpenFlags,
18+
mode: c_int,
19+
) -> Result<OwnedFd<K>, Errno> {
20+
let td = K::Pcpu::curthread();
21+
let errno = kern.kern_openat(td, fd, path, seg, flags, mode);
22+
23+
match Errno::new(errno) {
24+
Some(v) => Err(v),
25+
None => Ok(OwnedFd {
26+
kern,
27+
fd: (*td).ret(0).try_into().unwrap(),
28+
phantom: PhantomData,
29+
}),
30+
}
31+
}
32+
33+
/// RAII struct to call [`Kernel::kern_close()`] when dropped.
34+
pub struct OwnedFd<K: Kernel> {
35+
kern: K,
36+
fd: c_int,
37+
phantom: PhantomData<*const ()>, // For !Send.
38+
}
39+
40+
impl<K: Kernel> Drop for OwnedFd<K> {
41+
fn drop(&mut self) {
42+
// This drop must be called from the same process as the one that created the FD.
43+
assert_eq!(
44+
unsafe { self.kern.kern_close(K::Pcpu::curthread(), self.fd) },
45+
0
46+
);
47+
}
48+
}

src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ pub use okf_macros::*;
1818

1919
pub mod errno;
2020
pub mod fcntl;
21+
pub mod fd;
2122
pub mod file;
2223
pub mod lock;
2324
pub mod malloc;
@@ -100,6 +101,9 @@ pub trait Kernel: MappedKernel {
100101
/// If `addr` is not valid.
101102
unsafe fn free(self, addr: *mut u8, ty: *mut Self::Malloc);
102103

104+
/// Note that this method return an errno, not a FD! You can grab the FD from `td_retval[0]` if
105+
/// this method return zero.
106+
///
103107
/// # Safety
104108
/// - `td` cannot be null.
105109
/// - `path` cannot be null and must point to a null-terminated string if `seg` is [`UioSeg::Kernel`].

0 commit comments

Comments
 (0)