Skip to content

Commit a62348f

Browse files
feat(syscall): cleanup fd handling
Signed-off-by: Anhad Singh <[email protected]>
1 parent 255e4c3 commit a62348f

File tree

9 files changed

+156
-161
lines changed

9 files changed

+156
-161
lines changed

src/aero_kernel/src/fs/ext2/mod.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -477,8 +477,17 @@ impl INodeInterface for INode {
477477
Ok(())
478478
}
479479

480-
fn truncate(&self, _size: usize) -> super::Result<()> {
481-
log::warn!("ext2::truncate is a stub!");
480+
fn truncate(&self, size: usize) -> super::Result<()> {
481+
let inode = self.inode.read();
482+
483+
if inode.size() > size {
484+
// grow inode
485+
log::warn!("ext2::truncate(at=grow) is a stub!");
486+
} else if inode.size() < size {
487+
log::warn!("ext2::truncate(at=shrink) is a stub!");
488+
// shrink inode
489+
}
490+
482491
Ok(())
483492
}
484493

src/aero_kernel/src/socket/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ pub enum SocketAddrRef<'a> {
4444
}
4545

4646
impl<'a> SocketAddrRef<'a> {
47-
pub fn from_family(address: VirtAddr, family: u32) -> Result<Self, SyscallError> {
47+
pub fn from_family(address: VirtAddr, family: u32) -> Result<Self> {
4848
match family {
4949
AF_UNIX => Ok(SocketAddrRef::Unix(address.read_mut::<SocketAddrUnix>()?)),
5050
AF_INET => Ok(SocketAddrRef::INet(address.read_mut::<SocketAddrInet>()?)),
@@ -54,7 +54,7 @@ impl<'a> SocketAddrRef<'a> {
5454
}
5555
}
5656

57-
pub fn from_ifreq(ifreq: &IfReq) -> Result<Self, SyscallError> {
57+
pub fn from_ifreq(ifreq: &IfReq) -> Result<Self> {
5858
// SAFETY???
5959
let family = unsafe { ifreq.data.addr.sa_family };
6060
SocketAddrRef::from_family(

src/aero_kernel/src/syscall/fs.rs

Lines changed: 82 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -15,55 +15,86 @@
1515
// You should have received a copy of the GNU General Public License
1616
// along with Aero. If not, see <https://www.gnu.org/licenses/>.
1717

18+
use core::fmt;
19+
1820
use aero_syscall::prelude::*;
1921
use aero_syscall::signal::SigProcMask;
2022
use aero_syscall::{OpenFlags, Stat, SyscallError, TimeSpec, AT_FDCWD};
23+
use alloc::sync::Arc;
2124

2225
use crate::fs::cache::{self, DirCacheImpl};
2326
use crate::fs::epoll::EPoll;
2427
use crate::fs::eventfd::EventFd;
25-
use crate::fs::file_table::DuplicateHint;
28+
use crate::fs::file_table::{DuplicateHint, FileHandle};
2629
use crate::fs::inode::{DirEntry, PollTable};
2730
use crate::fs::pipe::Pipe;
2831
use crate::fs::{self, lookup_path, LookupMode};
2932
use crate::userland::scheduler;
3033

3134
use crate::fs::Path;
3235

33-
#[syscall]
34-
pub fn write(fd: usize, buffer: &[u8]) -> Result<usize, SyscallError> {
35-
let handle = scheduler::get_scheduler()
36-
.current_task()
37-
.file_table
38-
.get_handle(fd)
39-
.ok_or(SyscallError::EBADFD)?;
36+
#[derive(Debug, Copy, Clone)]
37+
pub struct FileDescriptor(usize);
38+
39+
impl FileDescriptor {
40+
/// Returns the file handle associated with this file descriptor.
41+
///
42+
/// ## Errors
43+
/// * `EBADFD`: The file descriptor is not a valid open file descriptor.
44+
pub fn handle(&self) -> aero_syscall::Result<Arc<FileHandle>> {
45+
scheduler::current_thread()
46+
.file_table
47+
.get_handle(self.0)
48+
.ok_or(SyscallError::EBADFD)
49+
}
50+
}
51+
52+
impl fmt::Display for FileDescriptor {
53+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
54+
if let Ok(file_handle) = self.handle() {
55+
let path = file_handle.inode.absolute_path_str();
56+
write!(f, "{{ {} -> {} }}", self.0, path)
57+
} else {
58+
// invalid file descriptor
59+
write!(f, "{{ {} -> INVALID }}", self.0)
60+
}
61+
}
62+
}
4063

64+
impl super::SysArg for FileDescriptor {
65+
fn from_usize(value: usize) -> Self {
66+
Self(value)
67+
}
68+
}
69+
70+
impl Into<usize> for FileDescriptor {
71+
fn into(self) -> usize {
72+
self.0
73+
}
74+
}
75+
76+
#[syscall]
77+
pub fn write(fd: FileDescriptor, buffer: &[u8]) -> Result<usize, SyscallError> {
4178
// FIXME(heck for xeyes): fnctl should update the open flags!
4279
//
4380
// if handle
4481
// .flags
4582
// .intersects(OpenFlags::O_WRONLY | OpenFlags::O_RDWR)
4683
// {
47-
Ok(handle.write(buffer)?)
84+
Ok(fd.handle()?.write(buffer)?)
4885
// } else {
4986
// Err(SyscallError::EACCES)
5087
// }
5188
}
5289

5390
#[syscall]
54-
pub fn read(fd: usize, buffer: &mut [u8]) -> Result<usize, SyscallError> {
55-
let handle = scheduler::get_scheduler()
56-
.current_task()
57-
.file_table
58-
.get_handle(fd)
59-
.ok_or(SyscallError::EBADFD)?;
60-
91+
pub fn read(fd: FileDescriptor, buffer: &mut [u8]) -> Result<usize, SyscallError> {
6192
// if handle
6293
// .flags
6394
// .read()
6495
// .intersects(OpenFlags::O_RDONLY | OpenFlags::O_RDWR)
6596
// {
66-
Ok(handle.read(buffer)?)
97+
Ok(fd.handle()?.read(buffer)?)
6798
// } else {
6899
// Err(SyscallError::EACCES)
69100
// }
@@ -111,42 +142,37 @@ pub fn open(fd: usize, path: &Path, mode: usize) -> Result<usize, SyscallError>
111142
}
112143

113144
#[syscall]
114-
pub fn dup(fd: usize, flags: usize) -> Result<usize, SyscallError> {
145+
pub fn dup(fd: FileDescriptor, flags: usize) -> Result<usize, SyscallError> {
115146
let task = scheduler::get_scheduler().current_task();
116147
let flags = OpenFlags::from_bits(flags).ok_or(SyscallError::EINVAL)? & OpenFlags::O_CLOEXEC;
117148

118-
task.file_table.duplicate(fd, DuplicateHint::Any, flags)
149+
task.file_table
150+
.duplicate(fd.into(), DuplicateHint::Any, flags)
119151
}
120152

121153
#[syscall]
122-
pub fn dup2(fd: usize, new_fd: usize, flags: usize) -> Result<usize, SyscallError> {
154+
pub fn dup2(fd: FileDescriptor, new_fd: usize, flags: usize) -> Result<usize, SyscallError> {
123155
let task = scheduler::get_scheduler().current_task();
124156
let flags = OpenFlags::from_bits(flags).ok_or(SyscallError::EINVAL)? & OpenFlags::O_CLOEXEC;
125157

126158
task.file_table
127-
.duplicate(fd, DuplicateHint::Exact(new_fd), flags)
159+
.duplicate(fd.into(), DuplicateHint::Exact(new_fd), flags)
128160
}
129161

130162
#[syscall]
131-
pub fn getdents(fd: usize, buffer: &mut [u8]) -> Result<usize, SyscallError> {
132-
let handle = scheduler::get_scheduler()
133-
.current_task()
134-
.file_table
135-
.get_handle(fd)
136-
.ok_or(SyscallError::EBADFD)?;
137-
138-
Ok(handle.get_dents(buffer)?)
163+
pub fn getdents(fd: FileDescriptor, buffer: &mut [u8]) -> Result<usize, SyscallError> {
164+
Ok(fd.handle()?.get_dents(buffer)?)
139165
}
140166

141167
#[syscall]
142-
pub fn close(fd: usize) -> Result<usize, SyscallError> {
168+
pub fn close(fd: FileDescriptor) -> Result<usize, SyscallError> {
143169
let res = scheduler::get_scheduler()
144170
.current_task()
145171
.file_table
146-
.close_file(fd);
172+
.close_file(fd.into());
147173

148174
if res {
149-
Ok(0x00)
175+
Ok(0)
150176
} else {
151177
// FD isn't a valid open file descriptor.
152178
Err(SyscallError::EBADFD)
@@ -163,7 +189,7 @@ pub fn chdir(path: &str) -> Result<usize, SyscallError> {
163189
}
164190

165191
scheduler::get_scheduler().current_task().set_cwd(inode);
166-
Ok(0x00)
192+
Ok(0)
167193
}
168194

169195
#[syscall]
@@ -234,12 +260,8 @@ pub fn getcwd(buffer: &mut [u8]) -> Result<usize, SyscallError> {
234260
}
235261

236262
#[syscall]
237-
pub fn ioctl(fd: usize, command: usize, argument: usize) -> Result<usize, SyscallError> {
238-
let handle = scheduler::get_scheduler()
239-
.current_task()
240-
.file_table
241-
.get_handle(fd)
242-
.ok_or(SyscallError::EBADFD)?;
263+
pub fn ioctl(fd: FileDescriptor, command: usize, argument: usize) -> Result<usize, SyscallError> {
264+
let handle = fd.handle()?;
243265

244266
match command {
245267
// Sets the close-on-exec file descriptor flag. This is equivalent
@@ -262,13 +284,8 @@ pub fn ioctl(fd: usize, command: usize, argument: usize) -> Result<usize, Syscal
262284
}
263285

264286
#[syscall]
265-
pub fn seek(fd: usize, offset: usize, whence: usize) -> Result<usize, SyscallError> {
266-
let handle = scheduler::get_scheduler()
267-
.current_task()
268-
.file_table
269-
.get_handle(fd)
270-
.ok_or(SyscallError::EBADFD)?;
271-
287+
pub fn seek(fd: FileDescriptor, offset: usize, whence: usize) -> Result<usize, SyscallError> {
288+
let handle = fd.handle()?;
272289
Ok(handle.seek(offset as isize, aero_syscall::SeekWhence::from(whence))?)
273290
}
274291

@@ -347,12 +364,8 @@ const SETFL_MASK: OpenFlags = OpenFlags::from_bits_truncate(
347364
);
348365

349366
#[syscall]
350-
pub fn fcntl(fd: usize, command: usize, arg: usize) -> Result<usize, SyscallError> {
351-
let handle = scheduler::get_scheduler()
352-
.current_task()
353-
.file_table
354-
.get_handle(fd)
355-
.ok_or(SyscallError::EBADFD)?;
367+
pub fn fcntl(fd: FileDescriptor, command: usize, arg: usize) -> Result<usize, SyscallError> {
368+
let handle = fd.handle()?;
356369

357370
match command {
358371
// F_DUPFD_CLOEXEC and F_DUPFD:
@@ -364,19 +377,17 @@ pub fn fcntl(fd: usize, command: usize, arg: usize) -> Result<usize, SyscallErro
364377
//
365378
// F_DUPFD_CLOEXEC additionally sets the close-on-exec flag for the duplicate
366379
// file descriptor.
367-
aero_syscall::prelude::F_DUPFD => scheduler::get_scheduler()
368-
.current_task()
369-
.file_table
370-
.duplicate(fd, DuplicateHint::GreatorOrEqual(arg), handle.flags()),
371-
372-
aero_syscall::prelude::F_DUPFD_CLOEXEC => scheduler::get_scheduler()
373-
.current_task()
374-
.file_table
375-
.duplicate(
376-
fd,
377-
DuplicateHint::GreatorOrEqual(arg),
378-
handle.flags() | OpenFlags::O_CLOEXEC,
379-
),
380+
aero_syscall::prelude::F_DUPFD => scheduler::current_thread().file_table.duplicate(
381+
fd.into(),
382+
DuplicateHint::GreatorOrEqual(arg),
383+
handle.flags(),
384+
),
385+
386+
aero_syscall::prelude::F_DUPFD_CLOEXEC => scheduler::current_thread().file_table.duplicate(
387+
fd.into(),
388+
DuplicateHint::GreatorOrEqual(arg),
389+
handle.flags() | OpenFlags::O_CLOEXEC,
390+
),
380391

381392
// Get the value of file descriptor flags.
382393
aero_syscall::prelude::F_GETFD => {
@@ -429,24 +440,15 @@ pub fn fcntl(fd: usize, command: usize, arg: usize) -> Result<usize, SyscallErro
429440
}
430441

431442
#[syscall]
432-
pub fn fstat(fd: usize, stat: &mut Stat) -> Result<usize, SyscallError> {
433-
let file = scheduler::get_scheduler()
434-
.current_task()
435-
.file_table
436-
.get_handle(fd)
437-
.ok_or(SyscallError::EBADFD)?;
438-
439-
*stat = file.inode().stat()?;
440-
443+
pub fn fstat(fd: FileDescriptor, stat: &mut Stat) -> Result<usize, SyscallError> {
444+
*stat = fd.handle()?.inode().stat()?;
441445
Ok(0)
442446
}
443447

444448
#[syscall]
445449
pub fn stat(path: &Path, stat: &mut Stat) -> Result<usize, SyscallError> {
446450
let file = fs::lookup_path(path)?;
447-
448451
*stat = file.inode().stat()?;
449-
450452
Ok(0)
451453
}
452454

@@ -480,16 +482,12 @@ pub fn epoll_create(flags: usize) -> Result<usize, SyscallError> {
480482
/// the operation be performed for the target file descriptor.
481483
#[syscall]
482484
pub fn epoll_ctl(
483-
epfd: usize,
485+
epfd: FileDescriptor,
484486
mode: usize,
485487
fd: usize,
486488
event: &mut EPollEvent,
487489
) -> Result<usize, SyscallError> {
488-
let epfd = scheduler::get_scheduler()
489-
.current_task()
490-
.file_table
491-
.get_handle(epfd)
492-
.ok_or(SyscallError::EBADFD)?;
490+
let epfd = epfd.handle()?;
493491

494492
let epoll = epfd
495493
.inode()
@@ -518,7 +516,7 @@ pub fn epoll_ctl(
518516

519517
#[syscall]
520518
pub fn epoll_pwait(
521-
epfd: usize,
519+
epfd: FileDescriptor,
522520
event: &mut [EPollEvent],
523521
timeout: usize,
524522
sigmask: usize,
@@ -528,11 +526,7 @@ pub fn epoll_pwait(
528526
let current_task = scheduler::get_scheduler().current_task();
529527
let signals = current_task.signals();
530528

531-
let epfd = current_task
532-
.file_table
533-
.get_handle(epfd)
534-
.ok_or(SyscallError::EBADFD)?;
535-
529+
let epfd = epfd.handle()?;
536530
let epfd = epfd
537531
.inode()
538532
.downcast_arc::<EPoll>()

src/aero_kernel/src/syscall/mod.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
//! System Calls are used to call a kernel service from userland.
1919
20+
use core::fmt::Display;
2021
use core::mem::MaybeUninit;
2122

2223
use aero_syscall::prelude::*;
@@ -98,6 +99,16 @@ pub fn exec_args_from_slice(args: usize, size: usize) -> ExecArgs {
9899
ExecArgs { inner: result }
99100
}
100101

102+
pub trait SysArg: Display {
103+
fn from_usize(value: usize) -> Self;
104+
}
105+
106+
impl SysArg for usize {
107+
fn from_usize(value: usize) -> Self {
108+
value
109+
}
110+
}
111+
101112
pub(super) struct SysLog {
102113
name: &'static str,
103114
/// The result of the syscall.

0 commit comments

Comments
 (0)