Patchwork [hurd,commited,1/2] hurd: Define and pass UTIME_NOW and UTIME_OMIT to new file_utimens RPC

login
register
mail settings
Submitter Samuel Thibault
Date March 6, 2018, 7:45 a.m.
Message ID <20180306074519.6980-2-samuel.thibault@ens-lyon.org>
Download mbox | patch
Permalink /patch/26205/
State Committed, archived
Headers show

Comments

Samuel Thibault - March 6, 2018, 7:45 a.m.
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
Ben Hutchings - March 6, 2018, 7:56 p.m.
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.
Samuel Thibault - March 7, 2018, 9:09 a.m.
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

Patch

diff --git a/ChangeLog b/ChangeLog
index f586c3f55e..989881e972 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.
diff --git a/sysdeps/mach/hurd/bits/stat.h b/sysdeps/mach/hurd/bits/stat.h
index 7296cd2dcc..e354a05237 100644
--- a/sysdeps/mach/hurd/bits/stat.h
+++ b/sysdeps/mach/hurd/bits/stat.h
@@ -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.  */
diff --git a/sysdeps/mach/hurd/futimens.c b/sysdeps/mach/hurd/futimens.c
index 44ba7f15f1..4a8b0f7fa4 100644
--- 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])
 {
-  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)
diff --git a/sysdeps/mach/hurd/futimes.c b/sysdeps/mach/hurd/futimes.c
index cc2a68f641..1b521e3e51 100644
--- a/sysdeps/mach/hurd/futimes.c
+++ b/sysdeps/mach/hurd/futimes.c
@@ -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)
diff --git a/sysdeps/mach/hurd/lutimes.c b/sysdeps/mach/hurd/lutimes.c
index e6b0f04172..23b00c1739 100644
--- a/sysdeps/mach/hurd/lutimes.c
+++ b/sysdeps/mach/hurd/lutimes.c
@@ -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);
diff --git a/sysdeps/mach/hurd/utime-helper.c b/sysdeps/mach/hurd/utime-helper.c
new file mode 100644
index 0000000000..357dfe9705
--- /dev/null
+++ b/sysdeps/mach/hurd/utime-helper.c
@@ -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;
+}
diff --git a/sysdeps/mach/hurd/utimes.c b/sysdeps/mach/hurd/utimes.c
index 2f7c8c228d..25e47539fe 100644
--- a/sysdeps/mach/hurd/utimes.c
+++ b/sysdeps/mach/hurd/utimes.c
@@ -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);