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}