diff options
Diffstat (limited to 'libtrivfs')
-rw-r--r-- | libtrivfs/file-utimes.c | 34 | ||||
-rw-r--r-- | libtrivfs/times.c | 64 |
2 files changed, 78 insertions, 20 deletions
diff --git a/libtrivfs/file-utimes.c b/libtrivfs/file-utimes.c index 827c0554..7c5eaf43 100644 --- a/libtrivfs/file-utimes.c +++ b/libtrivfs/file-utimes.c @@ -25,3 +25,37 @@ trivfs_S_file_utimes (struct trivfs_protid *cred, { return cred ? file_utimes (cred->realnode, atime, mtime) : EOPNOTSUPP; } + +kern_return_t +trivfs_S_file_utimens (struct trivfs_protid *cred, + mach_port_t reply, mach_msg_type_name_t reply_type, + struct timespec atime, struct timespec mtime) +{ + kern_return_t err; + + if (!cred) + return EOPNOTSUPP; + +#ifdef HAVE_FILE_UTIMENS + err = file_utimens (cred->realnode, atime, mtime); + + if (err == EMIG_BAD_ID || err == EOPNOTSUPP) +#endif + { + time_value_t atim, mtim; + + if (atime.tv_nsec == UTIME_NOW) + atim.microseconds = -1; + else + TIMESPEC_TO_TIME_VALUE (&atim, &atime); + + if (mtime.tv_nsec == UTIME_NOW) + mtim.microseconds = -1; + else + TIMESPEC_TO_TIME_VALUE (&mtim, &mtime); + + err = file_utimes (cred->realnode, atim, mtim); + } + + return err; +} diff --git a/libtrivfs/times.c b/libtrivfs/times.c index 42e668d7..5e20bf10 100644 --- a/libtrivfs/times.c +++ b/libtrivfs/times.c @@ -21,36 +21,60 @@ error_t trivfs_set_atime (struct trivfs_control *cntl) { error_t err; - struct stat st; - time_value_t atime; - time_value_t mtime; +#ifdef HAVE_FILE_UTIMENS + struct timespec atime; + struct timespec mtime; - err = io_stat (cntl->underlying, &st); - if (err) - return err; + atime.tv_sec = 0; + atime.tv_nsec = UTIME_NOW; + mtime.tv_sec = 0; + mtime.tv_nsec = UTIME_OMIT; - mtime.seconds = st.st_mtim.tv_sec; - mtime.microseconds = st.st_mtim.tv_nsec / 1000; - atime.microseconds = -1; + err = file_utimens (cntl->underlying, atime, mtime); - return file_utimes (cntl->underlying, atime, mtime); + if (err == MIG_BAD_ID || err == EOPNOTSUPP) +#endif + { + struct stat st; + time_value_t atim, mtim; + + io_stat (cntl->underlying, &st); + + TIMESPEC_TO_TIME_VALUE (&atim, &st.st_atim); + mtim.microseconds = -1; + err = file_utimes (cntl->underlying, atim, mtim); + } + + return err; } error_t trivfs_set_mtime (struct trivfs_control *cntl) { error_t err; - struct stat st; - time_value_t atime; - time_value_t mtime; +#ifdef HAVE_FILE_UTIMENS + struct timespec atime; + struct timespec mtime; + + atime.tv_sec = 0; + atime.tv_nsec = UTIME_OMIT; + mtime.tv_sec = 0; + mtime.tv_nsec = UTIME_NOW; + + err = file_utimens (cntl->underlying, atime, mtime); + + if (err == MIG_BAD_ID || err == EOPNOTSUPP) +#endif + { + struct stat st; + time_value_t atim, mtim; - err = io_stat (cntl->underlying, &st); - if (err) - return err; + io_stat (cntl->underlying, &st); - atime.seconds = st.st_atim.tv_sec; - atime.microseconds = st.st_atim.tv_nsec / 1000; - mtime.microseconds = -1; + atim.microseconds = -1; + TIMESPEC_TO_TIME_VALUE (&mtim, &st.st_mtim); + err = file_utimes (cntl->underlying, atim, mtim); + } - return file_utimes (cntl->underlying, atime, mtime); + return err; } |