@@ -20,6 +20,7 @@ use super::*;
20
20
use crate :: fs:: epoll:: EpollInstance ;
21
21
use crate :: fs:: FileLike ;
22
22
use crate :: process:: Process ;
23
+ use crate :: syscall:: SysError :: EINVAL ;
23
24
use rcore_fs:: vfs:: PollStatus ;
24
25
25
26
impl Syscall < ' _ > {
@@ -963,7 +964,12 @@ impl Syscall<'_> {
963
964
self . sys_symlinkat ( target, AT_FDCWD , linkpath)
964
965
}
965
966
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 {
967
973
let proc = self . process ( ) ;
968
974
let target = check_and_clone_cstr ( target) ?;
969
975
let linkpath = check_and_clone_cstr ( linkpath) ?;
@@ -976,19 +982,15 @@ impl Syscall<'_> {
976
982
977
983
// If linkpath exists, it will not be overwritten.
978
984
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 )
990
991
}
991
- }
992
+ _ => Err ( e. into ( ) ) ,
993
+ } ,
992
994
}
993
995
}
994
996
@@ -1050,6 +1052,48 @@ impl Syscall<'_> {
1050
1052
Ok ( 0 )
1051
1053
}
1052
1054
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
+
1053
1097
pub fn sys_sync ( & mut self ) -> SysResult {
1054
1098
ROOT_INODE . fs ( ) . sync ( ) ?;
1055
1099
Ok ( 0 )
0 commit comments