kernel/object/capability/file/syscall.rs
1//! System calls for FileObject capability
2//!
3//! This module implements system calls that operate on KernelObjects
4//! with FileObject capability (seek, truncate, metadata operations).
5
6use crate::arch::Trapframe;
7use crate::task::mytask;
8use super::SeekFrom;
9
10/// System call for seeking within a file
11///
12/// # Arguments
13/// - handle: Handle to the KernelObject (must support FileObject)
14/// - offset: Offset for seek operation
15/// - whence: Seek origin (0=start, 1=current, 2=end)
16///
17/// # Returns
18/// - On success: new position in file
19/// - On error: usize::MAX
20pub fn sys_file_seek(trapframe: &mut Trapframe) -> usize {
21 let task = match mytask() {
22 Some(task) => task,
23 None => return usize::MAX,
24 };
25
26 let handle = trapframe.get_arg(0) as u32;
27 let offset = trapframe.get_arg(1) as i64;
28 let whence = trapframe.get_arg(2) as i32;
29
30 // Increment PC to avoid infinite loop if seek fails
31 trapframe.increment_pc_next(task);
32
33 // Get KernelObject from handle table
34 let kernel_obj = match task.handle_table.get(handle) {
35 Some(obj) => obj,
36 None => return usize::MAX, // Invalid handle
37 };
38
39 // Check if object supports FileObject operations
40 let file = match kernel_obj.as_file() {
41 Some(file) => file,
42 None => return usize::MAX, // Object doesn't support file operations
43 };
44
45 // Convert whence to SeekFrom
46 let seek_from = match whence {
47 0 => SeekFrom::Start(offset as u64),
48 1 => SeekFrom::Current(offset),
49 2 => SeekFrom::End(offset),
50 _ => return usize::MAX, // Invalid whence
51 };
52
53 // Perform seek operation
54 match file.seek(seek_from) {
55 Ok(new_position) => new_position as usize,
56 Err(_) => usize::MAX, // Seek error
57 }
58}
59
60/// System call for truncating a file
61///
62/// # Arguments
63/// - handle: Handle to the KernelObject (must support FileObject)
64/// - length: New length of the file
65///
66/// # Returns
67/// - On success: 0
68/// - On error: usize::MAX
69pub fn sys_file_truncate(trapframe: &mut Trapframe) -> usize {
70 let task = match mytask() {
71 Some(task) => task,
72 None => return usize::MAX,
73 };
74
75 let handle = trapframe.get_arg(0) as u32;
76 let length = trapframe.get_arg(1) as u64;
77
78 // Increment PC to avoid infinite loop if truncate fails
79 trapframe.increment_pc_next(task);
80
81 // Get KernelObject from handle table
82 let kernel_obj = match task.handle_table.get(handle) {
83 Some(obj) => obj,
84 None => return usize::MAX, // Invalid handle
85 };
86
87 // Check if object supports FileObject operations
88 let file = match kernel_obj.as_file() {
89 Some(file) => file,
90 None => return usize::MAX, // Object doesn't support file operations
91 };
92
93 // Perform truncate operation
94 match file.truncate(length) {
95 Ok(()) => 0,
96 Err(_) => usize::MAX, // Truncate error
97 }
98}
99
100// /// System call for getting file metadata
101// ///
102// /// # Arguments
103// /// - handle: Handle to the KernelObject (must support FileObject)
104// /// - metadata_ptr: Pointer to FileMetadata structure to fill
105// ///
106// /// # Returns
107// /// - On success: 0
108// /// - On error: usize::MAX
109// pub fn sys_file_metadata(trapframe: &mut Trapframe) -> usize {
110// let task = match mytask() {
111// Some(task) => task,
112// None => return usize::MAX,
113// };
114
115// let handle = trapframe.get_arg(0) as u32;
116// let metadata_ptr = trapframe.get_arg(1);
117
118// // Increment PC to avoid infinite loop if metadata fails
119// trapframe.increment_pc_next(task);
120
121// // Translate the pointer to get access to the metadata structure
122// let metadata_vaddr = match task.vm_manager.translate_vaddr(metadata_ptr) {
123// Some(addr) => addr as *mut crate::fs::FileMetadata,
124// None => return usize::MAX, // Invalid pointer
125// };
126
127// // Get KernelObject from handle table
128// let kernel_obj = match task.handle_table.get(handle) {
129// Some(obj) => obj,
130// None => return usize::MAX, // Invalid handle
131// };
132
133// // Check if object supports FileObject operations
134// let file = match kernel_obj.as_file() {
135// Some(file) => file,
136// None => return usize::MAX, // Object doesn't support file operations
137// };
138
139// // Get metadata
140// match file.metadata() {
141// Ok(metadata) => {
142// // Write the metadata to user space
143// unsafe {
144// *metadata_vaddr = metadata;
145// }
146// 0 // Success
147// }
148// Err(_) => usize::MAX, // Metadata error
149// }
150// }