* 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.
This commit is contained in:
parent
0d02384a48
commit
eba32ec829
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -182,6 +182,21 @@ time_t_to_filetime (time_t time_in, FILETIME *out)
|
||||
out->dwLowDateTime = x;
|
||||
}
|
||||
|
||||
/* 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)
|
||||
@ -202,6 +217,30 @@ time_t_to_timeval (time_t in)
|
||||
return res;
|
||||
}
|
||||
|
||||
/* 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
|
||||
@ -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)
|
||||
|
@ -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 */
|
||||
|
Loading…
x
Reference in New Issue
Block a user