Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2008-04-24 13:59:54 +0400
committerCorinna Vinschen <corinna@vinschen.de>2008-04-24 13:59:54 +0400
commiteba32ec829904a40f34808374a1c53415ef7bc0b (patch)
tree9b345ab8c40ce458d77f73de9a693177a89ccbfa
parent0d02384a4892d1419ca12125beaf155d2af7d720 (diff)
* cygwin.din (futimens): Export.
(utimensat): Export. * fhandler.cc (fhandler_base::utimens): Replace fhandler_base::utimes. Call utimens_fs. * fhandler.h (class fhandler_base): Declare utimens_fs instead of utimes_fs, utimens instead of utimes. (class fhandler_disk_file): Declare utimens instead of utimes. * fhandler_disk_file.cc (fhandler_disk_file::utimens): Replace fhandler_disk_file::utimes. (fhandler_base::utimens_fs): Replace fhandler_base::utimes_fs. Implement tv_nsec handling according to SUSv4. * syscalls.cc (utimensat): New function. * times.cc (timespec_to_filetime): New function. (timeval_to_timespec): New function. (utimens_worker): Replace utimes_worker. (utimes): Convert timeval to timespec and call utimens_worker. (lutimes): Ditto. (futimens): Take over implementation from futimes. (futimes): Convert timeval to timespec and call futimens. * winsup.h (timespec_to_filetime): Declare. * include/cygwin/version.h: Bump API minor number. * posix.sgml: Add SUSv4 section. Add futimens and utimensat to it.
-rw-r--r--winsup/cygwin/ChangeLog25
-rw-r--r--winsup/cygwin/cygwin.din2
-rw-r--r--winsup/cygwin/fhandler.cc4
-rw-r--r--winsup/cygwin/fhandler.h6
-rw-r--r--winsup/cygwin/fhandler_disk_file.cc31
-rw-r--r--winsup/cygwin/include/cygwin/version.h3
-rw-r--r--winsup/cygwin/posix.sgml9
-rw-r--r--winsup/cygwin/syscalls.cc19
-rw-r--r--winsup/cygwin/times.cc69
-rw-r--r--winsup/cygwin/winsup.h1
10 files changed, 143 insertions, 26 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 2c8a4f4de..bee003c5b 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,28 @@
+2008-04-24 Corinna Vinschen <corinna@vinschen.de>
+
+ * cygwin.din (futimens): Export.
+ (utimensat): Export.
+ * fhandler.cc (fhandler_base::utimens): Replace fhandler_base::utimes.
+ Call utimens_fs.
+ * fhandler.h (class fhandler_base): Declare utimens_fs instead of
+ utimes_fs, utimens instead of utimes.
+ (class fhandler_disk_file): Declare utimens instead of utimes.
+ * fhandler_disk_file.cc (fhandler_disk_file::utimens): Replace
+ fhandler_disk_file::utimes.
+ (fhandler_base::utimens_fs): Replace fhandler_base::utimes_fs.
+ Implement tv_nsec handling according to SUSv4.
+ * syscalls.cc (utimensat): New function.
+ * times.cc (timespec_to_filetime): New function.
+ (timeval_to_timespec): New function.
+ (utimens_worker): Replace utimes_worker.
+ (utimes): Convert timeval to timespec and call utimens_worker.
+ (lutimes): Ditto.
+ (futimens): Take over implementation from futimes.
+ (futimes): Convert timeval to timespec and call futimens.
+ * winsup.h (timespec_to_filetime): Declare.
+ * include/cygwin/version.h: Bump API minor number.
+ * posix.sgml: Add SUSv4 section. Add futimens and utimensat to it.
+
2008-04-24 Yaakov (Cygwin Ports) <yselkowitz@users.sourceforge.net>
* include/wait.h: New file.
diff --git a/winsup/cygwin/cygwin.din b/winsup/cygwin/cygwin.din
index 3b1aaf1d4..e418f4033 100644
--- a/winsup/cygwin/cygwin.din
+++ b/winsup/cygwin/cygwin.din
@@ -564,6 +564,7 @@ fts_set_clientptr NOSIGFE
ftw SIGFE
funlockfile SIGFE
funopen SIGFE
+futimens SIGFE
futimes SIGFE
futimesat SIGFE
fwrite SIGFE
@@ -1656,6 +1657,7 @@ usleep SIGFE
_usleep = usleep SIGFE
utime SIGFE
_utime = utime SIGFE
+utimensat SIGFE
utimes SIGFE
_utimes = utimes SIGFE
utmpname SIGFE
diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc
index b46756dd0..75711260b 100644
--- a/winsup/cygwin/fhandler.cc
+++ b/winsup/cygwin/fhandler.cc
@@ -1516,10 +1516,10 @@ fhandler_base::link (const char *newpath)
}
int
-fhandler_base::utimes (const struct timeval *tvp)
+fhandler_base::utimens (const struct timespec *tvp)
{
if (is_fs_special ())
- return utimes_fs (tvp);
+ return utimens_fs (tvp);
set_errno (EINVAL);
return -1;
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 856f68321..259a0f450 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -286,7 +286,7 @@ class fhandler_base
int __stdcall fstat_by_handle (struct __stat64 *buf) __attribute__ ((regparm (2)));
int __stdcall fstat_by_name (struct __stat64 *buf) __attribute__ ((regparm (2)));
virtual int __stdcall fstatvfs (struct statvfs *buf) __attribute__ ((regparm (2)));
- int utimes_fs (const struct timeval *) __attribute__ ((regparm (2)));
+ int utimens_fs (const struct timespec *) __attribute__ ((regparm (2)));
virtual int __stdcall fchmod (mode_t mode) __attribute__ ((regparm (1)));
virtual int __stdcall fchown (__uid32_t uid, __gid32_t gid) __attribute__ ((regparm (2)));
virtual int __stdcall facl (int, int, __acl32 *) __attribute__ ((regparm (3)));
@@ -295,7 +295,7 @@ class fhandler_base
virtual int __stdcall fadvise (_off64_t, _off64_t, int) __attribute__ ((regparm (3)));
virtual int __stdcall ftruncate (_off64_t, bool) __attribute__ ((regparm (3)));
virtual int __stdcall link (const char *) __attribute__ ((regparm (2)));
- virtual int __stdcall utimes (const struct timeval *) __attribute__ ((regparm (2)));
+ virtual int __stdcall utimens (const struct timespec *) __attribute__ ((regparm (2)));
virtual int __stdcall fsync () __attribute__ ((regparm (1)));
virtual int ioctl (unsigned int cmd, void *);
virtual int fcntl (int cmd, void *);
@@ -695,7 +695,7 @@ class fhandler_disk_file: public fhandler_base
int __stdcall fadvise (_off64_t, _off64_t, int) __attribute__ ((regparm (3)));
int __stdcall ftruncate (_off64_t, bool) __attribute__ ((regparm (3)));
int __stdcall link (const char *) __attribute__ ((regparm (2)));
- int __stdcall utimes (const struct timeval *) __attribute__ ((regparm (2)));
+ int __stdcall utimens (const struct timespec *) __attribute__ ((regparm (2)));
int __stdcall fstatvfs (struct statvfs *buf) __attribute__ ((regparm (2)));
HANDLE mmap (caddr_t *addr, size_t len, int prot, int flags, _off64_t off);
diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc
index 4f81bf764..dabee7beb 100644
--- a/winsup/cygwin/fhandler_disk_file.cc
+++ b/winsup/cygwin/fhandler_disk_file.cc
@@ -1149,16 +1149,17 @@ fhandler_disk_file::link (const char *newpath)
}
int
-fhandler_disk_file::utimes (const struct timeval *tvp)
+fhandler_disk_file::utimens (const struct timespec *tvp)
{
- return utimes_fs (tvp);
+ return utimens_fs (tvp);
}
int
-fhandler_base::utimes_fs (const struct timeval *tvp)
+fhandler_base::utimens_fs (const struct timespec *tvp)
{
LARGE_INTEGER lastaccess, lastwrite;
- struct timeval tmp[2];
+ struct timespec timeofday;
+ struct timespec tmp[2];
bool closeit = false;
if (!get_handle ())
@@ -1180,15 +1181,25 @@ fhandler_base::utimes_fs (const struct timeval *tvp)
closeit = true;
}
- gettimeofday (&tmp[0], 0);
+ gettimeofday (reinterpret_cast<struct timeval *> (&timeofday), 0);
+ timeofday.tv_nsec *= 1000;
if (!tvp)
+ tmp[1] = tmp[0] = timeofday;
+ else
{
- tmp[1] = tmp[0];
- tvp = tmp;
+ if ((tmp[0].tv_nsec < UTIME_NOW || tmp[0].tv_nsec > 999999999L)
+ || (tmp[1].tv_nsec < UTIME_NOW || tmp[1].tv_nsec > 999999999L))
+ {
+ set_errno (EINVAL);
+ return -1;
+ }
+ tmp[0] = (tvp[0].tv_nsec == UTIME_NOW) ? timeofday : tvp[0];
+ tmp[1] = (tvp[1].tv_nsec == UTIME_NOW) ? timeofday : tvp[1];
}
- timeval_to_filetime (&tvp[0], (FILETIME *) &lastaccess);
- timeval_to_filetime (&tvp[1], (FILETIME *) &lastwrite);
- debug_printf ("incoming lastaccess %08x %08x", tvp[0].tv_sec, tvp[0].tv_usec);
+ /* UTIME_OMIT is handled in timespec_to_filetime by setting FILETIME to 0. */
+ timespec_to_filetime (&tmp[0], (FILETIME *) &lastaccess);
+ timespec_to_filetime (&tmp[1], (FILETIME *) &lastwrite);
+ debug_printf ("incoming lastaccess %08x %08x", tmp[0].tv_sec, tmp[0].tv_nsec);
IO_STATUS_BLOCK io;
FILE_BASIC_INFORMATION fbi;
diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h
index 007032a59..668c0636e 100644
--- a/winsup/cygwin/include/cygwin/version.h
+++ b/winsup/cygwin/include/cygwin/version.h
@@ -331,12 +331,13 @@ details. */
184: Export openat, faccessat, fchmodat, fchownat, fstatat, futimesat,
linkat, mkdirat, mkfifoat, mknodat, readlinkat, renameat, symlinkat,
unlinkat.
+ 185: Export futimens, utimensat.
*/
/* Note that we forgot to bump the api for ualarm, strtoll, strtoull */
#define CYGWIN_VERSION_API_MAJOR 0
-#define CYGWIN_VERSION_API_MINOR 184
+#define CYGWIN_VERSION_API_MINOR 185
/* There is also a compatibity version number associated with the
shared memory regions. It is incremented when incompatible
diff --git a/winsup/cygwin/posix.sgml b/winsup/cygwin/posix.sgml
index ca5f5581e..ca9e0cf3e 100644
--- a/winsup/cygwin/posix.sgml
+++ b/winsup/cygwin/posix.sgml
@@ -1042,6 +1042,15 @@ also ISO/IEC 9945:2003 and IEEE Std 1003.1-2001 (POSIX.1-2001).</para>
</sect1>
+<sect1 id="std-susv4"><title>System interfaces compatible with the Draft Single Unix Specification, Version 4:</title>
+
+<screen>
+ futimens
+ utimensat
+</screen>
+
+</sect1>
+
<sect1 id="std-deprec"><title>Other UNIX system interfaces, deprecated or not in POSIX.1-2001:</title>
<screen>
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index 1a2572186..7da929efa 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -3631,6 +3631,25 @@ fstatat (int dirfd, const char *pathname, struct __stat64 *st, int flags)
return (flags & AT_SYMLINK_NOFOLLOW) ? lstat64 (path, st) : stat64 (path, st);
}
+extern int utimens_worker (path_conv &, const struct timespec *);
+
+extern "C" int
+utimensat (int dirfd, const char *pathname, const struct timespec *times,
+ int flags)
+{
+ myfault efault;
+ if (efault.faulted (EFAULT))
+ return -1;
+ tmp_pathbuf tp;
+ char *path = tp.c_get ();
+ if (gen_full_path_at (path, dirfd, pathname))
+ return -1;
+ path_conv win32 (path, PC_POSIX | ((flags & AT_SYMLINK_NOFOLLOW)
+ ? PC_SYM_NOFOLLOW : PC_SYM_FOLLOW),
+ stat_suffixes);
+ return utimens_worker (win32, times);
+}
+
extern "C" int
futimesat (int dirfd, const char *pathname, const struct timeval *times)
{
diff --git a/winsup/cygwin/times.cc b/winsup/cygwin/times.cc
index 1417dc9c7..ee63a2e3a 100644
--- a/winsup/cygwin/times.cc
+++ b/winsup/cygwin/times.cc
@@ -184,6 +184,21 @@ time_t_to_filetime (time_t time_in, FILETIME *out)
/* Cygwin internal */
void __stdcall
+timespec_to_filetime (const struct timespec *time_in, FILETIME *out)
+{
+ if (time_in->tv_nsec == UTIME_OMIT)
+ out->dwHighDateTime = out->dwLowDateTime = 0;
+ else
+ {
+ long long x = time_in->tv_sec * NSPERSEC +
+ time_in->tv_nsec / (NSPERSEC/100000) + FACTOR;
+ out->dwHighDateTime = x >> 32;
+ out->dwLowDateTime = x;
+ }
+}
+
+/* Cygwin internal */
+void __stdcall
timeval_to_filetime (const struct timeval *time_in, FILETIME *out)
{
long long x = time_in->tv_sec * NSPERSEC +
@@ -203,6 +218,30 @@ time_t_to_timeval (time_t in)
}
/* Cygwin internal */
+static const struct timespec *
+timeval_to_timespec (const struct timeval *tvp, struct timespec *tmp)
+{
+ if (!tvp)
+ return NULL;
+
+ tmp[0].tv_sec = tvp[0].tv_sec;
+ tmp[0].tv_nsec = tvp[0].tv_usec * 1000;
+ if (tmp[0].tv_nsec < 0)
+ tmp[0].tv_nsec = 0;
+ else if (tmp[0].tv_nsec > 999999999)
+ tmp[0].tv_nsec = 999999999;
+
+ tmp[1].tv_sec = tvp[1].tv_sec;
+ tmp[1].tv_nsec = tvp[1].tv_usec * 1000;
+ if (tmp[1].tv_nsec < 0)
+ tmp[1].tv_nsec = 0;
+ else if (tmp[1].tv_nsec > 999999999)
+ tmp[1].tv_nsec = 999999999;
+
+ return tmp;
+}
+
+/* Cygwin internal */
/* Convert a Win32 time to "UNIX" format. */
long __stdcall
to_time_t (FILETIME *ptr)
@@ -439,8 +478,8 @@ gmtime (const time_t *tim_p)
#endif /* POSIX_LOCALTIME */
-static int
-utimes_worker (path_conv &win32, const struct timeval *tvp)
+int
+utimens_worker (path_conv &win32, const struct timespec *tvp)
{
int res = -1;
@@ -475,7 +514,7 @@ utimes_worker (path_conv &win32, const struct timeval *tvp)
}
}
- res = fh->utimes (tvp);
+ res = fh->utimens (tvp);
if (!fromfd)
delete fh;
@@ -492,7 +531,8 @@ extern "C" int
utimes (const char *path, const struct timeval *tvp)
{
path_conv win32 (path, PC_POSIX | PC_SYM_FOLLOW, stat_suffixes);
- return utimes_worker (win32, tvp);
+ struct timespec tmp[2];
+ return utimens_worker (win32, timeval_to_timespec (tvp, tmp));
}
/* BSD */
@@ -500,12 +540,13 @@ extern "C" int
lutimes (const char *path, const struct timeval *tvp)
{
path_conv win32 (path, PC_POSIX | PC_SYM_NOFOLLOW, stat_suffixes);
- return utimes_worker (win32, tvp);
+ struct timespec tmp[2];
+ return utimens_worker (win32, timeval_to_timespec (tvp, tmp));
}
-/* BSD */
+/* futimens: POSIX/SUSv4 */
extern "C" int
-futimes (int fd, const struct timeval *tvp)
+futimens (int fd, const struct timespec *tvp)
{
int res;
@@ -513,13 +554,21 @@ futimes (int fd, const struct timeval *tvp)
if (cfd < 0)
res = -1;
else if (cfd->get_access () & (FILE_WRITE_ATTRIBUTES | GENERIC_WRITE))
- res = cfd->utimes (tvp);
+ res = cfd->utimens (tvp);
else
- res = utimes_worker (cfd->pc, tvp);
- syscall_printf ("%d = futimes (%d, %p)", res, fd, tvp);
+ res = utimens_worker (cfd->pc, tvp);
+ syscall_printf ("%d = futimens (%d, %p)", res, fd, tvp);
return res;
}
+/* BSD */
+extern "C" int
+futimes (int fd, const struct timeval *tvp)
+{
+ struct timespec tmp[2];
+ return futimens (fd, timeval_to_timespec (tvp, tmp));
+}
+
/* utime: POSIX 5.6.6.1 */
extern "C" int
utime (const char *path, const struct utimbuf *buf)
diff --git a/winsup/cygwin/winsup.h b/winsup/cygwin/winsup.h
index 68a0c2b7b..0852b2908 100644
--- a/winsup/cygwin/winsup.h
+++ b/winsup/cygwin/winsup.h
@@ -285,6 +285,7 @@ void __stdcall totimeval (struct timeval *, FILETIME *, int, int);
long __stdcall to_time_t (FILETIME *);
void __stdcall to_timestruc_t (FILETIME *, timestruc_t *);
void __stdcall time_as_timestruc_t (timestruc_t *);
+void __stdcall timespec_to_filetime (const struct timespec *, FILETIME *);
void __stdcall timeval_to_filetime (const struct timeval *, FILETIME *);
/* Console related */