aboutsummaryrefslogtreecommitdiff
path: root/libtrivfs
diff options
context:
space:
mode:
Diffstat (limited to 'libtrivfs')
-rw-r--r--libtrivfs/file-utimes.c34
-rw-r--r--libtrivfs/times.c64
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;
}