* sysdeps/unix/sysv/linux/powerpc/bits/stat.h: Define UTIME_NOW and

UTIME_OMIT.
	* sysdeps/unix/sysv/linux/x86_64/bits/stat.h: Likewise.
	* sysdeps/unix/sysv/linux/sparc/bits/stat.h: Likewise.
	* sysdeps/unix/sysv/linux/alpha/bits/stat.h: Likewise.
	* sysdeps/unix/sysv/linux/ia64/bits/stat.h: Likewise.
	* sysdeps/unix/sysv/linux/bits/stat.h: Likewise.
	* sysdeps/unix/sysv/linux/s390/bits/stat.h: Likewise.
	* sysdeps/unix/sysv/linux/kernel-features.h: Define __ASSUME_UTIMENSAT.
	* io/sys/stat.h: Declare utimensat, futimens.
	* io/utimensat.c: New file.
	* io/futimens.c: New file.
	* sysdeps/unix/sysv/linux/utimensat.c: New file.
	* sysdeps/unix/sysv/linux/futimens.c: New file.
	* io/Makefile (routines): Add utimensat, futimens.
	* io/Versions: Add utimensat, futimens to GLIBC_2.6.
	* sysdeps/unix/sysv/linux/lutimes.c: New file.
	* sysdeps/unix/sysv/linux/futimes.c: Use utimensat syscall if
	available.

	* include/sys/cdefs.h: Redefine __nonnull so that test for
	incorrect parameters in the libc code itself are not omitted.
This commit is contained in:
Ulrich Drepper 2007-05-10 21:44:41 +00:00
parent 00afb11fc0
commit c27d207813
18 changed files with 367 additions and 15 deletions

View File

@ -1,3 +1,28 @@
2007-05-10 Ulrich Drepper <drepper@redhat.com>
* sysdeps/unix/sysv/linux/powerpc/bits/stat.h: Define UTIME_NOW and
UTIME_OMIT.
* sysdeps/unix/sysv/linux/x86_64/bits/stat.h: Likewise.
* sysdeps/unix/sysv/linux/sparc/bits/stat.h: Likewise.
* sysdeps/unix/sysv/linux/alpha/bits/stat.h: Likewise.
* sysdeps/unix/sysv/linux/ia64/bits/stat.h: Likewise.
* sysdeps/unix/sysv/linux/bits/stat.h: Likewise.
* sysdeps/unix/sysv/linux/s390/bits/stat.h: Likewise.
* sysdeps/unix/sysv/linux/kernel-features.h: Define __ASSUME_UTIMENSAT.
* io/sys/stat.h: Declare utimensat, futimens.
* io/utimensat.c: New file.
* io/futimens.c: New file.
* sysdeps/unix/sysv/linux/utimensat.c: New file.
* sysdeps/unix/sysv/linux/futimens.c: New file.
* io/Makefile (routines): Add utimensat, futimens.
* io/Versions: Add utimensat, futimens to GLIBC_2.6.
* sysdeps/unix/sysv/linux/lutimes.c: New file.
* sysdeps/unix/sysv/linux/futimes.c: Use utimensat syscall if
available.
* include/sys/cdefs.h: Redefine __nonnull so that test for
incorrect parameters in the libc code itself are not omitted.
2007-05-09 Jakub Jelinek <jakub@redhat.com> 2007-05-09 Jakub Jelinek <jakub@redhat.com>
* sysdeps/ia64/fpu/fraiseexcpt.c (feraiseexcept): Don't raise overflow * sysdeps/ia64/fpu/fraiseexcpt.c (feraiseexcept): Don't raise overflow

View File

@ -51,7 +51,8 @@ routines := \
ftw ftw64 fts poll ppoll \ ftw ftw64 fts poll ppoll \
posix_fadvise posix_fadvise64 \ posix_fadvise posix_fadvise64 \
posix_fallocate posix_fallocate64 \ posix_fallocate posix_fallocate64 \
sendfile sendfile64 sendfile sendfile64 \
utimensat futimens
# These routines will be omitted from the libc shared object. # These routines will be omitted from the libc shared object.
# Instead the static object files will be included in a special archive # Instead the static object files will be included in a special archive

