kernel/object/capability/file/mod.rs
1//! File operations capability module
2//!
3//! This module provides system calls and traits for FileObject capability,
4//! which extends StreamOps with file-specific operations like seek and metadata.
5
6use core::any::Any;
7
8use crate::object::capability::Selectable;
9use crate::object::capability::control::ControlOps;
10use crate::object::capability::memory_mapping::MemoryMappingOps;
11use crate::object::capability::stream::{StreamError, StreamOps};
12
13pub mod syscall;
14
15pub use syscall::{sys_file_seek, sys_file_truncate};
16
17/// Seek operations for file positioning
18#[derive(Debug, Clone, Copy)]
19pub enum SeekFrom {
20 /// Seek from the beginning of the file
21 Start(u64),
22 /// Seek relative to the current position
23 Current(i64),
24 /// Seek relative to the end of the file
25 End(i64),
26}
27
28/// Trait for file objects
29///
30/// This trait represents a file-like object that supports stream operations,
31/// file-specific operations like seeking and metadata access, control
32/// operations for device-specific functionality, and memory mapping operations.
33/// Directory reading is handled through normal read() operations.
34pub trait FileObject: StreamOps + ControlOps + MemoryMappingOps + Selectable {
35 /// Seek to a position in the file stream
36 fn seek(&self, whence: SeekFrom) -> Result<u64, StreamError>;
37
38 /// Get metadata about the file
39 fn metadata(&self) -> Result<crate::fs::FileMetadata, StreamError>;
40
41 /// Read data from a specific offset without changing internal position
42 ///
43 /// This method performs a random-access read operation that must not
44 /// modify the file's current seek position. Filesystems that cannot
45 /// support position-independent reads may return `StreamError::NotSupported`.
46 fn read_at(&self, offset: u64, buffer: &mut [u8]) -> Result<usize, StreamError> {
47 let _ = (offset, buffer);
48 Err(StreamError::NotSupported)
49 }
50
51 /// Write data to a specific offset without changing internal position
52 ///
53 /// Similar to [`read_at`], this operation must not adjust the file's
54 /// internal cursor. Implementations can default to returning
55 /// `StreamError::NotSupported` when random-access writes are unavailable.
56 fn write_at(&self, offset: u64, buffer: &[u8]) -> Result<usize, StreamError> {
57 let _ = (offset, buffer);
58 Err(StreamError::NotSupported)
59 }
60
61 /// Truncate the file to the specified size
62 ///
63 /// This method changes the size of the file to the specified length.
64 /// If the new size is smaller than the current size, the file is truncated.
65 /// If the new size is larger, the file is extended with zero bytes.
66 ///
67 /// # Arguments
68 ///
69 /// * `size` - New size of the file in bytes
70 ///
71 /// # Returns
72 ///
73 /// * `Result<(), StreamError>` - Ok if the file was truncated successfully
74 ///
75 /// # Errors
76 ///
77 /// * `StreamError` - If the file is a directory or the operation is not supported
78 fn truncate(&self, size: u64) -> Result<(), StreamError> {
79 let _ = size;
80 Err(StreamError::NotSupported)
81 }
82
83 /// Synchronize file content to storage
84 ///
85 /// This method ensures that any buffered changes to the file are written
86 /// to the underlying storage device. This is important for filesystems
87 /// that cache file content in memory.
88 ///
89 /// # Returns
90 ///
91 /// * `Result<(), StreamError>` - Ok if the sync was successful
92 ///
93 /// # Errors
94 ///
95 /// * `StreamError` - If the sync operation fails or is not supported
96 fn sync(&self) -> Result<(), StreamError> {
97 // Default implementation does nothing - files that don't cache content
98 // don't need to sync
99 Ok(())
100 }
101
102 fn as_any(&self) -> &dyn Any;
103}