* 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>
|
2008-04-24 Yaakov (Cygwin Ports) <yselkowitz@users.sourceforge.net>
|
||||||
|
|
||||||
* include/wait.h: New file.
|
* include/wait.h: New file.
|
||||||
|
|
|
@ -564,6 +564,7 @@ fts_set_clientptr NOSIGFE
|
||||||
ftw SIGFE
|
ftw SIGFE
|
||||||
funlockfile SIGFE
|
funlockfile SIGFE
|
||||||
funopen SIGFE
|
funopen SIGFE
|
||||||
|
futimens SIGFE
|
||||||
futimes SIGFE
|
futimes SIGFE
|
||||||
futimesat SIGFE
|
futimesat SIGFE
|
||||||
fwrite SIGFE
|
fwrite SIGFE
|
||||||
|
@ -1656,6 +1657,7 @@ usleep SIGFE
|
||||||
_usleep = usleep SIGFE
|
_usleep = usleep SIGFE
|
||||||
utime SIGFE
|
utime SIGFE
|
||||||
_utime = utime SIGFE
|
_utime = utime SIGFE
|
||||||
|
utimensat SIGFE
|
||||||
utimes SIGFE
|
utimes SIGFE
|
||||||
_utimes = utimes SIGFE
|
_utimes = utimes SIGFE
|
||||||
utmpname SIGFE
|
utmpname SIGFE
|
||||||
|
|
|
@ -1516,10 +1516,10 @@ fhandler_base::link (const char *newpath)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fhandler_base::utimes (const struct timeval *tvp)
|
fhandler_base::utimens (const struct timespec *tvp)
|
||||||
{
|
{
|
||||||
if (is_fs_special ())
|
if (is_fs_special ())
|
||||||
return utimes_fs (tvp);
|
return utimens_fs (tvp);
|
||||||
|
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -286,7 +286,7 @@ class fhandler_base
|
||||||
int __stdcall fstat_by_handle (struct __stat64 *buf) __attribute__ ((regparm (2)));
|
int __stdcall fstat_by_handle (struct __stat64 *buf) __attribute__ ((regparm (2)));
|
||||||
int __stdcall fstat_by_name (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)));
|
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 fchmod (mode_t mode) __attribute__ ((regparm (1)));
|
||||||
virtual int __stdcall fchown (__uid32_t uid, __gid32_t gid) __attribute__ ((regparm (2)));
|
virtual int __stdcall fchown (__uid32_t uid, __gid32_t gid) __attribute__ ((regparm (2)));
|
||||||
virtual int __stdcall facl (int, int, __acl32 *) __attribute__ ((regparm (3)));
|
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 fadvise (_off64_t, _off64_t, int) __attribute__ ((regparm (3)));
|
||||||
virtual int __stdcall ftruncate (_off64_t, bool) __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 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 __stdcall fsync () __attribute__ ((regparm (1)));
|
||||||
virtual int ioctl (unsigned int cmd, void *);
|
virtual int ioctl (unsigned int cmd, void *);
|
||||||
virtual int fcntl (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 fadvise (_off64_t, _off64_t, int) __attribute__ ((regparm (3)));
|
||||||
int __stdcall ftruncate (_off64_t, bool) __attribute__ ((regparm (3)));
|
int __stdcall ftruncate (_off64_t, bool) __attribute__ ((regparm (3)));
|
||||||
int __stdcall link (const char *) __attribute__ ((regparm (2)));
|
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)));
|
int __stdcall fstatvfs (struct statvfs *buf) __attribute__ ((regparm (2)));
|
||||||
|
|
||||||
HANDLE mmap (caddr_t *addr, size_t len, int prot, int flags, _off64_t off);
|
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
|
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
|
int
|
||||||
fhandler_base::utimes_fs (const struct timeval *tvp)
|
fhandler_base::utimens_fs (const struct timespec *tvp)
|
||||||
{
|
{
|
||||||
LARGE_INTEGER lastaccess, lastwrite;
|
LARGE_INTEGER lastaccess, lastwrite;
|
||||||
struct timeval tmp[2];
|
struct timespec timeofday;
|
||||||
|
struct timespec tmp[2];
|
||||||
bool closeit = false;
|
bool closeit = false;
|
||||||
|
|
||||||
if (!get_handle ())
|
if (!get_handle ())
|
||||||
|
@ -1180,15 +1181,25 @@ fhandler_base::utimes_fs (const struct timeval *tvp)
|
||||||
closeit = true;
|
closeit = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
gettimeofday (&tmp[0], 0);
|
gettimeofday (reinterpret_cast<struct timeval *> (&timeofday), 0);
|
||||||
|
timeofday.tv_nsec *= 1000;
|
||||||
if (!tvp)
|
if (!tvp)
|
||||||
|
tmp[1] = tmp[0] = timeofday;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
tmp[1] = tmp[0];
|
if ((tmp[0].tv_nsec < UTIME_NOW || tmp[0].tv_nsec > 999999999L)
|
||||||
tvp = tmp;
|
|| (tmp[1].tv_nsec < UTIME_NOW || tmp[1].tv_nsec > 999999999L))
|
||||||
|
{
|
||||||
|
set_errno (EINVAL);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
timeval_to_filetime (&tvp[0], (FILETIME *) &lastaccess);
|
tmp[0] = (tvp[0].tv_nsec == UTIME_NOW) ? timeofday : tvp[0];
|
||||||
timeval_to_filetime (&tvp[1], (FILETIME *) &lastwrite);
|
tmp[1] = (tvp[1].tv_nsec == UTIME_NOW) ? timeofday : tvp[1];
|
||||||
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;
|
IO_STATUS_BLOCK io;
|
||||||
FILE_BASIC_INFORMATION fbi;
|
FILE_BASIC_INFORMATION fbi;
|
||||||
|
|
|
@ -331,12 +331,13 @@ details. */
|
||||||
184: Export openat, faccessat, fchmodat, fchownat, fstatat, futimesat,
|
184: Export openat, faccessat, fchmodat, fchownat, fstatat, futimesat,
|
||||||
linkat, mkdirat, mkfifoat, mknodat, readlinkat, renameat, symlinkat,
|
linkat, mkdirat, mkfifoat, mknodat, readlinkat, renameat, symlinkat,
|
||||||
unlinkat.
|
unlinkat.
|
||||||
|
185: Export futimens, utimensat.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Note that we forgot to bump the api for ualarm, strtoll, strtoull */
|
/* Note that we forgot to bump the api for ualarm, strtoll, strtoull */
|
||||||
|
|
||||||
#define CYGWIN_VERSION_API_MAJOR 0
|
#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
|
/* There is also a compatibity version number associated with the
|
||||||
shared memory regions. It is incremented when incompatible
|
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>
|
||||||
|
|
||||||
|
<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>
|
<sect1 id="std-deprec"><title>Other UNIX system interfaces, deprecated or not in POSIX.1-2001:</title>
|
||||||
|
|
||||||
<screen>
|
<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);
|
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
|
extern "C" int
|
||||||
futimesat (int dirfd, const char *pathname, const struct timeval *times)
|
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;
|
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 */
|
/* Cygwin internal */
|
||||||
void __stdcall
|
void __stdcall
|
||||||
timeval_to_filetime (const struct timeval *time_in, FILETIME *out)
|
timeval_to_filetime (const struct timeval *time_in, FILETIME *out)
|
||||||
|
@ -202,6 +217,30 @@ time_t_to_timeval (time_t in)
|
||||||
return res;
|
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 */
|
/* Cygwin internal */
|
||||||
/* Convert a Win32 time to "UNIX" format. */
|
/* Convert a Win32 time to "UNIX" format. */
|
||||||
long __stdcall
|
long __stdcall
|
||||||
|
@ -439,8 +478,8 @@ gmtime (const time_t *tim_p)
|
||||||
|
|
||||||
#endif /* POSIX_LOCALTIME */
|
#endif /* POSIX_LOCALTIME */
|
||||||
|
|
||||||
static int
|
int
|
||||||
utimes_worker (path_conv &win32, const struct timeval *tvp)
|
utimens_worker (path_conv &win32, const struct timespec *tvp)
|
||||||
{
|
{
|
||||||
int res = -1;
|
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)
|
if (!fromfd)
|
||||||
delete fh;
|
delete fh;
|
||||||
|
@ -492,7 +531,8 @@ extern "C" int
|
||||||
utimes (const char *path, const struct timeval *tvp)
|
utimes (const char *path, const struct timeval *tvp)
|
||||||
{
|
{
|
||||||
path_conv win32 (path, PC_POSIX | PC_SYM_FOLLOW, stat_suffixes);
|
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 */
|
/* BSD */
|
||||||
|
@ -500,12 +540,13 @@ extern "C" int
|
||||||
lutimes (const char *path, const struct timeval *tvp)
|
lutimes (const char *path, const struct timeval *tvp)
|
||||||
{
|
{
|
||||||
path_conv win32 (path, PC_POSIX | PC_SYM_NOFOLLOW, stat_suffixes);
|
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
|
extern "C" int
|
||||||
futimes (int fd, const struct timeval *tvp)
|
futimens (int fd, const struct timespec *tvp)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
|
@ -513,13 +554,21 @@ futimes (int fd, const struct timeval *tvp)
|
||||||
if (cfd < 0)
|
if (cfd < 0)
|
||||||
res = -1;
|
res = -1;
|
||||||
else if (cfd->get_access () & (FILE_WRITE_ATTRIBUTES | GENERIC_WRITE))
|
else if (cfd->get_access () & (FILE_WRITE_ATTRIBUTES | GENERIC_WRITE))
|
||||||
res = cfd->utimes (tvp);
|
res = cfd->utimens (tvp);
|
||||||
else
|
else
|
||||||
res = utimes_worker (cfd->pc, tvp);
|
res = utimens_worker (cfd->pc, tvp);
|
||||||
syscall_printf ("%d = futimes (%d, %p)", res, fd, tvp);
|
syscall_printf ("%d = futimens (%d, %p)", res, fd, tvp);
|
||||||
return res;
|
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 */
|
/* utime: POSIX 5.6.6.1 */
|
||||||
extern "C" int
|
extern "C" int
|
||||||
utime (const char *path, const struct utimbuf *buf)
|
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 *);
|
long __stdcall to_time_t (FILETIME *);
|
||||||
void __stdcall to_timestruc_t (FILETIME *, timestruc_t *);
|
void __stdcall to_timestruc_t (FILETIME *, timestruc_t *);
|
||||||
void __stdcall time_as_timestruc_t (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 *);
|
void __stdcall timeval_to_filetime (const struct timeval *, FILETIME *);
|
||||||
|
|
||||||
/* Console related */
|
/* Console related */
|
||||||
|
|
Loading…
Reference in New Issue