View File

@ -113,4 +113,7 @@ libc {
ppoll; ppoll;
} }
GLIBC_2.6 {
utimensat; futimens;
}
} }

36
io/futimens.c Normal file
View File

@ -0,0 +1,36 @@
/* Change access and modification times of open file. Linux version.
Copyright (C) 2007 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, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <time.h>
#include <sysdep.h>
/* Change the access time of the file associated with FD to TSP[0] and
the modification time of FILE to TSP[1]. */
int
futimens (int fd, const struct timespec tsp[2])
{
__set_errno (ENOSYS);
return -1;
}
stub_warning (futimens)
#include <stub-tag.h>

View File

@ -28,7 +28,7 @@
#include <bits/types.h> /* For __mode_t and __dev_t. */ #include <bits/types.h> /* For __mode_t and __dev_t. */
#if defined __USE_XOPEN || defined __USE_MISC #if defined __USE_XOPEN || defined __USE_XOPEN2K || defined __USE_MISC
# if defined __USE_XOPEN || defined __USE_XOPEN2K # if defined __USE_XOPEN || defined __USE_XOPEN2K
# define __need_time_t # define __need_time_t
# endif # endif
@ -354,6 +354,21 @@ extern int mkfifoat (int __fd, __const char *__path, __mode_t __mode)
__THROW __nonnull ((2)); __THROW __nonnull ((2));
#endif #endif
#ifdef __USE_ATFILE
/* Set file access and modification times relative to directory file
descriptor. */
extern int utimensat (int __fd, __const char *__path,
__const struct timespec __times[2],
int __flags)
__THROW __nonnull ((2));
#endif
#ifdef __USE_GNU
/* XXX This will change to the macro for the next 2008 POSIX revision. */
/* Set file access and modification times of the file associated with FD. */
extern int futimens (int __fd, __const struct timespec __times[2]) __THROW;
#endif
/* To allow the `struct stat' structure and the file type `mode_t' /* To allow the `struct stat' structure and the file type `mode_t'
bits to vary without changing shared library major version number, bits to vary without changing shared library major version number,
the `stat' family of functions and `mknod' are in fact inline the `stat' family of functions and `mknod' are in fact inline

34
io/utimensat.c Normal file
View File

@ -0,0 +1,34 @@
/* Change access and modification times of open file. Stub version.
Copyright (C) 2007 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, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <errno.h>
#include <sys/stat.h>
/* Change the access time of FILE to TSP[0] and
the modification time of FILE to TSP[1]. */
int
utimensat (int fd, const char *file, const struct timespec tsp[2],
int flags)
{
__set_errno (ENOSYS);
return -1;
}
stub_warning (utimensat)
#include <stub-tag.h>

View File

@ -149,3 +149,9 @@ struct stat64
#define __S_IREAD 0400 /* Read by owner. */ #define __S_IREAD 0400 /* Read by owner. */
#define __S_IWRITE 0200 /* Write by owner. */ #define __S_IWRITE 0200 /* Write by owner. */
#define __S_IEXEC 0100 /* Execute by owner. */ #define __S_IEXEC 0100 /* Execute by owner. */
#if defined __USE_ATFILE || defined __USE_GNU
/* XXX This will change to the macro for the next 2008 POSIX revision. */
# define UTIME_NOW ((1l << 30) - 1l)
# define UTIME_OMIT ((1l << 30) - 2l)
#endif

View File

@ -161,3 +161,9 @@ struct stat64
#define __S_IREAD 0400 /* Read by owner. */ #define __S_IREAD 0400 /* Read by owner. */
#define __S_IWRITE 0200 /* Write by owner. */ #define __S_IWRITE 0200 /* Write by owner. */
#define __S_IEXEC 0100 /* Execute by owner. */ #define __S_IEXEC 0100 /* Execute by owner. */
#if defined __USE_ATFILE || defined __USE_GNU
/* XXX This will change to the macro for the next 2008 POSIX revision. */
# define UTIME_NOW ((1l << 30) - 1l)
# define UTIME_OMIT ((1l << 30) - 2l)
#endif

