file.rs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610
  1. use super::{
  2. dentry::Dentry,
  3. inode::{Mode, WriteOffset},
  4. s_isblk, s_isreg,
  5. };
  6. use crate::{
  7. io::{Buffer, BufferFill, ByteBuffer, Chunks, IntoStream},
  8. kernel::{
  9. constants::{TCGETS, TCSETS, TIOCGPGRP, TIOCGWINSZ, TIOCSPGRP},
  10. mem::{paging::Page, AsMemoryBlock as _},
  11. task::Thread,
  12. terminal::{Terminal, TerminalIORequest},
  13. user::{UserPointer, UserPointerMut},
  14. CharDevice,
  15. },
  16. prelude::*,
  17. sync::CondVar,
  18. };
  19. use crate::{
  20. io::{Stream, StreamRead},
  21. kernel::constants::{
  22. EBADF, EFAULT, EINTR, EINVAL, ENOTDIR, ENOTTY, EOVERFLOW, EPIPE, ESPIPE, S_IFMT,
  23. },
  24. };
  25. use alloc::{collections::vec_deque::VecDeque, sync::Arc};
  26. use bitflags::bitflags;
  27. use core::{
  28. ops::{ControlFlow, Deref},
  29. sync::atomic::{AtomicU32, Ordering},
  30. };
  31. use eonix_runtime::task::Task;
  32. use eonix_sync::Mutex;
  33. use posix_types::{open::OpenFlags, signal::Signal, stat::StatX};
  34. pub struct InodeFile {
  35. read: bool,
  36. write: bool,
  37. append: bool,
  38. /// Only a few modes those won't possibly change are cached here to speed up file operations.
  39. /// Specifically, `S_IFMT` masked bits.
  40. mode: Mode,
  41. cursor: Mutex<usize>,
  42. dentry: Arc<Dentry>,
  43. }
  44. pub struct PipeInner {
  45. buffer: VecDeque<u8>,
  46. read_closed: bool,
  47. write_closed: bool,
  48. }
  49. pub struct Pipe {
  50. inner: Mutex<PipeInner>,
  51. cv_read: CondVar,
  52. cv_write: CondVar,
  53. }
  54. pub struct PipeReadEnd {
  55. pipe: Arc<Pipe>,
  56. }
  57. pub struct PipeWriteEnd {
  58. pipe: Arc<Pipe>,
  59. }
  60. pub struct TerminalFile {
  61. terminal: Arc<Terminal>,
  62. }
  63. // TODO: We should use `File` as the base type, instead of `Arc<File>`
  64. // If we need shared states, like for `InodeFile`, the files themselves should
  65. // have their own shared semantics. All `File` variants will just keep the
  66. // `Clone` semantics.
  67. //
  68. // e.g. The `CharDevice` itself is stateless.
  69. pub enum FileType {
  70. Inode(InodeFile),
  71. PipeRead(PipeReadEnd),
  72. PipeWrite(PipeWriteEnd),
  73. TTY(TerminalFile),
  74. CharDev(Arc<CharDevice>),
  75. }
  76. pub struct File {
  77. flags: AtomicU32,
  78. file_type: FileType,
  79. }
  80. pub enum SeekOption {
  81. Set(usize),
  82. Current(isize),
  83. End(isize),
  84. }
  85. bitflags! {
  86. pub struct PollEvent: u16 {
  87. const Readable = 0x0001;
  88. const Writable = 0x0002;
  89. }
  90. }
  91. impl Drop for PipeReadEnd {
  92. fn drop(&mut self) {
  93. self.pipe.close_read();
  94. }
  95. }
  96. impl Drop for PipeWriteEnd {
  97. fn drop(&mut self) {
  98. self.pipe.close_write();
  99. }
  100. }
  101. fn send_sigpipe_to_current() {
  102. let current = Thread::current();
  103. current.raise(Signal::SIGPIPE);
  104. }
  105. impl Pipe {
  106. const PIPE_SIZE: usize = 4096;
  107. /// # Return
  108. /// `(read_end, write_end)`
  109. pub fn new(flags: OpenFlags) -> (Arc<File>, Arc<File>) {
  110. let pipe = Arc::new(Self {
  111. inner: Mutex::new(PipeInner {
  112. buffer: VecDeque::with_capacity(Self::PIPE_SIZE),
  113. read_closed: false,
  114. write_closed: false,
  115. }),
  116. cv_read: CondVar::new(),
  117. cv_write: CondVar::new(),
  118. });
  119. let read_flags = flags.difference(OpenFlags::O_WRONLY | OpenFlags::O_RDWR);
  120. let mut write_flags = read_flags;
  121. write_flags.insert(OpenFlags::O_WRONLY);
  122. (
  123. Arc::new(File {
  124. flags: AtomicU32::new(read_flags.bits()),
  125. file_type: FileType::PipeRead(PipeReadEnd { pipe: pipe.clone() }),
  126. }),
  127. Arc::new(File {
  128. flags: AtomicU32::new(write_flags.bits()),
  129. file_type: FileType::PipeWrite(PipeWriteEnd { pipe }),
  130. }),
  131. )
  132. }
  133. fn close_read(&self) {
  134. let mut inner = Task::block_on(self.inner.lock());
  135. if inner.read_closed {
  136. return;
  137. }
  138. inner.read_closed = true;
  139. self.cv_write.notify_all();
  140. }
  141. fn close_write(&self) {
  142. let mut inner = Task::block_on(self.inner.lock());
  143. if inner.write_closed {
  144. return;
  145. }
  146. inner.write_closed = true;
  147. self.cv_read.notify_all();
  148. }
  149. async fn poll(&self, event: PollEvent) -> KResult<PollEvent> {
  150. if !event.contains(PollEvent::Readable) {
  151. unimplemented!("Poll event not supported.");
  152. }
  153. let mut inner = self.inner.lock().await;
  154. while inner.buffer.is_empty() && !inner.write_closed {
  155. inner = self.cv_read.wait(inner).await;
  156. }
  157. if Thread::current().signal_list.has_pending_signal() {
  158. return Err(EINTR);
  159. }
  160. let mut retval = PollEvent::empty();
  161. if inner.write_closed {
  162. retval |= PollEvent::Writable;
  163. }
  164. if !inner.buffer.is_empty() {
  165. retval |= PollEvent::Readable;
  166. }
  167. Ok(retval)
  168. }
  169. async fn read(&self, buffer: &mut dyn Buffer) -> KResult<usize> {
  170. let mut inner = self.inner.lock().await;
  171. while !inner.write_closed && inner.buffer.is_empty() {
  172. inner = self.cv_read.wait(inner).await;
  173. if Thread::current().signal_list.has_pending_signal() {
  174. return Err(EINTR);
  175. }
  176. }
  177. let (data1, data2) = inner.buffer.as_slices();
  178. let nread = buffer.fill(data1)?.allow_partial() + buffer.fill(data2)?.allow_partial();
  179. inner.buffer.drain(..nread);
  180. self.cv_write.notify_all();
  181. Ok(nread)
  182. }
  183. async fn write_atomic(&self, data: &[u8]) -> KResult<usize> {
  184. let mut inner = self.inner.lock().await;
  185. if inner.read_closed {
  186. send_sigpipe_to_current();
  187. return Err(EPIPE);
  188. }
  189. while inner.buffer.len() + data.len() > Self::PIPE_SIZE {
  190. inner = self.cv_write.wait(inner).await;
  191. if Thread::current().signal_list.has_pending_signal() {
  192. return Err(EINTR);
  193. }
  194. if inner.read_closed {
  195. send_sigpipe_to_current();
  196. return Err(EPIPE);
  197. }
  198. }
  199. inner.buffer.extend(data);
  200. self.cv_read.notify_all();
  201. return Ok(data.len());
  202. }
  203. async fn write(&self, stream: &mut dyn Stream) -> KResult<usize> {
  204. let mut buffer = [0; Self::PIPE_SIZE];
  205. let mut total = 0;
  206. while let Some(data) = stream.poll_data(&mut buffer)? {
  207. let nwrote = self.write_atomic(data).await?;
  208. total += nwrote;
  209. if nwrote != data.len() {
  210. break;
  211. }
  212. }
  213. Ok(total)
  214. }
  215. }
  216. #[derive(Copy, Clone, Debug)]
  217. #[repr(C, packed)]
  218. struct UserDirent64 {
  219. /// Inode number
  220. d_ino: u64,
  221. /// Implementation defined. We ignore it
  222. d_off: u64,
  223. /// Length of this record
  224. d_reclen: u16,
  225. /// File type. Set to 0
  226. d_type: u8,
  227. /// Filename with a padding '\0'
  228. d_name: [u8; 0],
  229. }
  230. /// File type is at offset `d_reclen - 1`. Set it to 0
  231. #[derive(Copy, Clone, Debug)]
  232. #[repr(C, packed)]
  233. struct UserDirent {
  234. /// Inode number
  235. d_ino: u32,
  236. /// Implementation defined. We ignore it
  237. d_off: u32,
  238. /// Length of this record
  239. d_reclen: u16,
  240. /// Filename with a padding '\0'
  241. d_name: [u8; 0],
  242. }
  243. impl InodeFile {
  244. pub fn new(dentry: Arc<Dentry>, flags: OpenFlags) -> Arc<File> {
  245. // SAFETY: `dentry` used to create `InodeFile` is valid.
  246. // SAFETY: `mode` should never change with respect to the `S_IFMT` fields.
  247. let cached_mode = dentry
  248. .get_inode()
  249. .expect("`dentry` is invalid")
  250. .mode
  251. .load(Ordering::Relaxed)
  252. & S_IFMT;
  253. let (read, write, append) = flags.as_rwa();
  254. Arc::new(File {
  255. flags: AtomicU32::new(flags.bits()),
  256. file_type: FileType::Inode(InodeFile {
  257. dentry,
  258. read,
  259. write,
  260. append,
  261. mode: cached_mode,
  262. cursor: Mutex::new(0),
  263. }),
  264. })
  265. }
  266. fn seek(&self, option: SeekOption) -> KResult<usize> {
  267. let mut cursor = Task::block_on(self.cursor.lock());
  268. let new_cursor = match option {
  269. SeekOption::Current(off) => cursor.checked_add_signed(off).ok_or(EOVERFLOW)?,
  270. SeekOption::Set(n) => n,
  271. SeekOption::End(off) => {
  272. let inode = self.dentry.get_inode()?;
  273. let size = inode.size.load(Ordering::Relaxed) as usize;
  274. size.checked_add_signed(off).ok_or(EOVERFLOW)?
  275. }
  276. };
  277. *cursor = new_cursor;
  278. Ok(new_cursor)
  279. }
  280. fn write(&self, stream: &mut dyn Stream) -> KResult<usize> {
  281. if !self.write {
  282. return Err(EBADF);
  283. }
  284. let mut cursor = Task::block_on(self.cursor.lock());
  285. if self.append {
  286. let nwrote = self.dentry.write(stream, WriteOffset::End(&mut cursor))?;
  287. Ok(nwrote)
  288. } else {
  289. let nwrote = self.dentry.write(stream, WriteOffset::Position(*cursor))?;
  290. *cursor += nwrote;
  291. Ok(nwrote)
  292. }
  293. }
  294. fn read(&self, buffer: &mut dyn Buffer) -> KResult<usize> {
  295. if !self.read {
  296. return Err(EBADF);
  297. }
  298. let mut cursor = Task::block_on(self.cursor.lock());
  299. let nread = self.dentry.read(buffer, *cursor)?;
  300. *cursor += nread;
  301. Ok(nread)
  302. }
  303. fn getdents64(&self, buffer: &mut dyn Buffer) -> KResult<()> {
  304. let mut cursor = Task::block_on(self.cursor.lock());
  305. let nread = self.dentry.readdir(*cursor, |filename, ino| {
  306. // Filename length + 1 for padding '\0'
  307. let real_record_len = core::mem::size_of::<UserDirent64>() + filename.len() + 1;
  308. if buffer.available() < real_record_len {
  309. return Ok(ControlFlow::Break(()));
  310. }
  311. let record = UserDirent64 {
  312. d_ino: ino,
  313. d_off: 0,
  314. d_reclen: real_record_len as u16,
  315. d_type: 0,
  316. d_name: [0; 0],
  317. };
  318. buffer.copy(&record)?.ok_or(EFAULT)?;
  319. buffer.fill(filename)?.ok_or(EFAULT)?;
  320. buffer.fill(&[0])?.ok_or(EFAULT)?;
  321. Ok(ControlFlow::Continue(()))
  322. })?;
  323. *cursor += nread;
  324. Ok(())
  325. }
  326. fn getdents(&self, buffer: &mut dyn Buffer) -> KResult<()> {
  327. let mut cursor = Task::block_on(self.cursor.lock());
  328. let nread = self.dentry.readdir(*cursor, |filename, ino| {
  329. // + 1 for filename length padding '\0', + 1 for d_type.
  330. let real_record_len = core::mem::size_of::<UserDirent>() + filename.len() + 2;
  331. if buffer.available() < real_record_len {
  332. return Ok(ControlFlow::Break(()));
  333. }
  334. let record = UserDirent {
  335. d_ino: ino as u32,
  336. d_off: 0,
  337. d_reclen: real_record_len as u16,
  338. d_name: [0; 0],
  339. };
  340. buffer.copy(&record)?.ok_or(EFAULT)?;
  341. buffer.fill(filename)?.ok_or(EFAULT)?;
  342. buffer.fill(&[0, 0])?.ok_or(EFAULT)?;
  343. Ok(ControlFlow::Continue(()))
  344. })?;
  345. *cursor += nread;
  346. Ok(())
  347. }
  348. }
  349. impl TerminalFile {
  350. pub fn new(tty: Arc<Terminal>, flags: OpenFlags) -> Arc<File> {
  351. Arc::new(File {
  352. flags: AtomicU32::new(flags.bits()),
  353. file_type: FileType::TTY(TerminalFile { terminal: tty }),
  354. })
  355. }
  356. async fn read(&self, buffer: &mut dyn Buffer) -> KResult<usize> {
  357. self.terminal.read(buffer).await
  358. }
  359. fn write(&self, stream: &mut dyn Stream) -> KResult<usize> {
  360. stream.read_till_end(&mut [0; 128], |data| {
  361. self.terminal.write(data);
  362. Ok(())
  363. })
  364. }
  365. async fn poll(&self, event: PollEvent) -> KResult<PollEvent> {
  366. if !event.contains(PollEvent::Readable) {
  367. unimplemented!("Poll event not supported.")
  368. }
  369. self.terminal.poll_in().await.map(|_| PollEvent::Readable)
  370. }
  371. fn ioctl(&self, request: usize, arg3: usize) -> KResult<()> {
  372. Task::block_on(self.terminal.ioctl(match request as u32 {
  373. TCGETS => TerminalIORequest::GetTermios(UserPointerMut::new_vaddr(arg3)?),
  374. TCSETS => TerminalIORequest::SetTermios(UserPointer::new_vaddr(arg3)?),
  375. TIOCGPGRP => TerminalIORequest::GetProcessGroup(UserPointerMut::new_vaddr(arg3)?),
  376. TIOCSPGRP => TerminalIORequest::SetProcessGroup(UserPointer::new_vaddr(arg3)?),
  377. TIOCGWINSZ => TerminalIORequest::GetWindowSize(UserPointerMut::new_vaddr(arg3)?),
  378. _ => return Err(EINVAL),
  379. }))
  380. }
  381. }
  382. impl FileType {
  383. pub async fn read(&self, buffer: &mut dyn Buffer) -> KResult<usize> {
  384. match self {
  385. FileType::Inode(inode) => inode.read(buffer),
  386. FileType::PipeRead(pipe) => pipe.pipe.read(buffer).await,
  387. FileType::TTY(tty) => tty.read(buffer).await,
  388. FileType::CharDev(device) => device.read(buffer),
  389. _ => Err(EBADF),
  390. }
  391. }
  392. // TODO
  393. // /// Read from the file into the given buffers.
  394. // ///
  395. // /// Reads are atomic, not intermingled with other reads or writes.
  396. // pub fn readv<'r, 'i, I: Iterator<Item = &'i mut dyn Buffer>>(
  397. // &'r self,
  398. // buffers: I,
  399. // ) -> KResult<usize> {
  400. // match self {
  401. // File::Inode(inode) => inode.readv(buffers),
  402. // File::PipeRead(pipe) => pipe.pipe.readv(buffers),
  403. // _ => Err(EBADF),
  404. // }
  405. // }
  406. pub async fn write(&self, stream: &mut dyn Stream) -> KResult<usize> {
  407. match self {
  408. FileType::Inode(inode) => inode.write(stream),
  409. FileType::PipeWrite(pipe) => pipe.pipe.write(stream).await,
  410. FileType::TTY(tty) => tty.write(stream),
  411. FileType::CharDev(device) => device.write(stream),
  412. _ => Err(EBADF),
  413. }
  414. }
  415. pub fn seek(&self, option: SeekOption) -> KResult<usize> {
  416. match self {
  417. FileType::Inode(inode) => inode.seek(option),
  418. _ => Err(ESPIPE),
  419. }
  420. }
  421. pub fn getdents(&self, buffer: &mut dyn Buffer) -> KResult<()> {
  422. match self {
  423. FileType::Inode(inode) => inode.getdents(buffer),
  424. _ => Err(ENOTDIR),
  425. }
  426. }
  427. pub fn getdents64(&self, buffer: &mut dyn Buffer) -> KResult<()> {
  428. match self {
  429. FileType::Inode(inode) => inode.getdents64(buffer),
  430. _ => Err(ENOTDIR),
  431. }
  432. }
  433. pub async fn sendfile(&self, dest_file: &Self, count: usize) -> KResult<usize> {
  434. let buffer_page = Page::alloc();
  435. // SAFETY: We are the only owner of the page.
  436. let buffer = unsafe { buffer_page.as_memblk().as_bytes_mut() };
  437. match self {
  438. FileType::Inode(file) if s_isblk(file.mode) || s_isreg(file.mode) => (),
  439. _ => return Err(EINVAL),
  440. }
  441. let mut nsent = 0;
  442. for (cur, len) in Chunks::new(0, count, buffer.len()) {
  443. if Thread::current().signal_list.has_pending_signal() {
  444. return if cur == 0 { Err(EINTR) } else { Ok(cur) };
  445. }
  446. let nread = self.read(&mut ByteBuffer::new(&mut buffer[..len])).await?;
  447. if nread == 0 {
  448. break;
  449. }
  450. let nwrote = dest_file.write(&mut buffer[..nread].into_stream()).await?;
  451. nsent += nwrote;
  452. if nwrote != len {
  453. break;
  454. }
  455. }
  456. Ok(nsent)
  457. }
  458. pub fn ioctl(&self, request: usize, arg3: usize) -> KResult<usize> {
  459. match self {
  460. FileType::TTY(tty) => tty.ioctl(request, arg3).map(|_| 0),
  461. _ => Err(ENOTTY),
  462. }
  463. }
  464. pub async fn poll(&self, event: PollEvent) -> KResult<PollEvent> {
  465. match self {
  466. FileType::Inode(_) => Ok(event),
  467. FileType::TTY(tty) => tty.poll(event).await,
  468. FileType::PipeRead(PipeReadEnd { pipe })
  469. | FileType::PipeWrite(PipeWriteEnd { pipe }) => pipe.poll(event).await,
  470. _ => unimplemented!("Poll event not supported."),
  471. }
  472. }
  473. pub fn statx(&self, buffer: &mut StatX, mask: u32) -> KResult<()> {
  474. match self {
  475. FileType::Inode(inode) => inode.dentry.statx(buffer, mask),
  476. _ => Err(EBADF),
  477. }
  478. }
  479. pub fn as_path(&self) -> Option<&Arc<Dentry>> {
  480. match self {
  481. FileType::Inode(inode_file) => Some(&inode_file.dentry),
  482. _ => None,
  483. }
  484. }
  485. }
  486. impl File {
  487. pub fn new(flags: OpenFlags, file_type: FileType) -> Arc<Self> {
  488. Arc::new(Self {
  489. flags: AtomicU32::new(flags.bits()),
  490. file_type,
  491. })
  492. }
  493. pub fn get_flags(&self) -> OpenFlags {
  494. OpenFlags::from_bits_retain(self.flags.load(Ordering::Relaxed))
  495. }
  496. pub fn set_flags(&self, flags: OpenFlags) {
  497. let flags = flags.difference(
  498. OpenFlags::O_WRONLY
  499. | OpenFlags::O_RDWR
  500. | OpenFlags::O_CREAT
  501. | OpenFlags::O_TRUNC
  502. | OpenFlags::O_EXCL,
  503. // | OpenFlags::O_NOCTTY,
  504. );
  505. self.flags.store(flags.bits(), Ordering::Relaxed);
  506. }
  507. }
  508. impl Deref for File {
  509. type Target = FileType;
  510. fn deref(&self) -> &Self::Target {
  511. &self.file_type
  512. }
  513. }