@@ -2,10 +2,10 @@ use core::ffi::{c_char, c_int, c_void};
22
33use alloc:: ffi:: CString ;
44use axerrno:: { LinuxError , LinuxResult } ;
5- use linux_raw_sys:: general:: { __kernel_ino_t, __kernel_off_t, AT_FDCWD , AT_REMOVEDIR } ;
5+ use linux_raw_sys:: general:: { __kernel_ino_t, __kernel_off_t, AT_FDCWD , AT_REMOVEDIR , timespec } ;
66
77use crate :: {
8- fd:: { Directory , FileLike } ,
8+ fd:: { Directory , FileLike , get_file_like } ,
99 path:: { HARDLINK_MANAGER , handle_file_path} ,
1010 ptr:: { UserConstPtr , UserPtr , nullable} ,
1111} ;
@@ -318,72 +318,72 @@ pub const UTIME_NOW: usize = 0x3fffffff;
318318/// when nsec is UTIME_OMIT,donot modify time
319319pub const UTIME_OMIT : usize = 0x3ffffffe ;
320320
321- // / Modify the timestamp of file or dir
322- // / if fir_fd < 0, it determines the file together with path
323- // / if fir_fd >=0, it is the fd of the file
324- // / nsec is omited except for special values now
325- // pub fn sys_utimensat(
326- // dir_fd: i32,
327- // path: UserConstPtr<c_char>,
328- // times: UserConstPtr<timespec>,
329- // _flags: i32,
330- // ) -> LinuxResult<isize> {
331- // if dir_fd != AT_FDCWD as _ && (dir_fd as isize) < 0 {
332- // return Err(LinuxError::EBADF); // wrong dir_fd
333- // }
334-
335- // let times = times.get_as_array (2)?;
336- // let (atime, mtime): (timespec, timespec) = unsafe { (* times, *( times.add(1))) } ;
337- // // FIXME: this is time elapsed since system boot, but not timestamp now
338- // let current_s = axhal::time::monotonic_time_nanos() as i64 / 1000 / 1000;
339- // let now = current_s as usize;
340- // info!(
341- // "sys_utimensat: dir_fd={}; atime=({}, {}); mtime=({}, {}); now={}",
342- // dir_fd, atime.tv_sec, atime.tv_nsec, mtime.tv_sec, mtime.tv_nsec, now
343- // );
344- // // TODO: simplify the code
345- // if (dir_fd as isize) > 0 {
346- // let file = get_file_like(dir_fd as _)?;
347- // match atime.tv_nsec as _ {
348- // UTIME_NOW => {
349- // _ = file.set_atime(now);
350- // }
351- // UTIME_OMIT => {}
352- // _ => {
353- // _ = file.set_atime(atime.tv_sec as _);
354- // }
355- // };
356- // match mtime.tv_nsec as _ {
357- // UTIME_NOW => {
358- // _ = file.set_mtime(now);
359- // }
360- // UTIME_OMIT => {}
361- // _ => {
362- // _ = file.set_mtime(mtime.tv_sec as _);
363- // }
364- // };
365- // } else {
366- // let file = axfs::fops::File::open(path.get_as_str()?, &axfs::fops::OpenOptions::new())
367- // .map_err(|_| LinuxError::ENOTDIR)?;
368- // match atime.tv_nsec as _ {
369- // UTIME_NOW => {
370- // _ = file.set_atime(now);
371- // }
372- // UTIME_OMIT => {}
373- // _ => {
374- // _ = file.set_atime(atime.tv_sec as _);
375- // }
376- // };
377- // match mtime.tv_nsec as _ {
378- // UTIME_NOW => {
379- // _ = file.set_mtime(now);
380- // }
381- // UTIME_OMIT => {}
382- // _ => {
383- // _ = file.set_mtime(mtime.tv_sec as _);
384- // }
385- // };
386- // };
387-
388- // Ok(0)
389- // }
321+ /// Modify the timestamp of file or dir
322+ /// if fir_fd < 0, it determines the file together with path
323+ /// if fir_fd >=0, it is the fd of the file
324+ /// nsec is omited except for special values now
325+ pub fn sys_utimensat (
326+ dir_fd : i32 ,
327+ path : UserConstPtr < c_char > ,
328+ times : UserConstPtr < timespec > ,
329+ _flags : i32 ,
330+ ) -> LinuxResult < isize > {
331+ if dir_fd != AT_FDCWD as _ && ( dir_fd as isize ) < 0 {
332+ return Err ( LinuxError :: EBADF ) ; // wrong dir_fd
333+ }
334+
335+ let times = times. get_as_slice ( 2 ) ?;
336+ let ( atime, mtime) : ( timespec , timespec ) = ( times[ 0 ] , times[ 1 ] ) ;
337+ // FIXME: this is time elapsed since system boot, but not timestamp now
338+ let current_s = axhal:: time:: monotonic_time_nanos ( ) as i64 / 1000 / 1000 ;
339+ let now = current_s as usize ;
340+ info ! (
341+ "sys_utimensat: dir_fd={}; atime=({}, {}); mtime=({}, {}); now={}" ,
342+ dir_fd, atime. tv_sec, atime. tv_nsec, mtime. tv_sec, mtime. tv_nsec, now
343+ ) ;
344+ // TODO: simplify the code
345+ if ( dir_fd as isize ) > 0 {
346+ let file = get_file_like ( dir_fd as _ ) ?;
347+ match atime. tv_nsec as _ {
348+ UTIME_NOW => {
349+ _ = file. set_atime ( now) ;
350+ }
351+ UTIME_OMIT => { }
352+ _ => {
353+ _ = file. set_atime ( atime. tv_sec as _ ) ;
354+ }
355+ } ;
356+ match mtime. tv_nsec as _ {
357+ UTIME_NOW => {
358+ _ = file. set_mtime ( now) ;
359+ }
360+ UTIME_OMIT => { }
361+ _ => {
362+ _ = file. set_mtime ( mtime. tv_sec as _ ) ;
363+ }
364+ } ;
365+ } else {
366+ let file = axfs:: fops:: File :: open ( path. get_as_str ( ) ?, & axfs:: fops:: OpenOptions :: new ( ) )
367+ . map_err ( |_| LinuxError :: ENOTDIR ) ?;
368+ match atime. tv_nsec as _ {
369+ UTIME_NOW => {
370+ _ = file. set_atime ( now) ;
371+ }
372+ UTIME_OMIT => { }
373+ _ => {
374+ _ = file. set_atime ( atime. tv_sec as _ ) ;
375+ }
376+ } ;
377+ match mtime. tv_nsec as _ {
378+ UTIME_NOW => {
379+ _ = file. set_mtime ( now) ;
380+ }
381+ UTIME_OMIT => { }
382+ _ => {
383+ _ = file. set_mtime ( mtime. tv_sec as _ ) ;
384+ }
385+ } ;
386+ } ;
387+
388+ Ok ( 0 )
389+ }
0 commit comments