View File

@ -0,0 +1,45 @@
/* Change access and modification times of open file. Linux version.
Copyright (C) 2007 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, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <time.h>
#include <sysdep.h>
/* Change the access time of the file associated with FD to TSP[0] and
the modification time of FILE to TSP[1].
Starting with 2.6.22 the Linux kernel has the utimensat syscall which
can be used to implement futimens. */
int
futimens (int fd, const struct timespec tsp[2])
{
#ifdef __NR_utimensat
return INLINE_SYSCALL (utimensat, 4, fd, NULL, tsp, 0);
#else
__set_errno (ENOSYS);
return -1;
#endif
}
#ifndef __NR_utimensat
stub_warning (futimens)
# include <stub-tag.h>
#endif

View File

@ -20,6 +20,7 @@
#include <errno.h> #include <errno.h>
#include <sysdep.h> #include <sysdep.h>
#include <string.h> #include <string.h>
#include <time.h>
#include <utime.h> #include <utime.h>
#include <sys/time.h> #include <sys/time.h>
#include <stdio-common/_itoa.h> #include <stdio-common/_itoa.h>
@ -27,32 +28,67 @@
#include <kernel-features.h> #include <kernel-features.h>
/* Change the access time of FILE to TVP[0] and
the modification time of FILE to TVP[1], but do not follow symlinks.
The Linux kernel has no futimes() syscall so we use the /proc #ifndef __ASSUME_UTIMENSAT
filesystem. */ static int miss_utimensat;
#endif
/* Change the access time of the file associated with FD to TVP[0] and
the modification time of FILE to TVP[1].
Starting with 2.6.22 the Linux kernel has the utimensat syscall which
can be used to implement futimes. Earlier kernels have no futimes()
syscall so we use the /proc filesystem. */
int int
__futimes (int fd, const struct timeval tvp[2]) __futimes (int fd, const struct timeval tvp[2])
{ {
/* The utimensat system call expects timespec not timeval. */
struct timespec ts[2];
if (tvp != NULL)
{
if (tvp[0].tv_usec < 0 || tvp[0].tv_usec >= 1000000
|| tvp[1].tv_usec < 0 || tvp[1].tv_usec >= 1000000)
{
__set_errno (EINVAL);
return -1;
}
TIMEVAL_TO_TIMESPEC (&tvp[0], &ts[0]);
TIMEVAL_TO_TIMESPEC (&tvp[1], &ts[1]);
}
#ifdef __ASSUME_UTIMENSAT
return INLINE_SYSCALL (utimensat, 4, fd, NULL, tvp ? &ts : NULL, 0);
#else
int result;
# ifdef __NR_utimensat
if (!__builtin_expect (miss_utimensat, 0))
{
result = INLINE_SYSCALL (utimensat, 4, fd, NULL, tvp ? &ts : NULL, 0);
if (__builtin_expect (result, 0) != -1 || errno != ENOSYS)
return result;
miss_utimensat = 1;
}
# endif
static const char selffd[] = "/proc/self/fd/"; static const char selffd[] = "/proc/self/fd/";
char fname[sizeof (selffd) + 3 * sizeof (int)]; char fname[sizeof (selffd) + 3 * sizeof (int)];
fname[sizeof (fname) - 1] = '\0'; fname[sizeof (fname) - 1] = '\0';
char *cp = _itoa_word ((unsigned int) fd, fname + sizeof (fname) - 1, 10, 0); char *cp = _itoa_word ((unsigned int) fd, fname + sizeof (fname) - 1, 10, 0);
cp = memcpy (cp - sizeof (selffd) + 1, selffd, sizeof (selffd) - 1); cp = memcpy (cp - sizeof (selffd) + 1, selffd, sizeof (selffd) - 1);
int result; # ifdef __NR_utimes
#ifdef __NR_utimes
result = INLINE_SYSCALL (utimes, 2, cp, tvp); result = INLINE_SYSCALL (utimes, 2, cp, tvp);
# ifndef __ASSUME_UTIMES # ifndef __ASSUME_UTIMES
if (result == -1 && errno == ENOSYS) if (result == -1 && errno == ENOSYS)
# endif # endif
#endif # endif
{ {
/* The utimes() syscall does not exist or is not available in the /* The utimes() syscall does not exist or is not available in the
used kernel. Use utime(). For this we have to convert to the used kernel. Use utime(). For this we have to convert to the
data format utime() expects. */ data format utime() expects. */
#ifndef __ASSUME_UTIMES # ifndef __ASSUME_UTIMES
struct utimbuf buf; struct utimbuf buf;
struct utimbuf *times; struct utimbuf *times;
@ -66,7 +102,7 @@ __futimes (int fd, const struct timeval tvp[2])
times = NULL; times = NULL;
result = INLINE_SYSCALL (utime, 2, cp, times); result = INLINE_SYSCALL (utime, 2, cp, times);
#endif # endif
} }
if (result == -1) if (result == -1)
@ -88,14 +124,15 @@ __futimes (int fd, const struct timeval tvp[2])
case ENOENT: case ENOENT:
/* Validate the file descriptor by letting fcntl set errno to /* Validate the file descriptor by letting fcntl set errno to
EBADF if it's bogus. Otherwise it's a /proc issue. */ EBADF if it's bogus. Otherwise it's a /proc issue. */
#if !defined __NR_fcntl && defined __NR_fcntl64 # if !defined __NR_fcntl && defined __NR_fcntl64
# define __NR_fcntl __NR_fcntl64 # define __NR_fcntl __NR_fcntl64
#endif # endif
if (INLINE_SYSCALL (fcntl, 3, fd, F_GETFD, 0) != -1) if (INLINE_SYSCALL (fcntl, 3, fd, F_GETFD, 0) != -1)
__set_errno (ENOSYS); __set_errno (ENOSYS);
break; break;
} }
return result; return result;
#endif
} }
weak_alias (__futimes, futimes) weak_alias (__futimes, futimes)

