* 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:
Corinna Vinschen 2008-04-24 09:59:54 +00:00
parent 0d02384a48
commit eba32ec829
10 changed files with 143 additions and 26 deletions

View File

@ -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.

View 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

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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>

View File

@ -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)
{ {

View File

@ -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)

View File

@ -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 */