Skip to content

Commit 3ed63ff

Browse files
committed
Add fd registry
1 parent 9cfdb15 commit 3ed63ff

2 files changed

Lines changed: 55 additions & 0 deletions

File tree

‎libcc2rs/src/fd.rs‎

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright (c) 2022-present INESC-ID.
2+
// Distributed under the MIT license that can be found in the LICENSE file.
3+
4+
use std::cell::RefCell;
5+
use std::os::fd::{AsFd, AsRawFd, BorrowedFd, OwnedFd};
6+
7+
pub struct FdRegistry {
8+
fds: Vec<Option<OwnedFd>>,
9+
}
10+
11+
thread_local! {
12+
static FD_REGISTRY: RefCell<FdRegistry> = const { RefCell::new(FdRegistry { fds: Vec::new() }) };
13+
}
14+
15+
impl FdRegistry {
16+
pub fn register(fd: OwnedFd) -> i32 {
17+
let raw = fd.as_raw_fd();
18+
FD_REGISTRY.with(|r| {
19+
let fds = &mut r.borrow_mut().fds;
20+
let idx = raw as usize;
21+
if fds.len() <= idx {
22+
fds.resize_with(idx + 1, || None);
23+
}
24+
assert!(fds[idx].is_none(), "ub: fd registry collision on fd {raw}");
25+
fds[idx] = Some(fd);
26+
});
27+
raw
28+
}
29+
30+
pub fn with_fd<R>(fd: i32, f: impl FnOnce(BorrowedFd<'_>) -> R) -> R {
31+
FD_REGISTRY.with(|r| {
32+
let reg = r.borrow();
33+
let owned = reg
34+
.fds
35+
.get(fd as usize)
36+
.and_then(|slot| slot.as_ref())
37+
.unwrap_or_else(|| panic!("ub: bad fd {fd}"));
38+
f(owned.as_fd())
39+
})
40+
}
41+
42+
pub fn close(fd: i32) -> i32 {
43+
FD_REGISTRY.with(|r| {
44+
r.borrow_mut()
45+
.fds
46+
.get_mut(fd as usize)
47+
.and_then(|slot| slot.take())
48+
.unwrap_or_else(|| panic!("ub: bad fd {fd}"))
49+
});
50+
0
51+
}
52+
}

‎libcc2rs/src/lib.rs‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,7 @@ pub use compat::*;
3737
mod va_args;
3838
pub use va_args::*;
3939

40+
mod fd;
41+
pub use fd::*;
42+
4043
pub use libcc2rs_macros::{goto, goto_block, switch};

0 commit comments

Comments
 (0)