arceos_posix_api/imp/
io.rs

1use crate::ctypes;
2use axerrno::LinuxError;
3use core::ffi::{c_int, c_void};
4
5#[cfg(feature = "fd")]
6use crate::imp::fd_ops::get_file_like;
7#[cfg(not(feature = "fd"))]
8use axio::prelude::*;
9
10/// Read data from the file indicated by `fd`.
11///
12/// Return the read size if success.
13pub fn sys_read(fd: c_int, buf: *mut c_void, count: usize) -> ctypes::ssize_t {
14    debug!("sys_read <= {} {:#x} {}", fd, buf as usize, count);
15    syscall_body!(sys_read, {
16        if buf.is_null() {
17            return Err(LinuxError::EFAULT);
18        }
19        let dst = unsafe { core::slice::from_raw_parts_mut(buf as *mut u8, count) };
20        #[cfg(feature = "fd")]
21        {
22            Ok(get_file_like(fd)?.read(dst)? as ctypes::ssize_t)
23        }
24        #[cfg(not(feature = "fd"))]
25        match fd {
26            0 => Ok(super::stdio::stdin().read(dst)? as ctypes::ssize_t),
27            1 | 2 => Err(LinuxError::EPERM),
28            _ => Err(LinuxError::EBADF),
29        }
30    })
31}
32
33/// Write data to the file indicated by `fd`.
34///
35/// Return the written size if success.
36pub fn sys_write(fd: c_int, buf: *const c_void, count: usize) -> ctypes::ssize_t {
37    debug!("sys_write <= {} {:#x} {}", fd, buf as usize, count);
38    syscall_body!(sys_write, {
39        if buf.is_null() {
40            return Err(LinuxError::EFAULT);
41        }
42        let src = unsafe { core::slice::from_raw_parts(buf as *const u8, count) };
43        #[cfg(feature = "fd")]
44        {
45            Ok(get_file_like(fd)?.write(src)? as ctypes::ssize_t)
46        }
47        #[cfg(not(feature = "fd"))]
48        match fd {
49            0 => Err(LinuxError::EPERM),
50            1 | 2 => Ok(super::stdio::stdout().write(src)? as ctypes::ssize_t),
51            _ => Err(LinuxError::EBADF),
52        }
53    })
54}
55
56/// Write a vector.
57pub unsafe fn sys_writev(fd: c_int, iov: *const ctypes::iovec, iocnt: c_int) -> ctypes::ssize_t {
58    debug!("sys_writev <= fd: {}", fd);
59    syscall_body!(sys_writev, {
60        if !(0..=1024).contains(&iocnt) {
61            return Err(LinuxError::EINVAL);
62        }
63
64        let iovs = unsafe { core::slice::from_raw_parts(iov, iocnt as usize) };
65        let mut ret = 0;
66        for iov in iovs.iter() {
67            ret += sys_write(fd, iov.iov_base, iov.iov_len);
68        }
69
70        Ok(ret)
71    })
72}