[hurd,commited,1/2] hurd: Define and pass UTIME_NOW and UTIME_OMIT to new file_utimens RPC
Commit Message
From: Flávio Cruz <flaviocruz@gmail.com>
* sysdeps/mach/hurd/bits/stat.h [__USE_ATFILE] (UTIME_NOW,
UTIME_OMIT): New macros.
* sysdeps/mach/hurd/futimens.c (__futimens): Try to use __file_utimens
before reverting to converting time spec to time value and calling
__file_utimes.
* sysdeps/mach/hurd/utime-helper.c: New file.
* sysdeps/mach/hurd/futimes.c: Include "utime-helper.c".
(__futimes): Try to use utime_ts_from_tval and __file_utimens before
reverting to utime_tvalue_from_tval and __file_utimes.
* sysdeps/mach/hurd/lutimes.c: Include "utime-helper.c".
(__lutimes): Just call hurd_futimens after lookup.
* sysdeps/mach/hurd/utimes.c: Likewise.
---
ChangeLog | 15 +++++++
sysdeps/mach/hurd/bits/stat.h | 5 +++
sysdeps/mach/hurd/futimens.c | 45 +++++++++++++++++----
sysdeps/mach/hurd/futimes.c | 26 ++++++-------
sysdeps/mach/hurd/lutimes.c | 21 +++-------
sysdeps/mach/hurd/utime-helper.c | 84 ++++++++++++++++++++++++++++++++++++++++
sysdeps/mach/hurd/utimes.c | 21 +++-------
7 files changed, 164 insertions(+), 53 deletions(-)
create mode 100644 sysdeps/mach/hurd/utime-helper.c
Comments
On Tue, 2018-03-06 at 08:45 +0100, Samuel Thibault wrote:
[...]
> --- a/sysdeps/mach/hurd/futimens.c
> +++ b/sysdeps/mach/hurd/futimens.c
> @@ -27,24 +27,53 @@
> int
> __futimens (int fd, const struct timespec tsp[2])
> {
[...]
> + err = HURD_DPORT_USE (fd, __file_utimens (port, atime, mtime));
> +
> + if (err == MIG_BAD_ID || err == EOPNOTSUPP)
> + {
[...]
> int
> __futimes (int fd, const struct timeval tvp[2])
> {
[...]
> + err = HURD_DPORT_USE (fd, __file_utimens (port, atime, mtime));
> +
> + if (err == EMIG_BAD_ID || err == EOPNOTSUPP)
> {
[...]
Shouldn't this error be cached, to avoid making twice as many calls on
older Hurd versions? That seems to be the usual practice for Linux
glibc code that has fallbacks for missing system calls.
Ben.
Hello,
Ben Hutchings, on mar. 06 mars 2018 19:56:35 +0000, wrote:
> On Tue, 2018-03-06 at 08:45 +0100, Samuel Thibault wrote:
> [...]
> > --- a/sysdeps/mach/hurd/futimens.c
> > +++ b/sysdeps/mach/hurd/futimens.c
> > @@ -27,24 +27,53 @@
> > int
> > __futimens (int fd, const struct timespec tsp[2])
> > {
> [...]
> > + err = HURD_DPORT_USE (fd, __file_utimens (port, atime, mtime));
> > +
> > + if (err == MIG_BAD_ID || err == EOPNOTSUPP)
> > + {
> [...]
> Shouldn't this error be cached, to avoid making twice as many calls on
> older Hurd versions?
No, because it depends on the actual translator that we are talking to.
There can be one which doesn't implement the new RPC yet, while others
do (and most of them will, we don't usually run old hurd servers with a
new glibc).
Samuel
@@ -1,3 +1,18 @@
+2018-03-05 Flávio Cruz <flaviocruz@gmail.com>
+
+ * sysdeps/mach/hurd/bits/stat.h [__USE_ATFILE] (UTIME_NOW,
+ UTIME_OMIT): New macros.
+ * sysdeps/mach/hurd/futimens.c (__futimens): Try to use __file_utimens
+ before reverting to converting time spec to time value and calling
+ __file_utimes.
+ * sysdeps/mach/hurd/utime-helper.c: New file.
+ * sysdeps/mach/hurd/futimes.c: Include "utime-helper.c".
+ (__futimes): Try to use utime_ts_from_tval and __file_utimens before
+ reverting to utime_tvalue_from_tval and __file_utimes.
+ * sysdeps/mach/hurd/lutimes.c: Include "utime-helper.c".
+ (__lutimes): Just call hurd_futimens after lookup.
+ * sysdeps/mach/hurd/utimes.c: Likewise.
+
2018-03-05 Samuel Thibault <samuel.thibault@ens-lyon.org>
* bits/sigaction.h: Add include guard.
@@ -244,6 +244,11 @@ struct stat64
# define SF_NOUNLINK 0x00100000 /* file may not be removed or renamed */
# define SF_SNAPSHOT 0x00200000 /* snapshot inode */
+#ifdef __USE_ATFILE
+# define UTIME_NOW -1 /* corresponds to the current time */
+# define UTIME_OMIT -2 /* target time is omitted */
+#endif
+
__BEGIN_DECLS
/* Set file flags for FILE to FLAGS. */
@@ -27,24 +27,53 @@
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_NOW)
+ atim.microseconds = -1;
+ else if (tsp[0].tv_nsec == UTIME_OMIT)
+ atim.microseconds = -2;
+ else
+ TIMESPEC_TO_TIME_VALUE (&atim, &(tsp[0]));
+ if (tsp[1].tv_nsec == UTIME_NOW)
+ mtim.microseconds = -1;
+ else if (tsp[1].tv_nsec == UTIME_OMIT)
+ mtim.microseconds = -2;
+ 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)
@@ -22,29 +22,29 @@
#include <hurd.h>
#include <hurd/fd.h>
+#include "utime-helper.c"
+
/* Change the access time of FD to TVP[0] and
the modification time of FD to TVP[1]. */
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)
+ utime_ts_from_tval (tvp, &atime, &mtime);
+
+ err = HURD_DPORT_USE (fd, __file_utimens (port, atime, mtime));
+
+ if (err == EMIG_BAD_ID || err == EOPNOTSUPP)
{
- /* Setting the number of microseconds to `-1' tells the
- underlying filesystems to use the current time. */
- nulltv[0].tvt.microseconds = nulltv[1].tvt.microseconds = -1;
- u = nulltv;
+ time_value_t atim, mtim;
+
+ utime_tvalue_from_tval (tvp, &atim, &mtim);
+
+ 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)
@@ -22,33 +22,22 @@
#include <hurd.h>
#include <fcntl.h>
+#include "utime-helper.c"
+
/* Change the access time of FILE to TVP[0] and
the modification time of FILE to TVP[1]. */
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];
error_t err;
file_t port;
- if (tvp == NULL)
- {
- /* Setting the number of microseconds to `-1' tells the
- underlying filesystems to use the current time. */
- nulltv[0].tvt.microseconds = nulltv[1].tvt.microseconds = -1;
- u = nulltv;
- }
-
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);
+
+ err = hurd_futimens (port, tvp);
+
__mach_port_deallocate (__mach_task_self (), port);
if (err)
return __hurd_fail (err);
new file mode 100644
@@ -0,0 +1,84 @@
+/* Helpers for utimes/utimens conversions.
+ Copyright (C) 2015-2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <hurd/hurd_types.h>
+#include <stddef.h>
+#include <sys/time.h>
+
+/* Initializes atime/mtime timespec structures from an array of timeval. */
+static inline void
+utime_ts_from_tval (const struct timeval tvp[2],
+ struct timespec *atime, struct timespec *mtime)
+{
+ if (tvp == NULL)
+ {
+ /* Setting the number of nanoseconds to UTIME_NOW tells the
+ underlying filesystems to use the current time. */
+ 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);
+ }
+}
+
+/* Initializes atime/mtime time_value_t structures from an array of timeval. */
+static inline void
+utime_tvalue_from_tval (const struct timeval tvp[2],
+ time_value_t *atime, time_value_t *mtime)
+{
+ if (tvp == NULL)
+ /* Setting the number of microseconds to `-1' tells the
+ underlying filesystems to use the current time. */
+ atime->microseconds = mtime->microseconds = -1;
+ else
+ {
+ atime->seconds = tvp[0].tv_sec;
+ atime->microseconds = tvp[0].tv_usec;
+ mtime->seconds = tvp[1].tv_sec;
+ mtime->microseconds = tvp[1].tv_usec;
+ }
+}
+
+/* Changes the access time of the file behind PORT using a timeval array. */
+static inline error_t
+hurd_futimens (const file_t port, const struct timeval tvp[2])
+{
+ error_t err;
+ struct timespec atime, mtime;
+
+ utime_ts_from_tval (tvp, &atime, &mtime);
+
+ err = __file_utimens (port, atime, mtime);
+
+ if (err == MIG_BAD_ID || err == EOPNOTSUPP)
+ {
+ time_value_t atim, mtim;
+
+ utime_tvalue_from_tval (tvp, &atim, &mtim);
+
+ err = __file_utimes (port, atim, mtim);
+ }
+
+ return err;
+}
@@ -20,33 +20,22 @@
#include <stddef.h>
#include <hurd.h>
+#include "utime-helper.c"
+
/* Change the access time of FILE to TVP[0] and
the modification time of FILE to TVP[1]. */
int
__utimes (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];
error_t err;
file_t port;
- if (tvp == NULL)
- {
- /* Setting the number of microseconds to `-1' tells the
- underlying filesystems to use the current time. */
- nulltv[0].tvt.microseconds = nulltv[1].tvt.microseconds = -1;
- u = nulltv;
- }
-
port = __file_name_lookup (file, 0, 0);
if (port == MACH_PORT_NULL)
return -1;
- err = __file_utimes (port, u[0].tvt, u[1].tvt);
+
+ err = hurd_futimens (port, tvp);
+
__mach_port_deallocate (__mach_task_self (), port);
if (err)
return __hurd_fail (err);