|
|
@ -274,7 +274,7 @@ impl Syscall<'_> {
|
|
|
|
mode: usize,
|
|
|
|
mode: usize,
|
|
|
|
) -> SysResult {
|
|
|
|
) -> SysResult {
|
|
|
|
let mut proc = self.process();
|
|
|
|
let mut proc = self.process();
|
|
|
|
let path = unsafe { check_and_clone_cstr(path)? };
|
|
|
|
let path = check_and_clone_cstr(path)?;
|
|
|
|
let flags = OpenFlags::from_bits_truncate(flags);
|
|
|
|
let flags = OpenFlags::from_bits_truncate(flags);
|
|
|
|
info!(
|
|
|
|
info!(
|
|
|
|
"openat: dir_fd: {}, path: {:?}, flags: {:?}, mode: {:#o}",
|
|
|
|
"openat: dir_fd: {}, path: {:?}, flags: {:?}, mode: {:#o}",
|
|
|
@ -338,7 +338,7 @@ impl Syscall<'_> {
|
|
|
|
) -> SysResult {
|
|
|
|
) -> SysResult {
|
|
|
|
// TODO: check permissions based on uid/gid
|
|
|
|
// TODO: check permissions based on uid/gid
|
|
|
|
let proc = self.process();
|
|
|
|
let proc = self.process();
|
|
|
|
let path = unsafe { check_and_clone_cstr(path)? };
|
|
|
|
let path = check_and_clone_cstr(path)?;
|
|
|
|
let flags = AtFlags::from_bits_truncate(flags);
|
|
|
|
let flags = AtFlags::from_bits_truncate(flags);
|
|
|
|
if !proc.pid.is_init() {
|
|
|
|
if !proc.pid.is_init() {
|
|
|
|
// we trust pid 0 process
|
|
|
|
// we trust pid 0 process
|
|
|
@ -347,7 +347,7 @@ impl Syscall<'_> {
|
|
|
|
dirfd as isize, path, mode, flags
|
|
|
|
dirfd as isize, path, mode, flags
|
|
|
|
);
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
let inode =
|
|
|
|
let _inode =
|
|
|
|
proc.lookup_inode_at(dirfd, &path, !flags.contains(AtFlags::SYMLINK_NOFOLLOW))?;
|
|
|
|
proc.lookup_inode_at(dirfd, &path, !flags.contains(AtFlags::SYMLINK_NOFOLLOW))?;
|
|
|
|
Ok(0)
|
|
|
|
Ok(0)
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -419,7 +419,7 @@ impl Syscall<'_> {
|
|
|
|
len: usize,
|
|
|
|
len: usize,
|
|
|
|
) -> SysResult {
|
|
|
|
) -> SysResult {
|
|
|
|
let proc = self.process();
|
|
|
|
let proc = self.process();
|
|
|
|
let path = unsafe { check_and_clone_cstr(path)? };
|
|
|
|
let path = check_and_clone_cstr(path)?;
|
|
|
|
let slice = unsafe { self.vm().check_write_array(base, len)? };
|
|
|
|
let slice = unsafe { self.vm().check_write_array(base, len)? };
|
|
|
|
info!(
|
|
|
|
info!(
|
|
|
|
"readlinkat: dirfd: {}, path: {:?}, base: {:?}, len: {}",
|
|
|
|
"readlinkat: dirfd: {}, path: {:?}, base: {:?}, len: {}",
|
|
|
@ -465,7 +465,7 @@ impl Syscall<'_> {
|
|
|
|
|
|
|
|
|
|
|
|
pub fn sys_truncate(&mut self, path: *const u8, len: usize) -> SysResult {
|
|
|
|
pub fn sys_truncate(&mut self, path: *const u8, len: usize) -> SysResult {
|
|
|
|
let proc = self.process();
|
|
|
|
let proc = self.process();
|
|
|
|
let path = unsafe { check_and_clone_cstr(path)? };
|
|
|
|
let path = check_and_clone_cstr(path)?;
|
|
|
|
info!("truncate: path: {:?}, len: {}", path, len);
|
|
|
|
info!("truncate: path: {:?}, len: {}", path, len);
|
|
|
|
proc.lookup_inode(&path)?.resize(len)?;
|
|
|
|
proc.lookup_inode(&path)?.resize(len)?;
|
|
|
|
Ok(0)
|
|
|
|
Ok(0)
|
|
|
@ -496,12 +496,11 @@ impl Syscall<'_> {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
let mut writer = DirentBufWriter::new(buf);
|
|
|
|
let mut writer = DirentBufWriter::new(buf);
|
|
|
|
loop {
|
|
|
|
loop {
|
|
|
|
let name = match file.read_entry() {
|
|
|
|
let entry = match file.read_entry() {
|
|
|
|
Err(FsError::EntryNotFound) => break,
|
|
|
|
Err(FsError::EntryNotFound) => break,
|
|
|
|
r => r,
|
|
|
|
r => r,
|
|
|
|
}?;
|
|
|
|
}?;
|
|
|
|
// TODO: get ino from dirent
|
|
|
|
let ok = writer.try_write(entry.0 as u64, DirentType::from_type(&info.type_).bits(), &entry.1);
|
|
|
|
let ok = writer.try_write(0, DirentType::from_type(&info.type_).bits(), &name);
|
|
|
|
|
|
|
|
if !ok {
|
|
|
|
if !ok {
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -678,7 +677,7 @@ impl Syscall<'_> {
|
|
|
|
|
|
|
|
|
|
|
|
pub fn sys_unlinkat(&mut self, dirfd: usize, path: *const u8, flags: usize) -> SysResult {
|
|
|
|
pub fn sys_unlinkat(&mut self, dirfd: usize, path: *const u8, flags: usize) -> SysResult {
|
|
|
|
let proc = self.process();
|
|
|
|
let proc = self.process();
|
|
|
|
let path = unsafe { check_and_clone_cstr(path)? };
|
|
|
|
let path = check_and_clone_cstr(path)?;
|
|
|
|
let flags = AtFlags::from_bits_truncate(flags);
|
|
|
|
let flags = AtFlags::from_bits_truncate(flags);
|
|
|
|
info!(
|
|
|
|
info!(
|
|
|
|
"unlinkat: dirfd: {}, path: {:?}, flags: {:?}",
|
|
|
|
"unlinkat: dirfd: {}, path: {:?}, flags: {:?}",
|
|
|
@ -876,7 +875,7 @@ impl Process {
|
|
|
|
dirfd: usize,
|
|
|
|
dirfd: usize,
|
|
|
|
path: &str,
|
|
|
|
path: &str,
|
|
|
|
follow: bool,
|
|
|
|
follow: bool,
|
|
|
|
) -> Result<Arc<INode>, SysError> {
|
|
|
|
) -> Result<Arc<dyn INode>, SysError> {
|
|
|
|
debug!(
|
|
|
|
debug!(
|
|
|
|
"lookup_inode_at: dirfd: {:?}, cwd: {:?}, path: {:?}, follow: {:?}",
|
|
|
|
"lookup_inode_at: dirfd: {:?}, cwd: {:?}, path: {:?}, follow: {:?}",
|
|
|
|
dirfd as isize, self.cwd, path, follow
|
|
|
|
dirfd as isize, self.cwd, path, follow
|
|
|
@ -916,7 +915,7 @@ impl Process {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn lookup_inode(&self, path: &str) -> Result<Arc<INode>, SysError> {
|
|
|
|
pub fn lookup_inode(&self, path: &str) -> Result<Arc<dyn INode>, SysError> {
|
|
|
|
self.lookup_inode_at(AT_FDCWD, path, true)
|
|
|
|
self.lookup_inode_at(AT_FDCWD, path, true)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -951,6 +950,8 @@ impl From<FsError> for SysError {
|
|
|
|
FsError::IOCTLError => SysError::EINVAL,
|
|
|
|
FsError::IOCTLError => SysError::EINVAL,
|
|
|
|
FsError::NoDevice => SysError::EINVAL,
|
|
|
|
FsError::NoDevice => SysError::EINVAL,
|
|
|
|
FsError::Again => SysError::EAGAIN,
|
|
|
|
FsError::Again => SysError::EAGAIN,
|
|
|
|
|
|
|
|
FsError::Busy => SysError::EBUSY,
|
|
|
|
|
|
|
|
FsError::SymLoop => SysError::ELOOP,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|