#include <string.h>
#include <uk/posix-fdio.h>
+#include <uk/posix-time.h>
+#include <uk/timeutil.h>
#include "fdio-impl.h"
+#define statx_time(ts) ((struct uk_statx_timestamp){ \
+ .tv_sec = (ts).tv_sec, \
+ .tv_nsec = (ts).tv_nsec \
+})
+
static inline
dev_t nums2dev(__u32 major, __u32 minor)
{
uk_file_wunlock(of->file);
return r;
}
+
+int uk_sys_futimens(struct uk_ofile *of, const struct timespec *times)
+{
+ int r;
+ unsigned int mask;
+ struct uk_statx sx;
+ struct timespec t;
+ const int iolock = _SHOULD_LOCK(of->mode);
+
+ /* TODO: check if uid is root or file owner for custom times */
+
+ if (!times ||
+ times[0].tv_nsec == UTIME_NOW || times[1].tv_nsec == UTIME_NOW) {
+ r = uk_sys_clock_gettime(CLOCK_REALTIME, &t);
+ if (unlikely(r)) {
+ UK_ASSERT(r < 0);
+ /* The futime(n)s manpages do not specify an error case
+ * for failing to get the current time, and failure of
+ * the above call may indicate a misconfigured kernel.
+ * Print a warning before erroring out.
+ */
+ uk_pr_warn("Failed to get current time: %d\n", r);
+ return r;
+ }
+ }
+
+ if (!times) {
+ mask = UK_STATX_ATIME | UK_STATX_MTIME;
+ sx.stx_atime = statx_time(t);
+ sx.stx_mtime = statx_time(t);
+ } else {
+ mask = 0;
+ if (times[0].tv_nsec != UTIME_OMIT) {
+ mask |= UK_STATX_ATIME;
+ if (times[0].tv_nsec == UTIME_NOW)
+ sx.stx_atime = statx_time(t);
+ else
+ sx.stx_atime = statx_time(times[0]);
+ }
+ if (times[1].tv_nsec != UTIME_OMIT) {
+ mask |= UK_STATX_MTIME;
+ if (times[1].tv_nsec == UTIME_NOW)
+ sx.stx_mtime = statx_time(t);
+ else
+ sx.stx_mtime = statx_time(times[1]);
+ }
+ }
+
+ if (iolock)
+ uk_file_wlock(of->file);
+ r = uk_file_setstat(of->file, mask, &sx);
+ if (iolock)
+ uk_file_wunlock(of->file);
+ return r;
+}
+
+int uk_sys_futimes(struct uk_ofile *of, const struct timeval *tv)
+{
+ return uk_sys_futimens(of, tv ? &uk_time_spec_from_val(tv) : NULL);
+}
#define __UK_POSIX_FDIO_H__
#include <sys/stat.h>
+#include <sys/time.h>
#include <uk/posix-fd.h>
int uk_sys_fchown(struct uk_ofile *of, uid_t owner, gid_t group);
+int uk_sys_futimes(struct uk_ofile *of, const struct timeval *tv);
+
+int uk_sys_futimens(struct uk_ofile *of, const struct timespec *times);
+
/* Control */
int uk_sys_ioctl(struct uk_ofile *of, int cmd, void *arg);