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 /winsup/cygwin/times.cc
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.
Diffstat (limited to 'winsup/cygwin/times.cc')
-rw-r--r--winsup/cygwin/times.cc69
1 files changed, 59 insertions, 10 deletions
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)