simplify sys_sendfile. check elf arch

master
WangRunji 6 years ago
parent 8494bf9b0c
commit 8090e154c1

@ -174,18 +174,30 @@ impl Thread {
_ => panic!("ELF is not executable or shared object"),
}
// Check interpreter
// Check ELF arch
match elf.header.pt2.machine().as_machine() {
#[cfg(target_arch = "x86_64")]
header::Machine::X86_64 => {}
#[cfg(target_arch = "aarch64")]
header::Machine::AArch64 => {}
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
header::Machine::Other(243) => {}
#[cfg(target_arch = "mips")]
header::Machine::Mips => {}
machine @ _ => panic!("invalid elf arch: {:?}", machine),
}
// Check interpreter (for dynamic link)
if let Ok(loader_path) = elf.get_interpreter() {
// assuming absolute path
if let Ok(inode) = crate::fs::ROOT_INODE.lookup_follow(loader_path, FOLLOW_MAX_DEPTH) {
if let Ok(buf) = inode.read_as_vec() {
debug!("using loader {}", &loader_path);
// Elf loader should not have INTERP
// No infinite loop
args.insert(0, loader_path.into());
args.insert(1, exec_path.into());
args.remove(2);
warn!("loader args: {:?}", args);
info!("loader args: {:?}", args);
return Thread::new_user(buf.as_slice(), exec_path, args, envs);
} else {
warn!("loader specified as {} but failed to read", &loader_path);

@ -662,8 +662,8 @@ pub fn sys_pipe(fds: *mut u32) -> SysResult {
);
unsafe {
*fds = read_fd as u32;
*(fds.add(1)) = write_fd as u32;
fds.write(read_fd as u32);
fds.add(1).write(write_fd as u32);
}
info!("pipe: created rfd: {} wfd: {}", read_fd, write_fd);
@ -676,69 +676,60 @@ pub fn sys_sync() -> SysResult {
Ok(0)
}
pub fn sys_sendfile(out_fd: usize, in_fd: usize, offset: *mut usize, count: usize) -> SysResult {
pub fn sys_sendfile(
out_fd: usize,
in_fd: usize,
offset_ptr: *mut usize,
count: usize,
) -> SysResult {
info!(
"sendfile: out: {}, in: {}, offset: {:?}, count: {}",
out_fd, in_fd, offset, count
"sendfile: out: {}, in: {}, offset_ptr: {:?}, count: {}",
out_fd, in_fd, offset_ptr, count
);
let proc = process();
// We know it's save, pacify the borrow checker
let proc_cell = UnsafeCell::new(proc);
let proc_in = unsafe { &mut *proc_cell.get() };
let proc_out = unsafe { &mut *proc_cell.get() };
//let in_file: &mut FileHandle = unsafe { &mut *UnsafeCell::new(proc.get_file(in_fd)?).get() };
//let out_file: &mut FileHandle = unsafe { &mut *UnsafeCell::new(proc.get_file(out_fd)?).get() };
let in_file = proc_in.get_file(in_fd)?;
let out_file = proc_out.get_file(out_fd)?;
let in_file = unsafe { (*proc_cell.get()).get_file(in_fd)? };
let out_file = unsafe { (*proc_cell.get()).get_file(out_fd)? };
let mut buffer = [0u8; 1024];
if offset.is_null() {
// read from current file offset
let mut bytes_read = 0;
while bytes_read < count {
let len = min(buffer.len(), count - bytes_read);
let read_len = in_file.read(&mut buffer[..len])?;
if read_len == 0 {
break;
}
bytes_read += read_len;
let mut bytes_written = 0;
while bytes_written < read_len {
let write_len = out_file.write(&buffer[bytes_written..])?;
if write_len == 0 {
return Err(SysError::EBADF);
}
bytes_written += write_len;
}
let mut read_offset = if !offset_ptr.is_null() {
unsafe {
(*proc_cell.get()).vm.check_read_ptr(offset_ptr)?;
offset_ptr.read()
}
return Ok(bytes_read);
} else {
let proc_mem = unsafe { &mut *proc_cell.get() };
proc_mem.vm.check_read_ptr(offset)?;
let mut read_offset = unsafe { *offset };
// read from specified offset and write new offset back
let mut bytes_read = 0;
while bytes_read < count {
let len = min(buffer.len(), count - bytes_read);
let read_len = in_file.read_at(read_offset, &mut buffer[..len])?;
if read_len == 0 {
break;
}
bytes_read += read_len;
read_offset += read_len;
let mut bytes_written = 0;
while bytes_written < read_len {
let write_len = out_file.write(&buffer[bytes_written..])?;
if write_len == 0 {
return Err(SysError::EBADF);
}
bytes_written += write_len;
in_file.seek(SeekFrom::Current(0))? as usize
};
// read from specified offset and write new offset back
let mut bytes_read = 0;
while bytes_read < count {
let len = min(buffer.len(), count - bytes_read);
let read_len = in_file.read_at(read_offset, &mut buffer[..len])?;
if read_len == 0 {
break;
}
bytes_read += read_len;
read_offset += read_len;
let mut bytes_written = 0;
while bytes_written < read_len {
let write_len = out_file.write(&buffer[bytes_written..])?;
if write_len == 0 {
return Err(SysError::EBADF);
}
bytes_written += write_len;
}
}
if !offset_ptr.is_null() {
unsafe {
*offset = read_offset;
offset_ptr.write(read_offset);
}
return Ok(bytes_read);
} else {
in_file.seek(SeekFrom::Current(bytes_read as i64))?;
}
return Ok(bytes_read);
}
impl Process {

@ -229,6 +229,10 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize {
Err(SysError::EACCES)
}
SYS_SETPRIORITY => sys_set_priority(args[0]),
SYS_PRCTL => {
warn!("ptctl is unimplemented");
Ok(0)
}
// SYS_SETRLIMIT => sys_setrlimit(),
SYS_SYNC => sys_sync(),
SYS_MOUNT => {
@ -264,6 +268,10 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize {
SYS_MKDIRAT => sys_mkdirat(args[0], args[1] as *const u8, args[2]),
// SYS_MKNODAT => sys_mknod(),
// 260
SYS_FCHMODAT => {
warn!("sys_fchmodat is unimplemented");
Ok(0)
}
SYS_FCHOWNAT => {
warn!("sys_fchownat is unimplemented");
Ok(0)

Loading…
Cancel
Save