View File

@ -138,3 +138,9 @@ struct stat64
#define __S_IREAD 0400 /* Read by owner. */ #define __S_IREAD 0400 /* Read by owner. */
#define __S_IWRITE 0200 /* Write by owner. */ #define __S_IWRITE 0200 /* Write by owner. */
#define __S_IEXEC 0100 /* Execute by owner. */ #define __S_IEXEC 0100 /* Execute by owner. */
#if defined __USE_ATFILE || defined __USE_GNU
/* XXX This will change to the macro for the next 2008 POSIX revision. */
# define UTIME_NOW ((1l << 30) - 1l)
# define UTIME_OMIT ((1l << 30) - 2l)
#endif

View File

@ -458,3 +458,8 @@
#if __LINUX_KERNEL_VERSION >= 0x020612 #if __LINUX_KERNEL_VERSION >= 0x020612
# define __ASSUME_FUTEX_LOCK_PI 1 # define __ASSUME_FUTEX_LOCK_PI 1
#endif #endif
/* Support for utimensat syscall was added in 2.6.22. */
#if __LINUX_KERNEL_VERSION >= 0x020616
# define __ASSUME_UTIMENSAT 1
#endif

View File

@ -0,0 +1,59 @@
/* Change access and/or modification date of file. Do not follow symbolic
links.
Copyright (C) 2007 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, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <errno.h>
#include <fcntl.h>
#include <time.h>
#include <sys/time.h>
#include <sysdep.h>
#include <kernel-features.h>
int
lutimes (const char *file, const struct timeval tvp[2])
{
#ifdef __NR_utimensat
/* The system call espects timespec, not timeval. */
struct timespec ts[2];
if (tvp != NULL)
{
if (tvp[0].tv_usec < 0 || tvp[0].tv_usec >= 1000000
|| tvp[1].tv_usec < 0 || tvp[1].tv_usec >= 1000000)
{
__set_errno (EINVAL);
return -1;
}
TIMEVAL_TO_TIMESPEC (&tvp[0], &ts[0]);
TIMEVAL_TO_TIMESPEC (&tvp[1], &ts[1]);
}
return INLINE_SYSCALL (utimensat, 4, AT_FDCWD, file, tvp ? ts : NULL,
AT_SYMLINK_NOFOLLOW);
#else
__set_errno (ENOSYS);
return -1;
#endif
}
#ifndef __NR_utimensat
stub_warning (lutimes)
# include <stub-tag.h>
#endif

