1use core::ffi::c_int;
2
3use axerrno::{LinuxError, LinuxResult};
4use axio::SeekFrom;
5use linux_raw_sys::general::{__kernel_off_t, iovec};
6
7use crate::{
8 file::{File, FileLike, get_file_like},
9 ptr::{UserConstPtr, UserPtr},
10};
11
12pub fn sys_read(fd: i32, buf: UserPtr<u8>, len: usize) -> LinuxResult<isize> {
16 let buf = buf.get_as_mut_slice(len)?;
17 debug!(
18 "sys_read <= fd: {}, buf: {:p}, len: {}",
19 fd,
20 buf.as_ptr(),
21 buf.len()
22 );
23 Ok(get_file_like(fd)?.read(buf)? as _)
24}
25
26pub fn sys_readv(fd: i32, iov: UserPtr<iovec>, iocnt: usize) -> LinuxResult<isize> {
27 if !(0..=1024).contains(&iocnt) {
28 return Err(LinuxError::EINVAL);
29 }
30
31 let iovs = iov.get_as_mut_slice(iocnt)?;
32 let mut ret = 0;
33 for iov in iovs {
34 if iov.iov_len == 0 {
35 continue;
36 }
37 let buf = UserPtr::<u8>::from(iov.iov_base as usize);
38 let buf = buf.get_as_mut_slice(iov.iov_len as _)?;
39 debug!(
40 "sys_readv <= fd: {}, buf: {:p}, len: {}",
41 fd,
42 buf.as_ptr(),
43 buf.len()
44 );
45
46 let read = get_file_like(fd)?.read(buf)?;
47 ret += read as isize;
48
49 if read < buf.len() {
50 break;
51 }
52 }
53
54 Ok(ret)
55}
56
57pub fn sys_write(fd: i32, buf: UserConstPtr<u8>, len: usize) -> LinuxResult<isize> {
61 let buf = buf.get_as_slice(len)?;
62 debug!(
63 "sys_write <= fd: {}, buf: {:p}, len: {}",
64 fd,
65 buf.as_ptr(),
66 buf.len()
67 );
68 Ok(get_file_like(fd)?.write(buf)? as _)
69}
70
71pub fn sys_writev(fd: i32, iov: UserConstPtr<iovec>, iocnt: usize) -> LinuxResult<isize> {
72 if !(0..=1024).contains(&iocnt) {
73 return Err(LinuxError::EINVAL);
74 }
75
76 let iovs = iov.get_as_slice(iocnt)?;
77 let mut ret = 0;
78 for iov in iovs {
79 if iov.iov_len == 0 {
80 continue;
81 }
82 let buf = UserConstPtr::<u8>::from(iov.iov_base as usize);
83 let buf = buf.get_as_slice(iov.iov_len as _)?;
84 debug!(
85 "sys_writev <= fd: {}, buf: {:p}, len: {}",
86 fd,
87 buf.as_ptr(),
88 buf.len()
89 );
90
91 let written = get_file_like(fd)?.write(buf)?;
92 ret += written as isize;
93
94 if written < buf.len() {
95 break;
96 }
97 }
98
99 Ok(ret)
100}
101
102pub fn sys_lseek(fd: c_int, offset: __kernel_off_t, whence: c_int) -> LinuxResult<isize> {
103 debug!("sys_lseek <= {} {} {}", fd, offset, whence);
104 let pos = match whence {
105 0 => SeekFrom::Start(offset as _),
106 1 => SeekFrom::Current(offset as _),
107 2 => SeekFrom::End(offset as _),
108 _ => return Err(LinuxError::EINVAL),
109 };
110 let off = File::from_fd(fd)?.inner().seek(pos)?;
111 Ok(off as _)
112}