forked from rcore-os/zCore
refactor: 尽量减少对用户指针传入的数组的拷贝
This commit is contained in:
parent
5783d60f9b
commit
3cc3374c87
|
@ -35,11 +35,9 @@ impl Syscall<'_> {
|
|||
/// - len – number of bytes to write
|
||||
pub fn sys_write(&self, fd: FileDesc, base: UserInPtr<u8>, len: usize) -> SysResult {
|
||||
info!("write: fd={:?}, base={:?}, len={:#x}", fd, base, len);
|
||||
let proc = self.linux_process();
|
||||
let buf = base.read_array(len)?;
|
||||
let file_like = proc.get_file_like(fd)?;
|
||||
let len = file_like.write(&buf)?;
|
||||
Ok(len)
|
||||
self.linux_process()
|
||||
.get_file_like(fd)?
|
||||
.write(base.as_slice(len)?)
|
||||
}
|
||||
|
||||
/// read from or write to a file descriptor at a given offset
|
||||
|
@ -77,11 +75,9 @@ impl Syscall<'_> {
|
|||
"pwrite: fd={:?}, base={:?}, len={}, offset={}",
|
||||
fd, base, len, offset
|
||||
);
|
||||
let proc = self.linux_process();
|
||||
let buf = base.read_array(len)?;
|
||||
let file_like = proc.get_file_like(fd)?;
|
||||
let len = file_like.write_at(offset, &buf)?;
|
||||
Ok(len)
|
||||
self.linux_process()
|
||||
.get_file_like(fd)?
|
||||
.write_at(offset, base.as_slice(len)?)
|
||||
}
|
||||
|
||||
/// works just like read except that multiple buffers are filled.
|
||||
|
|
|
@ -307,10 +307,8 @@ impl FdSet {
|
|||
if len > MAX_FDSET_SIZE {
|
||||
return Err(LxError::EINVAL);
|
||||
}
|
||||
let slice = addr.read_array(len)?;
|
||||
|
||||
// save the fdset, and clear it
|
||||
let origin = BitVec::from_vec(slice);
|
||||
let origin = BitVec::from_slice(addr.as_slice(len)?).unwrap();
|
||||
let mut vec0 = Vec::<u32>::new();
|
||||
vec0.resize(len, 0);
|
||||
addr.write_array(&vec0)?;
|
||||
|
|
|
@ -98,14 +98,14 @@ impl Syscall<'_> {
|
|||
/// - If `op` is -1, see [`release`](linux_object::sync::Semaphore::release).
|
||||
pub async fn sys_semop(&self, id: usize, ops: UserInPtr<SemBuf>, num_ops: usize) -> SysResult {
|
||||
info!("semop: id: {}", id);
|
||||
let ops = ops.read_array(num_ops)?;
|
||||
let ops = ops.as_slice(num_ops)?;
|
||||
|
||||
let sem_array = self
|
||||
.linux_process()
|
||||
.semaphores_get(id)
|
||||
.ok_or(LxError::EINVAL)?;
|
||||
sem_array.otime();
|
||||
for &SemBuf { num, op, flags } in ops.iter() {
|
||||
for &SemBuf { num, op, flags } in ops {
|
||||
let flags = SemFlags::from_bits_truncate(flags);
|
||||
if flags.contains(SemFlags::IPC_NOWAIT) {
|
||||
unimplemented!("Semaphore: semop.IPC_NOWAIT");
|
||||
|
|
|
@ -81,11 +81,10 @@ impl Syscall<'_> {
|
|||
"sys_setsockopt : sockfd : {:?}, level : {:?}, optname : {:?}, optval : {:?} , optlen : {:?}",
|
||||
sockfd, level, optname,optval,optlen
|
||||
);
|
||||
let proc = self.linux_process();
|
||||
let data = optval.read_array(optlen)?;
|
||||
let socket = proc.get_socket(sockfd.into())?;
|
||||
let len = socket.lock().setsockopt(level, optname, &data)?;
|
||||
Ok(len)
|
||||
self.linux_process()
|
||||
.get_socket(sockfd.into())?
|
||||
.lock()
|
||||
.setsockopt(level, optname, optval.as_slice(optlen)?)
|
||||
}
|
||||
|
||||
/// net setsockopt
|
||||
|
@ -102,8 +101,6 @@ impl Syscall<'_> {
|
|||
"sys_sendto : sockfd : {:?}, buffer : {:?}, length : {:?}, flags : {:?} , optlen : {:?}, addrlen : {:?}",
|
||||
sockfd,buffer,length,flags,dest_addr,addrlen
|
||||
);
|
||||
let proc = self.linux_process();
|
||||
let data = buffer.read_array(length)?;
|
||||
let endpoint = if dest_addr.is_null() {
|
||||
None
|
||||
} else {
|
||||
|
@ -111,8 +108,9 @@ impl Syscall<'_> {
|
|||
let endpoint = sockaddr_to_endpoint(dest_addr.read()?, addrlen)?;
|
||||
Some(endpoint)
|
||||
};
|
||||
let proc = self.linux_process();
|
||||
let socket = proc.get_socket(sockfd.into())?;
|
||||
let len = socket.lock().write(&data, endpoint)?;
|
||||
let len = socket.lock().write(buffer.as_slice(length)?, endpoint)?;
|
||||
Ok(len)
|
||||
}
|
||||
|
||||
|
|
|
@ -96,9 +96,9 @@ impl Syscall<'_> {
|
|||
}
|
||||
let proc = self.thread.proc();
|
||||
let data = user_bytes.read_array(num_bytes as usize)?;
|
||||
let handles = user_handles.read_array(num_handles as usize)?;
|
||||
let handles = user_handles.as_slice(num_handles as usize)?;
|
||||
let transfer_self = handles.iter().any(|&handle| handle == handle_value);
|
||||
let handles = proc.remove_handles(&handles)?;
|
||||
let handles = proc.remove_handles(handles)?;
|
||||
if transfer_self {
|
||||
return Err(ZxError::NOT_SUPPORTED);
|
||||
}
|
||||
|
@ -161,8 +161,8 @@ impl Syscall<'_> {
|
|||
let wr_msg = MessagePacket {
|
||||
data: args.wr_bytes.read_array(args.wr_num_bytes as usize)?,
|
||||
handles: {
|
||||
let handles = args.wr_handles.read_array(args.wr_num_handles as usize)?;
|
||||
let handles = proc.remove_handles(&handles)?;
|
||||
let handles = args.wr_handles.as_slice(args.wr_num_handles as usize)?;
|
||||
let handles = proc.remove_handles(handles)?;
|
||||
for handle in handles.iter() {
|
||||
if !handle.rights.contains(Rights::TRANSFER) {
|
||||
return Err(ZxError::ACCESS_DENIED);
|
||||
|
|
|
@ -5,8 +5,7 @@ impl Syscall<'_> {
|
|||
/// Write debug info to the serial port.
|
||||
pub fn sys_debug_write(&self, buf: UserInPtr<u8>, len: usize) -> ZxResult {
|
||||
info!("debug.write: buf=({:?}; {:#x})", buf, len);
|
||||
let data = buf.read_array(len)?;
|
||||
kernel_hal::console::console_write_str(core::str::from_utf8(&data).unwrap());
|
||||
kernel_hal::console::console_write_str(buf.as_str(len)?);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
@ -42,15 +42,18 @@ impl Syscall<'_> {
|
|||
"fifo.write: handle={:?}, item_size={}, count={:#x}",
|
||||
handle_value, elem_size, count
|
||||
);
|
||||
if count == 0 {
|
||||
return Err(ZxError::OUT_OF_RANGE);
|
||||
if count != 0 {
|
||||
let data = user_bytes.as_slice(count * elem_size)?;
|
||||
let actual_count = self
|
||||
.thread
|
||||
.proc()
|
||||
.get_object_with_rights::<Fifo>(handle_value, Rights::WRITE)?
|
||||
.write(elem_size, data, count)?;
|
||||
actual_count_ptr.write_if_not_null(actual_count)?;
|
||||
Ok(())
|
||||
} else {
|
||||
Err(ZxError::OUT_OF_RANGE)
|
||||
}
|
||||
let proc = self.thread.proc();
|
||||
let fifo = proc.get_object_with_rights::<Fifo>(handle_value, Rights::WRITE)?;
|
||||
let data = user_bytes.read_array(count * elem_size)?;
|
||||
let actual_count = fifo.write(elem_size, &data, count)?;
|
||||
actual_count_ptr.write_if_not_null(actual_count)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Read data from a fifo.
|
||||
|
|
|
@ -55,12 +55,10 @@ impl Syscall<'_> {
|
|||
handles, num_handles,
|
||||
);
|
||||
let proc = self.thread.proc();
|
||||
let handles = handles.read_array(num_handles)?;
|
||||
for handle in handles {
|
||||
if handle == INVALID_HANDLE {
|
||||
continue;
|
||||
for handle in handles.as_slice(num_handles)? {
|
||||
if *handle != INVALID_HANDLE {
|
||||
proc.remove_handle(*handle)?;
|
||||
}
|
||||
proc.remove_handle(handle)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -35,18 +35,17 @@ impl Syscall<'_> {
|
|||
"socket.write: socket={:#x?}, options={:#x?}, buffer={:#x?}, size={:#x?}",
|
||||
handle_value, options, user_bytes, count,
|
||||
);
|
||||
if count > 0 && user_bytes.is_null() {
|
||||
return Err(ZxError::INVALID_ARGS);
|
||||
if (count == 0 || !user_bytes.is_null()) && options == 0 {
|
||||
let actual_count = self
|
||||
.thread
|
||||
.proc()
|
||||
.get_object_with_rights::<Socket>(handle_value, Rights::WRITE)?
|
||||
.write(user_bytes.as_slice(count)?)?;
|
||||
actual_count_ptr.write_if_not_null(actual_count)?;
|
||||
Ok(())
|
||||
} else {
|
||||
Err(ZxError::INVALID_ARGS)
|
||||
}
|
||||
if options != 0 {
|
||||
return Err(ZxError::INVALID_ARGS);
|
||||
}
|
||||
let proc = self.thread.proc();
|
||||
let socket = proc.get_object_with_rights::<Socket>(handle_value, Rights::WRITE)?;
|
||||
let data = user_bytes.read_array(count)?;
|
||||
let actual_count = socket.write(&data)?;
|
||||
actual_count_ptr.write_if_not_null(actual_count)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Read data from a socket.
|
||||
|
|
|
@ -146,11 +146,10 @@ impl Syscall<'_> {
|
|||
"thread.write_state: handle={:#x?}, kind={:#x?}, buf=({:#x?}; {:#x?})",
|
||||
handle, kind, buffer, buffer_size,
|
||||
);
|
||||
let proc = self.thread.proc();
|
||||
let thread = proc.get_object_with_rights::<Thread>(handle, Rights::WRITE)?;
|
||||
let buf = buffer.read_array(buffer_size)?;
|
||||
thread.write_state(kind, &buf)?;
|
||||
Ok(())
|
||||
self.thread
|
||||
.proc()
|
||||
.get_object_with_rights::<Thread>(handle, Rights::WRITE)?
|
||||
.write_state(kind, buffer.as_slice(buffer_size)?)
|
||||
}
|
||||
|
||||
/// Sets process as critical to job.
|
||||
|
@ -304,9 +303,10 @@ impl Syscall<'_> {
|
|||
JOB_POL_ABSOLUTE => SetPolicyOptions::Absolute,
|
||||
_ => return Err(ZxError::INVALID_ARGS),
|
||||
};
|
||||
let all_policy =
|
||||
UserInPtr::<BasicPolicy>::from(policy).read_array(count as usize)?;
|
||||
job.set_policy_basic(policy_option, &all_policy)
|
||||
job.set_policy_basic(
|
||||
policy_option,
|
||||
UserInPtr::from(policy).as_slice(count as usize)?,
|
||||
)
|
||||
}
|
||||
//JOB_POL_BASE_V2 => unimplemented!(),
|
||||
JOB_POL_TIMER_SLACK => {
|
||||
|
@ -357,15 +357,17 @@ impl Syscall<'_> {
|
|||
mut actual: UserOutPtr<usize>,
|
||||
) -> ZxResult {
|
||||
if buffer.is_null() || buffer_size == 0 || buffer_size > MAX_BLOCK {
|
||||
return Err(ZxError::INVALID_ARGS);
|
||||
Err(ZxError::INVALID_ARGS)
|
||||
} else {
|
||||
let len = self
|
||||
.thread
|
||||
.proc()
|
||||
.get_object_with_rights::<Process>(handle_value, Rights::READ | Rights::WRITE)?
|
||||
.vmar()
|
||||
.write_memory(vaddr, buffer.as_slice(buffer_size)?)?;
|
||||
actual.write(len)?;
|
||||
Ok(())
|
||||
}
|
||||
let proc = self.thread.proc();
|
||||
let process =
|
||||
proc.get_object_with_rights::<Process>(handle_value, Rights::READ | Rights::WRITE)?;
|
||||
let data = buffer.read_array(buffer_size)?;
|
||||
let len = process.vmar().write_memory(vaddr, &data)?;
|
||||
actual.write(len)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -71,8 +71,7 @@ impl Syscall<'_> {
|
|||
if offset as usize > vmo.len() || buf_size > vmo.len() - (offset as usize) {
|
||||
return Err(ZxError::OUT_OF_RANGE);
|
||||
}
|
||||
vmo.write(offset as usize, &buf.read_array(buf_size)?)?;
|
||||
Ok(())
|
||||
vmo.write(offset as usize, buf.as_slice(buf_size)?)
|
||||
}
|
||||
|
||||
/// Add execute rights to a VMO.
|
||||
|
|
Loading…
Reference in New Issue