View File

@ -265,3 +265,9 @@ struct stat64
#define __S_IREAD 0400 /* Read by owner. */ #define __S_IREAD 0400 /* Read by owner. */
#define __S_IWRITE 0200 /* Write by owner. */ #define __S_IWRITE 0200 /* Write by owner. */
#define __S_IEXEC 0100 /* Execute by owner. */ #define __S_IEXEC 0100 /* Execute by owner. */
#if defined __USE_ATFILE || defined __USE_GNU
/* XXX This will change to the macro for the next 2008 POSIX revision. */
# define UTIME_NOW ((1l << 30) - 1l)
# define UTIME_OMIT ((1l << 30) - 2l)
#endif

View File

@ -254,3 +254,9 @@ struct stat64
#define __S_IREAD 0400 /* Read by owner. */ #define __S_IREAD 0400 /* Read by owner. */
#define __S_IWRITE 0200 /* Write by owner. */ #define __S_IWRITE 0200 /* Write by owner. */
#define __S_IEXEC 0100 /* Execute by owner. */ #define __S_IEXEC 0100 /* Execute by owner. */
#if defined __USE_ATFILE || defined __USE_GNU
/* XXX This will change to the macro for the next 2008 POSIX revision. */
# define UTIME_NOW ((1l << 30) - 1l)
# define UTIME_OMIT ((1l << 30) - 2l)
#endif

View File

@ -163,3 +163,9 @@ struct stat64
#define __S_IREAD 0400 /* Read by owner. */ #define __S_IREAD 0400 /* Read by owner. */
#define __S_IWRITE 0200 /* Write by owner. */ #define __S_IWRITE 0200 /* Write by owner. */
#define __S_IEXEC 0100 /* Execute by owner. */ #define __S_IEXEC 0100 /* Execute by owner. */
#if defined __USE_ATFILE || defined __USE_GNU
/* XXX This will change to the macro for the next 2008 POSIX revision. */
# define UTIME_NOW ((1l << 30) - 1l)
# define UTIME_OMIT ((1l << 30) - 2l)
#endif

View File

@ -0,0 +1,50 @@
/* Change access and modification times of open file. Linux version.
Copyright (C) 2007 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, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <errno.h>
#include <sys/stat.h>
#include <sysdep.h>
#include <kernel-features.h>
/* Change the access time of FILE to TSP[0] and
the modification time of FILE to TSP[1].
Starting with 2.6.22 the Linux kernel has the utimensat syscall. */
int
utimensat (int fd, const char *file, const struct timespec tsp[2],
int flags)
{
if (file == NULL)
{
__set_errno (EINVAL);
return -1;
}
#ifdef __NR_utimensat
return INLINE_SYSCALL (utimensat, 4, fd, file, tsp, flags);
#else
__set_errno (ENOSYS);
return -1;
#endif
}
#ifndef __NR_utimensat
stub_warning (utimensat)
# include <stub-tag.h>
#endif

View File

@ -201,3 +201,9 @@ struct stat64
#define __S_IREAD 0400 /* Read by owner. */ #define __S_IREAD 0400 /* Read by owner. */
#define __S_IWRITE 0200 /* Write by owner. */ #define __S_IWRITE 0200 /* Write by owner. */
#define __S_IEXEC 0100 /* Execute by owner. */ #define __S_IEXEC 0100 /* Execute by owner. */
#if defined __USE_ATFILE || defined __USE_GNU
/* XXX This will change to the macro for the next 2008 POSIX revision. */
# define UTIME_NOW ((1l << 30) - 1l)
# define UTIME_OMIT ((1l << 30) - 2l)
#endif