diff --git a/sysdeps/mach/hurd/bits/stat.h b/sysdeps/mach/hurd/bits/stat.h index f60a58a..c2d0cc2 100644 --- a/sysdeps/mach/hurd/bits/stat.h +++ b/sysdeps/mach/hurd/bits/stat.h @@ -246,6 +246,10 @@ struct stat64 # define SF_NOUNLINK 0x00100000 /* file may not be removed or renamed */ # define SF_SNAPSHOT 0x00200000 /* snapshot inode */ +/* Time flags for futimens. */ +#define UTIME_NOW -1 /* corresponds to the current time */ +#define UTIME_OMIT -2 /* target time is omitted */ + __BEGIN_DECLS /* Set file flags for FILE to FLAGS. */ diff --git a/sysdeps/mach/hurd/futimens.c b/sysdeps/mach/hurd/futimens.c index 4f82f1e..3159cb0 100644 --- a/sysdeps/mach/hurd/futimens.c +++ b/sysdeps/mach/hurd/futimens.c @@ -27,24 +27,51 @@ int __futimens (int fd, const struct timespec tsp[2]) { - time_value_t atime, mtime; + struct timespec atime, mtime; error_t err; if (tsp == NULL) { - /* Setting the number of microseconds to `-1' tells the + /* Setting the number of nanoseconds to UTIME_NOW tells the underlying filesystems to use the current time. */ - atime.microseconds = mtime.microseconds = -1; + atime.tv_sec = 0; + atime.tv_nsec = UTIME_NOW; + mtime.tv_sec = 0; + mtime.tv_nsec = UTIME_NOW; } else { - atime.seconds = tsp[0].tv_sec; - atime.microseconds = tsp[0].tv_nsec / 1000; - mtime.seconds = tsp[1].tv_sec; - mtime.microseconds = tsp[1].tv_nsec / 1000; + atime = tsp[0]; + mtime = tsp[1]; } - err = HURD_DPORT_USE (fd, __file_utimes (port, atime, mtime)); + err = HURD_DPORT_USE (fd, __file_utimens (port, atime, mtime)); + + if (err == MIG_BAD_ID || err == EOPNOTSUPP) + { + time_value_t atim, mtim; + + if (tsp == NULL) + /* Setting the number of microseconds to `-1' tells the + underlying filesystems to use the current time. */ + atim.microseconds = mtim.microseconds = -1; + else if (tsp[0].tv_nsec == UTIME_OMIT || tsp[1].tv_nsec == UTIME_OMIT) + return EOPNOTSUPP; + else + { + if (tsp[0].tv_nsec == UTIME_NOW) + atim.microseconds = -1; + else + TIMESPEC_TO_TIME_VALUE (&atim, &(tsp[0])); + if (tsp[1].tv_nsec == UTIME_NOW) + mtim.microseconds = -1; + else + TIMESPEC_TO_TIME_VALUE (&mtim, &(tsp[1])); + } + + err = HURD_DPORT_USE (fd, __file_utimes (port, atim, mtim)); + } + return err ? __hurd_dfail (fd, err) : 0; } weak_alias (__futimens, futimens) diff --git a/sysdeps/mach/hurd/futimes.c b/sysdeps/mach/hurd/futimes.c index c325d44..dc8ae61 100644 --- a/sysdeps/mach/hurd/futimes.c +++ b/sysdeps/mach/hurd/futimes.c @@ -27,24 +27,44 @@ int __futimes (int fd, const struct timeval tvp[2]) { - union tv - { - struct timeval tv; - time_value_t tvt; - }; - const union tv *u = (const union tv *) tvp; - union tv nulltv[2]; + struct timespec atime, mtime; error_t err; if (tvp == NULL) { - /* Setting the number of microseconds to `-1' tells the + /* Setting the number of nanoseconds to UTIME_NOW tells the underlying filesystems to use the current time. */ - nulltv[0].tvt.microseconds = nulltv[1].tvt.microseconds = -1; - u = nulltv; + atime.tv_sec = 0; + atime.tv_nsec = UTIME_NOW; + mtime.tv_sec = 0; + mtime.tv_nsec = UTIME_NOW; + } + else + { + TIMEVAL_TO_TIMESPEC (&tvp[0], &atime); + TIMEVAL_TO_TIMESPEC (&tvp[1], &mtime); + } + + err = HURD_DPORT_USE (fd, __file_utimens (port, atime, mtime)); + if (err == EMIG_BAD_ID || err == EOPNOTSUPP) + { + time_value_t atim, mtim; + + if (tvp == NULL) + /* Setting the number of microseconds to `-1' tells the + underlying filesystems to use the current time. */ + atim.microseconds = mtim.microseconds = -1; + else + { + atim.seconds = tvp[0].tv_sec; + atim.microseconds = tvp[0].tv_usec; + mtim.seconds = tvp[1].tv_sec; + mtim.microseconds = tvp[1].tv_usec; + } + + err = HURD_DPORT_USE (fd, __file_utimes (port, atim, mtim)); } - err = HURD_DPORT_USE (fd, __file_utimes (port, u[0].tvt, u[1].tvt)); return err ? __hurd_dfail (fd, err) : 0; } weak_alias (__futimes, futimes) diff --git a/sysdeps/mach/hurd/lutimes.c b/sysdeps/mach/hurd/lutimes.c index 260842d..c1d5566 100644 --- a/sysdeps/mach/hurd/lutimes.c +++ b/sysdeps/mach/hurd/lutimes.c @@ -27,28 +27,50 @@ int __lutimes (const char *file, const struct timeval tvp[2]) { - union tv - { - struct timeval tv; - time_value_t tvt; - }; - const union tv *u = (const union tv *) tvp; - union tv nulltv[2]; + struct timespec atime, mtime; error_t err; file_t port; + port = __file_name_lookup (file, O_NOLINK, 0); + if (port == MACH_PORT_NULL) + return -1; + if (tvp == NULL) { - /* Setting the number of microseconds to `-1' tells the + /* Setting the number of nanoseconds to UTIME_NOW tells the underlying filesystems to use the current time. */ - nulltv[0].tvt.microseconds = nulltv[1].tvt.microseconds = -1; - u = nulltv; + atime.tv_sec = 0; + atime.tv_nsec = UTIME_NOW; + mtime.tv_sec = 0; + mtime.tv_nsec = UTIME_NOW; + } + else + { + TIMEVAL_TO_TIMESPEC (&tvp[0], &atime); + TIMEVAL_TO_TIMESPEC (&tvp[1], &mtime); + } + + err = __file_utimens (port, atime, mtime); + + if (err == MIG_BAD_ID || err == EOPNOTSUPP) + { + time_value_t atim, mtim; + + if (tvp == NULL) + /* Setting the number of microseconds to `-1' tells the + underlying filesystems to use the current time. */ + atim.microseconds = mtim.microseconds = -1; + else + { + atim.seconds = tvp[0].tv_sec; + atim.microseconds = tvp[0].tv_usec; + mtim.seconds = tvp[1].tv_sec; + mtim.microseconds = tvp[1].tv_usec; + } + + err = __file_utimes (port, atim, mtim); } - port = __file_name_lookup (file, O_NOLINK, 0); - if (port == MACH_PORT_NULL) - return -1; - err = __file_utimes (port, u[0].tvt, u[1].tvt); __mach_port_deallocate (__mach_task_self (), port); if (err) return __hurd_fail (err); diff --git a/sysdeps/mach/hurd/utimes.c b/sysdeps/mach/hurd/utimes.c index 6739b79..1578637 100644 --- a/sysdeps/mach/hurd/utimes.c +++ b/sysdeps/mach/hurd/utimes.c @@ -27,28 +27,50 @@ __utimes (file, tvp) const char *file; const struct timeval tvp[2]; { - union tv - { - struct timeval tv; - time_value_t tvt; - }; - const union tv *u = (const union tv *) tvp; - union tv nulltv[2]; + struct timespec atime, mtime; error_t err; file_t port; + port = __file_name_lookup (file, 0, 0); + if (port == MACH_PORT_NULL) + return -1; + if (tvp == NULL) { - /* Setting the number of microseconds to `-1' tells the + /* Setting the number of nanoseconds to UTIME_NOW tells the underlying filesystems to use the current time. */ - nulltv[0].tvt.microseconds = nulltv[1].tvt.microseconds = -1; - u = nulltv; + atime.tv_sec = 0; + atime.tv_nsec = UTIME_NOW; + mtime.tv_sec = 0; + mtime.tv_nsec = UTIME_NOW; + } + else + { + TIMEVAL_TO_TIMESPEC (&tvp[0], &atime); + TIMEVAL_TO_TIMESPEC (&tvp[1], &mtime); + } + + err = __file_utimens (port, atime, mtime); + + if (err == MIG_BAD_ID || err == EOPNOTSUPP) + { + time_value_t atim, mtim; + + if (tvp == NULL) + /* Setting the number of microseconds to `-1' tells the + underlying filesystems to use the current time. */ + atim.microseconds = mtim.microseconds = -1; + else + { + atim.seconds = tvp[0].tv_sec; + atim.microseconds = tvp[0].tv_usec; + mtim.seconds = tvp[1].tv_sec; + mtim.microseconds = tvp[1].tv_usec; + } + + err = __file_utimes (port, atim, mtim); } - port = __file_name_lookup (file, 0, 0); - if (port == MACH_PORT_NULL) - return -1; - err = __file_utimes (port, u[0].tvt, u[1].tvt); __mach_port_deallocate (__mach_task_self (), port); if (err) return __hurd_fail (err);