This is the mail archive of the libc-hacker@sourceware.org mailing list for the glibc project.

Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix futimesat with NULL second argument


Hi!

According to http://docs.sun.com/app/docs/doc/816-5167/6mbb2jam2?a=view
futimesat (fd, NULL, tvp)
is supposed to set times on the file referenced by fd.

touch from coreutils uses this, so with current CVS glibc crashes
(see https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=173581).

It is unclear what happens with
futimesat (AT_FDCWD, NULL, tvp)
though, my patch will just fail, other variant would be set times on
current working directory.

Also, in generic futimesat.c, the documentation above says that
for absolute paths fd argument is ignored.  Therefore we shouldn't
IMHO verify that FD is non-negative or AT_FDCWD in that case.

2005-11-18  Jakub Jelinek  <jakub@redhat.com>

	* sysdeps/unix/sysv/linux/futimesat.c (futimesat): If FILE is NULL,
	set access and modification times of the file referenced by FD.
	* sysdeps/generic/futimesat.c (futimesat): Don't return EINVAL if
	FILE is NULL.  Don't check FD if FILE is absolute path.

--- libc/sysdeps/unix/sysv/linux/futimesat.c.jj	2005-11-18 20:48:37.000000000 +0100
+++ libc/sysdeps/unix/sysv/linux/futimesat.c	2005-11-18 21:59:12.000000000 +0100
@@ -37,7 +37,22 @@ futimesat (fd, file, tvp)
 {
   char *buf = NULL;
 
-  if (fd != AT_FDCWD && file[0] != '/')
+  if (file == NULL)
+    {
+      static const char procfd[] = "/proc/self/fd/%d";
+      /* Buffer for the path name we are going to use.  It consists of
+	 - the string /proc/self/fd/
+	 - the file descriptor number.
+	 The final NUL is included in the sizeof.   A bit of overhead
+	 due to the format elements compensates for possible negative
+	 numbers.  */
+      size_t buflen = sizeof (procfd) + sizeof (int) * 3;
+      buf = alloca (buflen);
+
+      __snprintf (buf, buflen, procfd, fd);
+      file = buf;
+    }
+  else if (fd != AT_FDCWD && file[0] != '/')
     {
       size_t filelen = strlen (file);
       static const char procfd[] = "/proc/self/fd/%d/%s";
--- libc/sysdeps/generic/futimesat.c.jj	2005-11-11 20:02:44.000000000 +0100
+++ libc/sysdeps/generic/futimesat.c	2005-11-18 21:54:36.000000000 +0100
@@ -30,18 +30,14 @@ futimesat (fd, file, tvp)
      const char *file;
      const struct timeval tvp[2];
 {
-  if (fd < 0 && fd != AT_FDCWD)
+  if (fd < 0
+      && (file == NULL
+          || (fd != AT_FDCWD && file[0] != '/')))
     {
       __set_errno (EBADF);
       return -1;
     }
 
-  if (file == NULL)
-    {
-      __set_errno (EINVAL);
-      return -1;
-    }
-
   __set_errno (ENOSYS);
   return -1;
 }

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]