Skip to content

Commit ff9b0cc

Browse files
author
function2-llx
committed
add utimensat, fix touch
1 parent db9ef21 commit ff9b0cc

File tree

8 files changed

+79
-22
lines changed

8 files changed

+79
-22
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,4 @@ Cargo.lock
2929
modules/*/objs
3030
# Rust
3131
modules/*/target
32+
test/

kernel/src/fs/fcntl.rs

+2
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,5 @@ const F_LINUX_SPECIFIC_BASE: usize = 1024;
1212
pub const F_DUPFD_CLOEXEC: usize = F_LINUX_SPECIFIC_BASE + 6;
1313

1414
pub const O_CLOEXEC: usize = 02000000; /* set close_on_exec */
15+
16+
pub const AT_SYMLINK_NOFOLLOW: usize = 0x100;

kernel/src/fs/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ lazy_static! {
107107
};
108108
}
109109

110-
pub const FOLLOW_MAX_DEPTH: usize = 1;
110+
pub const FOLLOW_MAX_DEPTH: usize = 3;
111111

112112
pub trait INodeExt {
113113
fn read_as_vec(&self) -> Result<Vec<u8>>;

kernel/src/process/structs.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
use alloc::{boxed::Box, collections::BTreeMap, string::String, sync::Arc, sync::Weak, vec::Vec, collections::BTreeSet};
1+
use alloc::{
2+
boxed::Box, collections::BTreeMap, collections::BTreeSet, string::String, sync::Arc,
3+
sync::Weak, vec::Vec,
4+
};
25
use core::fmt;
36

47
use core::str;
@@ -18,14 +21,14 @@ use crate::ipc::SemProc;
1821
use crate::memory::{
1922
ByFrame, Delay, File, GlobalFrameAlloc, KernelStack, MemoryAttr, MemorySet, Read,
2023
};
21-
use crate::sync::{Condvar, SpinNoIrqLock as Mutex, SpinLock};
24+
use crate::sync::{Condvar, SpinLock, SpinNoIrqLock as Mutex};
2225

2326
use super::abi::{self, ProcInitInfo};
2427
use crate::process::thread_manager;
28+
use bitflags::_core::cell::Ref;
2529
use core::mem::MaybeUninit;
2630
use rcore_fs::vfs::INode;
2731
use rcore_thread::std_thread::yield_now;
28-
use bitflags::_core::cell::Ref;
2932

3033
#[allow(dead_code)]
3134
pub struct Thread {

kernel/src/syscall/fs.rs

+57-13
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use super::*;
2020
use crate::fs::epoll::EpollInstance;
2121
use crate::fs::FileLike;
2222
use crate::process::Process;
23+
use crate::syscall::SysError::EINVAL;
2324
use rcore_fs::vfs::PollStatus;
2425

2526
impl Syscall<'_> {
@@ -963,7 +964,12 @@ impl Syscall<'_> {
963964
self.sys_symlinkat(target, AT_FDCWD, linkpath)
964965
}
965966

966-
pub fn sys_symlinkat(&mut self, target: *const u8, newdirfd: usize, linkpath: *const u8) -> SysResult {
967+
pub fn sys_symlinkat(
968+
&mut self,
969+
target: *const u8,
970+
newdirfd: usize,
971+
linkpath: *const u8,
972+
) -> SysResult {
967973
let proc = self.process();
968974
let target = check_and_clone_cstr(target)?;
969975
let linkpath = check_and_clone_cstr(linkpath)?;
@@ -976,19 +982,15 @@ impl Syscall<'_> {
976982

977983
// If linkpath exists, it will not be overwritten.
978984
match dir_inode.find(filename) {
979-
Ok(_) => {
980-
Err(SysError::EEXIST)
981-
}
982-
Err(e) => {
983-
match e {
984-
FsError::EntryNotFound => {
985-
let symlink = dir_inode.create(filename, FileType::SymLink, 0o777)?;
986-
symlink.write_at(0, target.as_bytes())?;
987-
Ok(0)
988-
},
989-
_ => Err(e.into())
985+
Ok(_) => Err(SysError::EEXIST),
986+
Err(e) => match e {
987+
FsError::EntryNotFound => {
988+
let symlink = dir_inode.create(filename, FileType::SymLink, 0o777)?;
989+
symlink.write_at(0, target.as_bytes())?;
990+
Ok(0)
990991
}
991-
}
992+
_ => Err(e.into()),
993+
},
992994
}
993995
}
994996

@@ -1050,6 +1052,48 @@ impl Syscall<'_> {
10501052
Ok(0)
10511053
}
10521054

1055+
pub fn sys_utimensat(
1056+
&mut self,
1057+
dirfd: usize,
1058+
pathname: *const u8,
1059+
times: *const TimeSpec,
1060+
flags: usize,
1061+
) -> SysResult {
1062+
info!(
1063+
"utimensat(raw): dirfd: {}, pathname: {}, times: {}, flags: {:#x}",
1064+
dirfd as i64, pathname as usize, times as usize, flags
1065+
);
1066+
let pathname = check_and_clone_cstr(pathname)?;
1067+
let proc = self.process();
1068+
let times = if times.is_null() {
1069+
[TimeSpec::get_epoch(), TimeSpec::get_epoch()]
1070+
} else {
1071+
let times = unsafe { self.vm().check_read_array(times, 2)? };
1072+
[times[0], times[1]]
1073+
};
1074+
info!(
1075+
"utimensat: dirfd: {}, pathname: {}, times: {:?}, flags: {:#x}",
1076+
dirfd as i64, pathname, times, flags
1077+
);
1078+
let follow = match flags {
1079+
0 => true,
1080+
fcntl::AT_SYMLINK_NOFOLLOW => false,
1081+
_ => return Err(EINVAL),
1082+
};
1083+
let inode = proc.lookup_inode_at(dirfd, &pathname, follow)?;
1084+
let mut metadata = inode.metadata()?;
1085+
metadata.atime = Timespec {
1086+
sec: times[0].sec as i64,
1087+
nsec: times[0].nsec as i32,
1088+
};
1089+
metadata.mtime = Timespec {
1090+
sec: times[1].sec as i64,
1091+
nsec: times[1].nsec as i32,
1092+
};
1093+
inode.set_metadata(&metadata)?;
1094+
Ok(0)
1095+
}
1096+
10531097
pub fn sys_sync(&mut self) -> SysResult {
10541098
ROOT_INODE.fs().sync()?;
10551099
Ok(0)

kernel/src/syscall/mem.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ impl Syscall<'_> {
2020
let flags = MmapFlags::from_bits_truncate(flags);
2121
info!(
2222
"mmap: addr={:#x}, size={:#x}, prot={:?}, flags={:?}, fd={}, offset={:#x}",
23-
addr, len, prot, flags, fd, offset
23+
addr, len, prot, flags, fd as isize, offset
2424
);
2525

2626
let mut proc = self.process();

kernel/src/syscall/mod.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,9 @@ impl Syscall<'_> {
135135
args[4],
136136
),
137137
SYS_UNLINKAT => self.sys_unlinkat(args[0], args[1] as *const u8, args[2]),
138-
SYS_SYMLINKAT => self.sys_symlinkat(args[0] as *const u8, args[1] as usize, args[2] as *const u8),
138+
SYS_SYMLINKAT => {
139+
self.sys_symlinkat(args[0] as *const u8, args[1] as usize, args[2] as *const u8)
140+
}
139141
SYS_READLINKAT => {
140142
self.sys_readlinkat(args[0], args[1] as *const u8, args[2] as *mut u8, args[3])
141143
}
@@ -146,7 +148,12 @@ impl Syscall<'_> {
146148
SYS_FACCESSAT => self.sys_faccessat(args[0], args[1] as *const u8, args[2], args[3]),
147149
SYS_DUP3 => self.sys_dup3(args[0], args[1], args[2]),
148150
SYS_PIPE2 => self.sys_pipe(args[0] as *mut u32), // TODO: handle `flags`
149-
SYS_UTIMENSAT => self.unimplemented("utimensat", Ok(0)),
151+
SYS_UTIMENSAT => self.sys_utimensat(
152+
args[0],
153+
args[1] as *const u8,
154+
args[2] as *const TimeSpec,
155+
args[3],
156+
),
150157
SYS_COPY_FILE_RANGE => self.sys_copy_file_range(
151158
args[0],
152159
args[1] as *mut usize,

kernel/src/syscall/time.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,8 @@ impl TimeVal {
129129
#[repr(C)]
130130
#[derive(Debug, Copy, Clone)]
131131
pub struct TimeSpec {
132-
sec: usize,
133-
nsec: usize,
132+
pub sec: usize,
133+
pub nsec: usize,
134134
}
135135

136136
impl TimeSpec {

0 commit comments

Comments
 (0)