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// }