1use crate::sync::SpinLock;
4use crate::vfs::{Dentry, File, FsError, Inode, InodeMetadata, OpenFlags, SeekWhence};
5use alloc::sync::Arc;
6
7pub struct RegFile {
18 pub dentry: Arc<Dentry>,
20
21 pub inode: Arc<dyn Inode>,
23
24 offset: SpinLock<usize>,
26
27 flags: SpinLock<OpenFlags>,
29
30 owner: SpinLock<Option<i32>>,
32}
33
34impl RegFile {
35 pub fn new(dentry: Arc<Dentry>, flags: OpenFlags) -> Self {
37 let inode = dentry.inode.clone();
38 Self {
39 dentry,
40 inode,
41 offset: SpinLock::new(0),
42 flags: SpinLock::new(flags),
43 owner: SpinLock::new(None),
44 }
45 }
46
47 pub fn inode(&self) -> Arc<dyn Inode> {
49 self.inode.clone()
50 }
51
52 pub fn dentry(&self) -> Arc<Dentry> {
54 self.dentry.clone()
55 }
56
57 pub fn set_flags(&self, new_flags: OpenFlags) -> Result<(), FsError> {
61 let mut flags = self.flags.lock();
62 *flags = new_flags;
63 Ok(())
64 }
65}
66
67impl File for RegFile {
68 fn readable(&self) -> bool {
69 self.flags.lock().readable()
70 }
71
72 fn writable(&self) -> bool {
73 self.flags.lock().writable()
74 }
75
76 fn read(&self, buf: &mut [u8]) -> Result<usize, FsError> {
77 if !self.readable() {
79 return Err(FsError::PermissionDenied);
80 }
81
82 let mut offset_guard = self.offset.lock();
84 let current_offset = *offset_guard;
85
86 let nread = self.inode.read_at(current_offset, buf)?;
88
89 *offset_guard = current_offset + nread;
91
92 Ok(nread)
93 }
94
95 fn write(&self, buf: &[u8]) -> Result<usize, FsError> {
96 if !self.writable() {
98 return Err(FsError::PermissionDenied);
99 }
100
101 let mut offset_guard = self.offset.lock();
103 let flags = self.flags.lock();
104 let write_offset = if flags.contains(OpenFlags::O_APPEND) {
105 self.inode.metadata()?.size
107 } else {
108 *offset_guard
109 };
110 drop(flags); let nwritten = self.inode.write_at(write_offset, buf)?;
114
115 *offset_guard = write_offset + nwritten;
117
118 Ok(nwritten)
119 }
120
121 fn metadata(&self) -> Result<InodeMetadata, FsError> {
122 self.inode.metadata()
123 }
124
125 fn lseek(&self, offset: isize, whence: SeekWhence) -> Result<usize, FsError> {
126 let mut offset_guard = self.offset.lock();
127 let current = *offset_guard as isize;
128 let file_size = self.inode.metadata()?.size as isize;
129
130 let new_offset = match whence {
131 SeekWhence::Set => offset,
132 SeekWhence::Cur => current + offset,
133 SeekWhence::End => file_size + offset,
134 };
135
136 if new_offset < 0 {
138 return Err(FsError::InvalidArgument);
139 }
140
141 *offset_guard = new_offset as usize;
142 Ok(new_offset as usize)
143 }
144
145 fn offset(&self) -> usize {
146 *self.offset.lock()
147 }
148
149 fn flags(&self) -> OpenFlags {
150 *self.flags.lock()
151 }
152
153 fn inode(&self) -> Result<Arc<dyn Inode>, FsError> {
154 Ok(self.inode())
155 }
156
157 fn dentry(&self) -> Result<Arc<Dentry>, FsError> {
158 Ok(self.dentry())
159 }
160
161 fn set_status_flags(&self, new_flags: OpenFlags) -> Result<(), FsError> {
162 self.set_flags(new_flags)
163 }
164
165 fn get_owner(&self) -> Result<i32, FsError> {
166 Ok(self.owner.lock().unwrap_or(0))
167 }
168
169 fn set_owner(&self, pid: i32) -> Result<(), FsError> {
170 *self.owner.lock() = if pid == 0 { None } else { Some(pid) };
171 Ok(())
172 }
173
174 fn read_at(&self, offset: usize, buf: &mut [u8]) -> Result<usize, FsError> {
175 self.inode.read_at(offset, buf)
176 }
177
178 fn write_at(&self, offset: usize, buf: &[u8]) -> Result<usize, FsError> {
179 self.inode.write_at(offset, buf)
180 }
181
182 fn as_any(&self) -> &dyn core::any::Any {
183 self
184 }
185}